Lazarus 3.0 (2023.12.21.)
Letöltés

  • Oldal:
  • 1

TÉMA:

Válasz: Mutációk létrehozása 2014 ápr. 10 05:16 #1330

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 504
  • Köszönetek: 86
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;
A "mutant" eljárásban szintén rosszul használod a "population" tömböt és nincs "for" ciklus amivel végiglépkednél a tömb elemein
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

  • vörösmacska
  • vörösmacska profilkép Témaindító
  • Új tag
  • Új tag
  • Hozzászólások: 1
  • Köszönetek: 0
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.

  • Oldal:
  • 1