function stuff = sctrain(Xin,yin,K,maxgen,M,alpha)
% try to cluster the data using a semi-supervised
%   version of kmeans with a genetic algorithm
%   to search the mean-space

if nargin<3  K=9;          end;
if nargin<4  maxgen=1000;  end;
if nargin<5  M=4;          end;
if nargin<6  alpha=.3;     end;

[n,d] = size(Xin);

%%%%%%%%%%%%%%%%%INITIALIZE 2 MEANS
means=[];
for i=1:K
    for m=1:M
        means(i,:,m) = Xin(ceil(rand*n),:);
    end;    
end;
bounds = [min(Xin,[],1);max(Xin,[],1)];

%%%%%%%%%%%%%%%%%BEGIN EVOLUTION
gen=0;
cont=1;
firsttime=1;
fits = [-Inf -Inf];

while (cont)
    %1. determine cluster centers via evolution
    if(firsttime)
        firsttime = 0;
    else
        means = oneonega(means,fits,bounds);
    end;

    %2. through 4. -- compute the fitness
    fstuff = meanfitness(means,Xin,yin,alpha);
    fits      = fstuff{1};
    soft_assn = fstuff{2};
    
    fithist(i) = fits(1);
    
    % ---- print out the fitness to keep track
    fprintf('gen %3d: ',gen);
    for m=1:M
        fprintf('%5.2f | ', fits(m));
    end;
    fprintf('\n');
    
    % ---- update the generation count
    gen = gen+1;
    if gen>maxgen
        cont=0;
    end;
end;

%clean up and return
[v,best] = max(fits);
fmeans = means(:,:,best);
sassn = soft_assn(:,best);

stuff{1} = fmeans;
stuff{2} = sassn;
stuff{3} = fithist;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% -- the 1+1 evolutionary program
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function nmeans = oneonega(means,fits,bounds)
% means is a 3d matrix which is two sets
%   of means for the clustering problem

[f,idx] = max(fits);
[n,d,m] = size(means);

% -- keep the most fit guy
for q=1:m
    nmeans(:,:,q) = means(:,:,idx);
    if(q~=idx)
        % -- exactly one mutation in everyone else
        mutdx = rand * 1e10;
        i = ceil(mod(mutdx,n));
        j = ceil(mod(mutdx,d));
        nmeans(i,j,q) = bounds(1,j) + ...
            rand * (bounds(2,j) - bounds(1,j));
    end;
end;