TÉMA:
Válasz: Mutációk létrehozása 2014 ápr. 10 05:16 #1330
|
Hát igen...
Alapvető hibák vannak, melyek javítása nélkül nem lehet lefordítani a programot. Ha tömb (array) típust használsz akkor illik meghatározni azt is, hogy az adott műveletben a tömb melyik elemét szeretnéd használni. A programodból vett egyik hibás eljárásban például így kellene: Procedure InitializePopulation(number:integer);
var i:integer;
begin
SetLength(population,number);
for i:=0 to number-1 do
begin
population[i].Enzyme1:=1; //Ez a kezdeti enzim 1 darabszám.
population[i].Enzyme2:=1; //Ez a kezdeti enzim 2 darabszám.
population[i].Mutant:=0; //Ez a kezdeti mutáns darabszám.
population[i].Fitness:=FitnessCalculation(population[i].Enzyme1,population[i].Enzyme2,population[i].Mutant)
end;
end; Kérdés: - Amikor "population[mi][1]" kifejezést írod a "mutant" eljárásban akkor valójában minek az értékét szeretnéd használni?
Hogyan kérdezzünk okosan?
/
Mit kell tennünk kérdezés előtt?
-- Lazarus 3.0 -- FPC 3.2-- GNU/Linux 5.15.0 x86_64
|
|
Mutációk létrehozása 2014 ápr. 08 15:49 #1329
|
Kedves Mindenki!
Van egy ilyen evolúciós programom, amiben vezikulák szerepelnek, bennük 3 féle génnel, ezek véletlenszerűen kiválasztódnak szaporodásra, majd végül a program kiszámolja ezek arányát. Beleírtam egy eljárást, amivel véletlenszerűen mutációkat lehetne generálni a 3 féle típusban, véletlenszerűen. Erre egy Box&Muller egyenletet alkalmaztam, ami a mutáciok normál eloszlását biztosítja. Azonban vmit elrontottam benne, úgy sejtem a population array-ben lehet gond, tudnátok segíteni hol hibás a "procedure mutation" rész? program mutation; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, { you can add units after this } Math; const MaxGeneration = 200; type PopulationType = record Enzyme1,Enzyme2,Mutant:integer; //The number of molecules of type enzyme 1, enzyme 2 and mutant Fitness: double; end; var population : array of PopulationType; //The population of cells mu:single; //Mutation rate r1,r2,rm:single; //The replication affinity of E1, E2 and the mutants MaxPopulation:integer; //The population size SplitDensity:integer; //Vesicles split after having this much molecule in them tmp,tmp2:integer; timer,timer2:integer; mutSzam:longint; mutFaktor:single; mutDistance:integer; FileName:string; //The name of the output file F:text; //The otput file Function FitnessCalculation(E1,E2,M:integer):double; {Calculates fitness based the number of genes present} var tmpf:double; begin if (E1=0) or (E2=0) then tmpf:=0 else tmpf:=min(E1,E2); FitnessCalculation:=tmpf; end; Procedure InitializePopulation(number:integer); var i:integer; begin SetLength(population,number); for i:=0 to number-1 do begin population.Enzyme1:=1; //Ez a kezdeti enzim 1 darabszám. population.Enzyme2:=1; //Ez a kezdeti enzim 2 darabszám. population.Mutant:=0; //Ez a kezdeti mutáns darabszám. population.Fitness:=FitnessCalculation(population.Enzyme1,population.Enzyme2,population.Mutant) end; end; Function PickOneForReplication:integer; var totalf,vote:double; pi:integer; begin totalf:=0; for pi:=0 to Length(population)-1 do totalf:=totalf+population[pi].Fitness; vote:=random*totalf; totalf:=population[0].Fitness; pi:=0; while totalf<vote do begin inc(pi); totalf:=totalf+population[pi].Fitness; end; PickOneForReplication:=pi; end; Function WhoShallBeCopied(E1,E2,M:integer):integer; var totalr,vote:double; begin totalr:=r1*E1+r2*E2+rm*M; vote:=random*totalr; if vote<r1*E1 then WhoShallBeCopied:=1 //E1 copied else if vote<r1*E1+r2*E2 then WhoShallBeCopied:=2 //E2 cpoied else WhoShallBeCopied:=3; //Mutant copied end; Function MakeCopy:integer; var mi:integer; begin mi:=PickOneForReplication; case WhoShallBeCopied(population[mi].Enzyme1,population[mi].Enzyme2,population[mi].Mutant) of 1: if random>mu then inc(population[mi].Enzyme1) else inc(population[mi].Mutant); //Mutáció lehetséges 2: if random>mu then inc(population[mi].Enzyme2) else inc(population[mi].Mutant); //Mutáció lehetséges 3: inc(population[mi].Mutant); end; population[mi].Fitness:=FitnessCalculation (population[mi].Enzyme1,population[mi].Enzyme2,population[mi].Mutant); //Fitness újraszámolás MakeCopy:=mi; end; Function SumPop(be:PopulationType):integer; begin SumPop:=be.Enzyme1+be.Enzyme2+be.Mutant; end; Function AverageFitness:single; var ai:integer; avg:single; begin avg:=0; for ai:=0 to MaxPopulation-1 do avg:=avg+population[ai].Fitness; AverageFitness:=avg/MaxPopulation; end; Function DeadCells:single; {Calculates the fraction of cells with 0 fitness, hany olyan vezikula van aminek nulla a fitnesze} var di,dj:integer; begin dj:=0; for di:=0 to MaxPopulation-1 do if (population[di].Enzyme1=0) or (population[di].Enzyme2=0) then inc(dj); //Ha bármelyik enzim nincs benne, akkor 0 a fitnessze. Az inc egyszerűen hozzáad 1-et egy egész számhoz. DeadCells:=dj/MaxPopulation; //A darabszámot elosztjuk az összes sejt számával end; Function ParasiteFraction:single; {Mi az átlagos aránya a parazitáknak} var pi:integer; pj:single; begin pj:=0; for pi:=0 to MaxPopulation-1 do pj:=pj+ population[pi].Mutant / (population[pi].Enzyme2 + population[pi].Enzyme1 + population[pi].Mutant); ParasiteFraction:=pj/MaxPopulation; end; Function Enzyme1Fraction:single; {átlagos aránya az enzim1-nek} var ei:integer; ej:single; begin ej:=0; for ei:=0 to MaxPopulation-1 do ej:=ej+population[ei].Enzyme1 / (population[ei].Enzyme2+population[ei].Enzyme1+population[ei].Mutant); Enzyme1Fraction:=ej/MaxPopulation; end; Function Enzyme2Fraction:single; {atlagos aranya az enzim2-nek} var fi:integer; fj:single; begin fj:=0; for fi:=0 to MaxPopulation-1 do fj:=fj+population[fi].Enzyme2 / (population[fi].Enzyme2+population[fi].Enzyme1+population[fi].Mutant); Enzyme2Fraction:=fj/MaxPopulation; end; Procedure Mutation; var a,b:integer; change:boolean; x:single; begin {mutaciok normal eloszlas szerint, csak a replikacios rata valtozik meg, az enzimatikus affinitas nem} x:=sqrt(-2*ln(random))* cos(2*pi*random)* mutFaktor * mutDistance; population[mi][1]:=max(1,round(population[mi][1]+x)); if round(x)<>0 then mutSzam:=mutSzam+1; end; Function BinomRandom(size:integer):integer; var bi:integer; vote:integer; begin vote:=1; for bi:=1 to size do if random<0.5 then vote:=vote+1; BinomRandom:=vote; end; begin Randomize; Val(ParamStr(1),mu); Val(ParamStr(2),r1); Val(ParamStr(3),r2); Val(ParamStr(4),rm); Val(ParamStr(5),MaxPopulation); Val(ParamStr(6),SplitDensity); FileName:=ParamStr(7); InitializePopulation(MaxPopulation); timer:=1; while timer<MaxGeneration do for timer2:= 1 to MaxPopulation*SplitDensity do begin tmp:=MakeCopy; if SumPop(population[tmp])>SplitDensity then begin repeat tmp2:=random(MaxPopulation) until tmp<>tmp2; Population[tmp2].Enzyme1:=BinomRandom(Population[tmp].Enzyme1); Population[tmp2].Enzyme2:=BinomRandom(Population[tmp].Enzyme2); Population[tmp2].Mutant:=BinomRandom(Population[tmp].Mutant); Population[tmp].Enzyme1:=Population[tmp].Enzyme1-Population[tmp2].Enzyme1; Population[tmp].Enzyme2:=Population[tmp].Enzyme2-Population[tmp2].Enzyme2; Population[tmp].Mutant:=Population[tmp].Mutant-Population[tmp2].Mutant; end; inc(timer); end; Assign(F,FileName); Append(F); writeln(F,ParamStr(1),' ',ParamStr(2),' ',ParamStr(3),' ',ParamStr(4),' ',ParamStr(5),' ',ParamStr(6),' ',AverageFitness:1:5,' ',DeadCells:1:5,' ',ParasiteFraction:1:5,' ',Enzyme1Fraction:1:5,' ',Enzyme2Fraction:1:5); Close(F); end. |
|