⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gabase.pas

📁 开发环境:Delphi 简要说明:TGABase is a abstract class. You must Derivate a sub_class from it. You must overr
💻 PAS
字号:
unit GABase;{Developed by Shu Jun, 2000/6/24, PMI, NCEPU}{TGABase is a abstract class. You must Derivate a sub_class from it. You mustoverride abstract function calculateFitness. By the way, this class can onlyget minimum solution}  interfaceuses  Dialogs,Sysutils;type  CIndividual = record    IntegerSection: array of integer;    FloatSection: array of double;    IsSurvival: boolean;//在选择中存活的个体, 不被交叉和变异    IsProtected: boolean;//受保护的个体不被且不参与交叉和变异,                        //用于专家控制和优化群体复制.    Fitness: double;  end;  CISectionLimit = record    UpperLimit: integer;    LowerLimit: integer;  end;  CFSectionLimit = record    UpperLimit: double;    LowerLimit: double;  end;  TGABase = class(TObject)  private    MaxJudge       :Boolean;        //True—最大值,False—最小值    Temp_Population: array of CIndividual;    ISectionLimit  : array of CISectionLimit;    FSectionLimit  : array of CFSectionLimit;    IntegerNum     : integer;    FloatNum       : integer;    MutationRatio  : double;    CrossOverRatio : double;    Generations    : integer;    NSurvivors     : integer;    CurrentGen     : integer;    procedure SetRandom;    function RandVal(ALow, AUp: integer): integer; overload;    function RandVal(ALow, AUp: double): double; overload;    function FindCanCopyed: integer;    procedure SelectFace2Face;         //遗传    procedure EquablyCrossOver;        //交叉    procedure Mutation; virtual;       //变异  public    Population: array of CIndividual;    constructor Create;    destructor Destroy;override;    procedure IniData(AINum, AFNum: integer; AIUp, AILow: array of integer;      AFUp, AFLow: array of double);    procedure IniParameter(Max:Boolean = False; AGens: integer = 200; APop: integer = 60; AMutionR: double = 0.01; ACrossOverR: double = 0.5);    procedure Calculate(ACurGen: integer); virtual;    procedure CopyData(var ADes: CIndividual; ASrc: CIndividual);  protected    PopSize: integer;    procedure CalculateFitness; virtual; abstract;  end;  implementation{ TGABase }uses  math;constructor TGABase.Create;begin  SetRandom();end;destructor TGABase.Destroy;begin  Population := nil;  Temp_Population := nil;end;procedure TGABase.IniData(AINum, AFNum: integer;  AIUp, AILow: array of integer; AFUp, AFLow: array of double);var  I, J: integer;begin  SetRandom();  IntegerNum := AINum;  FloatNum := AFNum;  SetLength(ISectionLimit, AINum);  SetLength(FSectionLimit, AFNum);  for I := 0 to AINum - 1 do  begin    ISectionLimit[I].UpperLimit := AIUp[I];    ISectionLimit[I].LowerLimit := AILow[I];  end;//for                      for I := 0 to AFNum - 1 do  begin    FSectionLimit[I].UpperLimit := AFUp[I];    FSectionLimit[I].LowerLimit := AFLow[I];  end;  SetLength(Population, PopSize + 1);  SetLength(Temp_Population, PopSize + 1);  for I := 0 to PopSize do  begin    SetLength(Population[I].IntegerSection, AINum);    SetLength(Population[I].FloatSection, AFNum);    SetLength(Temp_Population[I].IntegerSection, AINum);    SetLength(Temp_Population[I].FloatSection, AFNum);    Population[I].IsProtected := false;                 for J := 0 to AINum - 1 do      Population[I].IntegerSection[J] := RandVal(ISectionLimit[J].LowerLimit,        ISectionLimit[J].UpperLimit);    for J := 0 to AFNum - 1 do      Population[I].FloatSection[J] := RandVal(FSectionLimit[J].LowerLimit,        FSectionLimit[J].UpperLimit);  end;//for  Population[PopSize].Fitness := 10E100;end;procedure TGABase.IniParameter(Max:Boolean;AGens, APop: integer; AMutionR,  ACrossOverR: double);begin  MaxJudge:=Max;  Generations := AGens;  PopSize := APop;  MutationRatio := AMutionR;  CrossOverRatio := ACrossOverR;end;procedure TGABase.SetRandom;begin  RandSeed := 0;end;function TGABase.RandVal(ALow, AUp: integer): integer;var  Num: integer;begin  Num := AUp - ALow;  result := ALow + random(Num + 1);end;function TGABase.RandVal(ALow, AUp: double): double;var  Temp: double;begin  Temp := AUp - ALow;  result := ALow + random * Temp;end;procedure TGABase.SelectFace2Face;var  I, FirstMem, SecondMem, Winner: integer;begin  //如果最优解失去,拷贝一份  I := 0;  while (I < PopSize) and ((Population[I].IsProtected = true)    or (Population[I].Fitness <> Population[PopSize].Fitness)) do    I := I + 1;  if I = PopSize then  begin    FirstMem := FindCanCopyed;    CopyData(Population[FirstMem], Population[PopSize])  end;  //选择好个体进入Temp_Population, 保留的最好个体与受保护个体不参与竞争  for I := 0 to PopSize - 1 do  begin    FirstMem := Random(PopSize);    while Population[FirstMem].IsProtected = true do      FirstMem := Random(PopSize);    SecondMem := Random(PopSize);    while Population[SecondMem].IsProtected = true do      SecondMem := Random(PopSize);    if MaxJudge then     //求最大值    begin      if Population[FirstMem].Fitness>Population[SecondMem].Fitness then        Winner :=FirstMem      else        Winner :=SecondMem;    end    else begin           //求最小值       if Population[FirstMem].Fitness<Population[SecondMem].Fitness then        Winner :=FirstMem      else        Winner :=SecondMem;    end;    CopyData(Temp_Population[I], Population[Winner]);  end;//for  //将Temp_Population考入Population,保证Population中受保护的个体不被覆盖  for I := 0 to PopSize - 1 do  begin    if Population[I].IsProtected = false then    begin      CopyData(Population[I], Temp_Population[I]);    end;//if  end;//for  NSurvivors := 0;  for I := 0 to PopSize - 1 do    if CrossOverRatio < Random then    begin      Population[I].IsSurvival := true;      NSurvivors := NSurvivors + 1;    end    else      Population[I].IsSurvival := false;    Population[Popsize].IsSurvival := true;end;procedure TGABase.EquablyCrossOver;var  I, J, a, b, POne, PTwo, Count: integer;begin{  for I := 0 to PopSize - 1 do  begin    if random(2) = 0 then      Population[I].IsSurvival := true    else      Population[I].IsSurvival := false;  end;}  for I := 0 to PopSize - 1 do  begin    POne := 0;    PTwo := 0;    if Population[I].IsSurvival = false then    begin      a := random(NSurvivors + 1);      b := random(NSurvivors + 1);      Count := 0;      for J := 0 to PopSize - 1 do      begin        if (Population[J].IsSurvival = true)          and (Population[J].IsProtected = false) then          begin            Count := Count + 1;            if Count = a then POne := J;            if Count = b then PTwo := J;          end;//if      end;//for      for J := 0 to IntegerNum - 1 do      begin        if random(2) = 0 then          Population[I].IntegerSection[J] := Population[POne].IntegerSection[J]        else          Population[I].IntegerSection[J] := Population[PTwo].IntegerSection[J];      end;//for      for J := 0 to FloatNum - 1 do      begin        if random(2) = 0 then          Population[I].FloatSection[J] := Population[POne].FloatSection[J]        else          Population[I].FloatSection[J] := Population[PTwo].FloatSection[J];      end;//for    end;//if  end;//forend;procedure TGABase.Mutation;var  I, MutationNum, Member, Point: integer;begin  MutationNum := Round(PopSize * (IntegerNum + FloatNum) * MutationRatio);  I := 0;  while I < MutationNum do  begin    Member := Random(PopSize);    if Population[Member].IsProtected <> true then    begin      if IntegerNum > 0 then      begin        Point := Random(IntegerNum);        if Random(2) = 0 then        begin          Population[Member].IntegerSection[Point]             := RandVal(ISectionLimit[Point].LowerLimit,             Population[Member].IntegerSection[Point]);        end        else begin          Population[Member].IntegerSection[Point]             := RandVal(Population[Member].IntegerSection[Point],             ISectionLimit[Point].UpperLimit);        end;//if      end;//if      if FloatNum > 0 then      begin        Point := Random(FloatNum);        if Random(2) = 0 then        begin          Population[Member].FloatSection[Point]             := RandVal(FSectionLimit[Point].LowerLimit,             Population[Member].FloatSection[Point]);        end        else begin          Population[Member].FloatSection[Point]             := RandVal(Population[Member].FloatSection[Point],             FSectionLimit[Point].UpperLimit);        end;//if      end;//if      I := I + 1;    end;//if  end;//whileend;function TGABase.FindCanCopyed: integer;var  Member: integer;begin    Member := Random(PopSize);    while Population[Member].IsProtected = true do      Member := Random(PopSize);    if Member < PopSize then      result := Member    else      result := -1;end;procedure TGABase.Calculate(ACurGen: integer);begin  CurrentGen := ACurGen;  if CurrentGen < Generations then  begin    CalculateFitness;    if CurrentGen = Generations - 1 then exit;    SelectFace2Face;    EquablyCrossOver;    Mutation;  end;end;procedure TGABase.CopyData(var ADes: CIndividual; ASrc: CIndividual);var  I: integer;begin  for I := 0 to IntegerNum - 1 do    ADes.IntegerSection[I] := ASrc.IntegerSection[I];  for I := 0 to FloatNum - 1 do    ADes.FloatSection[I] := ASrc.FloatSection[I];  ADes.IsSurvival := ASrc.IsSurvival;  ADes.IsProtected := ASrc.IsProtected;  ADes.Fitness := ASrc.Fitness;end;end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -