Ausschnitt aus meinem Code, wo das Problem auftaucht
Code:
for ii=2:keep
odds=[odds ii*ones(1,ii)];
end
Nodds=length(odds);
odds=keep-odds+1; % odds determines probabilities for being parents
%_______________________________________________________
% Create the initial population
iga=0; % generation counter initialized for iz=1:popsize
pop(iz,:)=randperm(npar); % random population
cost=feval(ff,pop); % calculates population cost using ff [cost,ind]=sort(cost); % min cost in element 1
pop=pop(ind,:); % sort population with lowest cost first
minc(1)=min(cost); % minc contains min of population
meanc(1)=mean(cost); % meanc contains mean of population
%_______________________________________________________
% Iterate through generations while iga<maxit
iga=iga+1; % increments generation counter
%_______________________________________________________
% Pair and mate
pick1=ceil(Nodds*rand(1,M)); % mate #1
pick2=ceil(Nodds*rand(1,M)); % mate #2 % ma and pa contain the indicies of the parents
ma=odds(pick1);
pa=odds(pick2);
%_______________________________________________________
% Performs mating for ic=1:M
mate1=pop(ma(ic),:);
mate2=pop(pa(ic),:);
indx=2*(ic-1)+1; % starts at one and skips every other one
xp=ceil(rand*npar); % random value between 1 and N
temp=mate1; % hold value to be replaced
xs=xp;
while mate1(xp)~=mate2(xs)
mate1(xp)=mate2(xp);
mate2(xp)=temp(xp);
xs=find(temp==mate1(xp));% Position des doppelten Wertes
xp=xs;
end
pop(keep+indx,:)=mate1;
pop(keep+indx+1,:)=mate2;
end
Also die Methode mit der Sortierung sollte ja auch hellfen den Fehler einzukreisen. Aber die Summe ergbit immer 55? Denn das Datenbeispiel sollte ja nur 54 ergeben?
Es ist jetzt wichtig herauszufinden wo im Code der Fehler generiert wird. Schon in der Schleife die mit RANDPERM die Daten erschafft? Oder erst hinterher. Weil == ist mit Double Werte auch gerne eine numerische Falle.
Andreas
Nikki
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 10.09.2014, 11:51
Titel:
Hallo Andreas,
habe es noch ein paar laufen lassen. Die erste Schleife mit dem randperm läuft richtig.
Ich habe noch eine if-Abfrage eingebaut, so dass die fehlerhaften "mates1" angezeigt werden.
Code:
for ic=1:M
mate1=pop(ma(ic),:);
mate2=pop(pa(ic),:);
ifall(diff(sort(mate1)))% alle Elemente in mate1 verschieden
indx=2*(ic-1)+1; % starts at one and skips every other one
xp=ceil(rand*npar);
temp=mate1; % hold value to be replaced
xs=xp;
while mate1(xp)~=mate2(xs)
mate1(xp)=mate2(xp);
mate2(xp)=temp(xp);
xs=find(temp==mate1(xp));% Position des doppelten Wertes
xp=xs;
end
Na ja, mate1 wird ich dann wohl in der while Schleife vom ursprünglichen Wert verändern?
Wie auch immer, ob Bug oder Programmierfehler lässt sich fasst nur beantworten, wenn auch Daten vorliegen (M, ma, pa usw.). Wahrscheinlich am einfachsten eine Web-Anfrage an den Technischen Support machen.
Andreas
Nikki
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 10.09.2014, 13:05
Titel:
Hallo Andreas,
danke für deine Anwtwort!
Die Werte ma, pa werden willkürlich ausgewählt, M wird anhand der Populationsgröße und Selektionsrate berechnet. Den Code habe ich aus einem Buch. Hier das Original.
Irgendeine Idee woran es sonst noch liegen könnte?
Code:
Genetic Algorithm for permuation problems
% % minimizes the objective function designated in ff clear global iga x y
% Haupt & Haupt % 2003
%_______________________________________________________
% Setup the GA
ff='tspfun'; % objective function
npar=20; % # optimization variables
Nt=npar; % # columns in population matrix rand('state',3)
x=rand(1,npar);y=rand(1,npar); % cities are at % (xcity,ycity)
%_______________________________________________________
% Stopping criteria
maxit=10000; % max number of iterations
%_______________________________________________________
% GA parameters
popsize=20; % set population size
mutrate=.1; % set mutation rate
selection=0.5; % fraction of population kept
keep=floor(selection*popsize); % #population members % that survive
M=ceil((popsize-keep)/2); % number of matings
odds=1;
for ii=2:keep
odds=[odds ii*ones(1,ii)];
end
Nodds=length(odds);
%_______________________________________________________
% Create the initial population
iga=0; % generation counter initialized for iz=1:popsize
pop(iz,:)=randperm(npar); % random population end
cost=feval(ff,pop); % calculates population cost % using ff [cost,ind]=sort(cost); % min cost in element 1
pop=pop(ind,:); % sort population with lowest % cost first
minc(1)=min(cost); % minc contains min of % population
meanc(1)=mean(cost); % meanc contains mean of population
%_______________________________________________________
% Iterate through generations while iga<maxit
iga=iga+1; % increments generation counter
%_______________________________________________________
% Pair and mate
pick1=ceil(Nodds*rand(1,M)); % mate #1
pick2=ceil(Nodds*rand(1,M)); % mate #2 % ma and pa contain the indicies of the parents
ma=odds(pick1);
pa=odds(pick2);
%_______________________________________________________
% Performs mating for ic=1:M
mate1=pop(ma(ic),:);
mate2=pop(pa(ic),:);
indx=2*(ic-1)+1; % starts at one and skips every % other one
xp=ceil(rand*npar); % random value between 1 and N
temp=mate1;
x0=xp;
while mate1(xp)~=temp(x0)
mate1(xp)=mate2(xp);
mate2(xp)=temp(xp);
xs=find(temp==mate1(xp));
xp=xs;
end
pop(keep+indx,:)=mate1;
pop(keep+indx+1,:)=mate2;
end
%_______________________________________________________
% Mutate the population
nmut=ceil(popsize*npar*mutrate);
for ic = 1:nmut
row1=ceil(rand*(popsize-1))+1;
col1=ceil(rand*npar);
col2=ceil(rand*npar);
temp=pop(row1,col1);
pop(row1,col1)=pop(row1,col2);
pop(row1,col2)=temp;
im(ic)=row1;
end
cost=feval(ff,pop);
%_______________________________________________________
% Sort the costs and associated parameters
part=pop; costt=cost;
[cost,ind]=sort(cost);
pop=pop(ind,:);
%_______________________________________________________
% Do statistics
minc(iga)=min(cost);
meanc(iga)=mean(cost);
end %iga
%_______________________________________________________
Ich habe nicht nur Ideen, sondern ich werde es lösen können, wenn ich ein reproduzierbares Beispiel habe, Aber das aus dem Buch läift nicht weil mir 'tspfun' fehlt, und das erste Beispiel weil mir M, pa etc. fehlen. Auch für "willkürlich" muss ich ja letztendlich doch Annahmen treffen, wie z.B. den Datentyp.
Andreas
Nikki
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 10.09.2014, 14:24
Titel:
Ja, sorry, hier ist tspfun.
Code:
function dist=tspfun(pop) % Cost function for the traveling salesman problem. % Uses global variables "x" and "y"
%
% Haupt and Haupt, 2003 % Edited and modified by Hundley and Carr, 2014 global x y
[Npop,Ncity]=size(pop);
tour=[pop pop(:,1)];
%distance between cities
for ic=1:Ncity
for id=1:Ncity
dcity(ic,id)=sqrt((x(ic)-x(id))^2+(y(ic)-y(id))^2);
end% id end% ic % cost of each chromosome for ic=1:Npop
dist(ic,1)=0;
for id=1:Ncity
dist(ic,1)=dist(ic)+dcity(tour(ic,id),tour(ic,id+1));
end% id end% ic
Das Problem ist nicht kompliziert. Ich hatte nur aufgegeben, weil ich nicht die Informationen bekomme es zu lösen. Diese sind den vollständigen, aktuell Code mit den vollständigen, aktuellen Daten.
das zuletzt zur Verfügung gestellte tspfun ist nut nützlich wenn mann das Beispiel aus dem Buch verstehen oder debuggen will - aber das funktioniert ja.
sorry, dass ich erst jetzt schreibe.
Ich habe nicht alle meine Daten reingestellt, da es an die 15 Unterprogramme sind und ich mir dachte, dass es einfach zuviel wäre.
Ich habe aber jetzt den Fehler lokalisiert. Und zwar wird in dieser Schleife mate1 teilweise mit doppelten Werte ausgegeben, was nicht sein darf. Warum und wie man das löst, weiß ich aber noch nicht.
Code:
while mate1(xp)~=mate2(xs)% gleiche Positionen, da xs=xp
mate1(xp)=mate2(xp); % first half of swap
mate2(xp)=temp(xp); % second half of swap
xs=find(temp==mate1(xp));
xp=xs;
end
Das ist ja ein recht übersichtlicher Code Das kann eigentlich nur an einem unerwarteten Verhalten von == bzw. ~= oder FIND liegen. Diese Operationen sind numerich oftmals nicht klug eingesetzt. Hintergrundinformationen z.B. hier:
Danke für den Link, aber meine Daten sind alles natürliche Zahlen.
Kann es sein, dass die while-Schleife quasi zu früh aufhört? So, dass die mate1 mit doppelten Werten weitergegeben werden, und das ist dann genau das was bei mir den Fehler verursacht?!
Bei der ersten Generation, ist nämlich alles in Ordnung
temp=mate1;
while mate1(xp)~=mate2(xs)% gleiche Positionen, da xs=xp
mate1(xp)=mate2(xp); % first half of swap
mate2(xp)=temp(xp); % second half of swap
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.