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

📄 ga tsp.txt

📁 tsp遗传算法源代码
💻 TXT
📖 第 1 页 / 共 3 页
字号:
unit fEA_TSP;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, Spin, ComCtrls, uIEA, uITSP, uUtilsEA, uDisplayTSP;

type
  TFormGA = class(TForm)
    PanelFit: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    PanelDisp: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Label2: TLabel;
    EditNoCities: TSpinEdit;
    EditPopulationSize: TSpinEdit;
    EditKill: TSpinEdit;
    EditInversion: TSpinEdit;
    EditTransposition: TSpinEdit;
    EditGens: TSpinEdit;
    ButtonRun: TButton;
    ButtonStep: TButton;
    ButtonCreateCities: TButton;
    ButtonCreatePop: TButton;
    Bevel1: TBevel;
    Bevel2: TBevel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    StatusBar1: TStatusBar;
    Panel7: TPanel;
    Label1: TLabel;
    ListBox1: TListBox;
    Label7: TLabel;
    Bevel3: TBevel;
    procedure FormCreate(Sender: TObject);
    procedure ButtonCreateCitiesClick(Sender: TObject);
    procedure ButtonCreatePopClick(Sender: TObject);
    procedure ButtonStepClick(Sender: TObject);
    procedure ButtonRunClick(Sender: TObject);
    procedure EditKillChange(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure EditTranspositionChange(Sender: TObject);
    procedure EditInversionChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    { Private declarations }
    fGenerations: integer;
    Display: TTSPDisplay;
    Controller: ITSPController;
    BreederCrossover: IBreeder;
    Examiner: ITSPExaminer;
    Creator: ITSPCreator;
    KillerPercentage: IKillerPercentage;
    Mutator: ITSPMutator;
    Population: IPopulation;
    ParentSelectorTournament: IParentSelector;
    pFit: TPainter0;
    ArrFit: array of TFloat;
    ArrFitLen: integer;
    ArrFitPos: integer;
    BitmapF: TBitmap;
    procedure PopulationChange(Sender: TObject);
    procedure SetGenerations(const Value: integer);
    procedure ClearGraph;
    procedure DrawFit;
    procedure Plot(D: TFloat);
    procedure pFitPaint(Sender: TObject);
    procedure DisplayPaint(Sender: TObject);
  public
    { Public declarations }
    property Generations : integer read fGenerations write SetGenerations;
  end;

var
  FormGA: TFormGA;

implementation

uses
  uEA;

{$R *.DFM}

procedure TFormGA.FormCreate(Sender: TObject);
begin
  Randomize;
  Display := TTSPDisplay.Create(self,PanelDisp);
  Display.SetRanges(0.0,11.0,0.0,11.0,1.0);
  Display.BgColor := clWhite;
  Display.Clear;

  Controller := TTSPController.Create;
  Controller.Xmin := Display.Xmin;
  Controller.Xmax := Display.Xmax;
  Controller.Ymin := Display.Ymin;
  Controller.Ymax := Display.Ymax;

  Display.Controller := Controller;

  Creator := TTSPCreator.Create;
  Creator.Controller := Controller;

  BreederCrossover := TTSPBreederCrossover.Create;

  Examiner := TTSPExaminer.Create;
  Examiner.Controller := Controller;

  KillerPercentage := TKillerPercentage.Create;

  Mutator := TTSPMutator.Create;

  ParentSelectorTournament := TParentSelectorTournament.Create;

  Population := TPopulation.Create;
  Population.Breeder := BreederCrossover;
  Population.Examiner := Examiner;
  Population.Creator := Creator;
  Population.Killer := KillerPercentage;
  Population.Mutator := Mutator;
  Population.ParentSelector := ParentSelectorTournament;
  Population.OnChange := PopulationChange;

  pFit := TPainter0.Create(self,PanelFit);
  pFit.BgColor := clWhite;
  pFit.PenWidth := 3;
  pFit.PenColor := clRed;
  pFit.BrushColor := clRed;
  pFit.Clear;

  BitmapF := TBitmap.Create;
  BitmapF.Canvas.Pen.Color := pFit.PenColor;

  EditKillChange(self);
  EditTranspositionChange(self);
  EditInversionChange(self);
end;

procedure TFormGA.FormDestroy(Sender: TObject);
begin
  BitmapF.Free;
end;

procedure TFormGA.SetGenerations(const Value: integer);
begin
  fGenerations := Value;
  StatusBar1.Panels[0].Text := 'Gens: ' + IntToStr(Value);
end;

procedure TFormGA.ButtonCreateCitiesClick(Sender: TObject);
begin
  Population.Clear;
  Generations := 0;
  ClearGraph;
  Display.Controller.CityCount := EditNoCities.Value;
  Display.DrawMap;
  ButtonCreatePop.Enabled := true;
end;

procedure TFormGA.ButtonCreatePopClick(Sender: TObject);
const
  d = 5;
begin
  Population.Initialise(EditPopulationSize.Value);
  Display.DrawMapWithRoute(Population[0] as ITSPIndividual);
  Display.OnPaint := DisplayPaint;
  Generations := 0;
  ArrFitLen := (pFit.ClientWidth - d) div d;
  SetLength(ArrFit, ArrFitLen);
  ArrFitPos := Low(ArrFit);
  ArrFit[ArrFitPos] := Population.FitnessOf(0);
  pFit.SetRanges(ArrFitPos,ArrFitLen,0.0,ArrFit[ArrFitPos],-1.0);
  DrawFit;
  pFit.OnPaint := pFitPaint;
  ButtonRun.Enabled := true;
  ButtonStep.Enabled := true;
end;

procedure TFormGA.ClearGraph;
begin
  Display.Clear;
  pFit.Clear;
end;

procedure TFormGA.pFitPaint(Sender: TObject);
begin
  DrawFit;
end;

procedure TFormGA.DisplayPaint(Sender: TObject);
begin
  Display.DrawMapWithRoute(Population[0] as ITSPIndividual);
end;

procedure TFormGA.DrawFit;
var
  i: integer;
begin
  with BitmapF do
  begin
    Width := pFit.ClientWidth;
    Height := pFit.ClientHeight;
    Canvas.Brush.Color := clWhite;
    Canvas.FillRect(pFit.ClientRect);
    Canvas.Brush.Color := clRed;
    for i := Low(ArrFit) to ArrFitPos do
    begin
      Canvas.FillRect(pFit.rRect2iRect(i,i+1,0.0, ArrFit[i]));
    end;
  end;
// to prevent flickering
  pFit.Canvas.Draw(0,0,BitmapF);
end;

procedure TFormGA.Plot(D: TFloat);
var
  i: integer;
begin
  if ArrFitPos < High(ArrFit) then
  begin
    Inc(ArrFitPos);
  end else
  begin
    ArrFitPos := High(ArrFit);
    for i := Low(ArrFit) to ArrFitPos-1 do
      ArrFit[i] := ArrFit[i+1];
  end;
  ArrFit[ArrFitPos] := D;
  DrawFit;
end;

procedure TFormGA.ButtonStepClick(Sender: TObject);
begin
  Population.Generation;
  Display.DrawMapWithRoute(Population[0] as ITSPIndividual);
  Generations := Generations + 1;
  Plot(Population.FitnessOf(0));
end;

procedure TFormGA.ButtonRunClick(Sender: TObject);
var
  i : Integer;
begin
  for i := 1 to EditGens.Value do
  begin
    Population.Generation;
    Display.DrawMapWithRoute(Population[0] as ITSPIndividual);
    Generations := Generations + 1;
    Plot(Population.FitnessOf(0));
    Application.ProcessMessages;
  end;
end;

procedure TFormGA.PopulationChange(Sender: TObject);
var
  i : Integer;
begin
  ListBox1.Clear;

  for i := 0 to Population.Count - 1 do
  begin
    ListBox1.Items.Add(IntToStr(i+1)+': '+FloatToStr(Population.FitnessOf(i)))
  end;
end;

procedure TFormGA.EditKillChange(Sender: TObject);
begin
  KillerPercentage.Percentage := EditKill.Value;
end;

procedure TFormGA.ListBox1Click(Sender: TObject);
begin
  Display.DrawMapWithRoute(Population[ListBox1.ItemIndex] as ITSPIndividual);
end;

procedure TFormGA.EditTranspositionChange(Sender: TObject);
begin
  Mutator.Transposition := EditTransposition.Value;
end;

procedure TFormGA.EditInversionChange(Sender: TObject);
begin
  Mutator.Inversion := EditInversion.Value;
end;

procedure TFormGA.FormResize(Sender: TObject);
begin
  Display.SetRanges(0.0,11.0,0.0,11.0,1.0);
end;

end.


uDisplaytsp
{ interface-based implementation of
  Dan Taylor's (dan@logicalgenetics.com)
  Evolutionary TSP Algorithm demo program
Modified: September 2002
  by Nikolai Shokhirev (nikolai@u.arizona.edu)
}
  { Display object }
unit uDisplayTSP;

interface

uses
  uUtilsEA, uITSP, classes, controls;

type

  TTSPDisplay = class(TPainter0)
  private
    fController: ITSPController;
    {  Clear the map }
//    procedure Clear;  //is in the base class
    {  Show the cities }
    procedure DrawCities;
    {  Display a route  }
    procedure DrawRoute(Individual : ITSPIndividual);
    function GetController: ITSPController;
    procedure SetController(const Value: ITSPController);
  public
    {  The constructor }
    constructor Create(aOwner: TComponent; aParent: TWinControl);
    {  The destructor }
    destructor Destroy; override;
    {  Call this to draw the map }
    procedure DrawMap;
    {  Draw the map with a route  }
    procedure DrawMapWithRoute(Individual : ITSPIndividual);
    property Controller: ITSPController read GetController write SetController;
  end;

implementation

uses
  Graphics;

{ TTSPDisplay }

constructor TTSPDisplay.Create(aOwner: TComponent; aParent: TWinControl);
begin
  inherited;
  Clear;
end;

destructor TTSPDisplay.Destroy;
begin
  inherited;
end;

procedure TTSPDisplay.DrawCities;
var
  i : Integer;
begin
    PenColor := clBlack;
    BrushColor := clRed;
    PenWidth := 1;
    with fController do
      for i := 0 to CityCount - 1 do
        Circle(Cities[i].x, Cities[i].y,0.2);
end;

procedure TTSPDisplay.DrawMap;
begin
  Clear;
  DrawCities;
end;

procedure TTSPDisplay.DrawMapWithRoute(Individual: ITSPIndividual);
begin
  Clear;
  DrawCities;
  DrawRoute(Individual);
end;

procedure TTSPDisplay.DrawRoute(Individual: ITSPIndividual);
var
  i, c : Integer;
begin
  {  Set the pen colour and stuff }
  PenColor := clBlue;
  PenWidth := 1;

  {  Start at the first city }
  with fController do
  begin
    if Individual.Steps > 1 then
    begin
      c := Individual.RouteArray[0];
      MoveTo(Cities[c].X, Cities[c].Y);
    end;

    {  Move round the other cities }
    for i := 1 to Individual.Steps - 1 do
    begin
      c := Individual.RouteArray[i];
      LineTo(Cities[c].X, Cities[c].Y);
    end;

    c := Individual.RouteArray[0];
    LineTo(Cities[c].X, Cities[c].Y);
  end;
end;

function TTSPDisplay.GetController: ITSPController;
begin
  result := fController;
end;

procedure TTSPDisplay.SetController(const Value: ITSPController);
begin
  fController := Value;
end;

end.

uEA
unit uEA;

interface

uses
  uUtilsEA, uIEA, uITSP, Classes;

type

  TIndividual = class(TInterfacedObject, IIndividual)
  private
    // The internally stored fitness value
    fFitness: TFloat;
    procedure SetFitness(const Value: TFloat);
    function GetFitness: TFloat;
  public
    property Fitness : TFloat read GetFitness write SetFitness;
  end;

  TTSPIndividual = class(TIndividual, ITSPIndividual)
  private
    // The route we travel
    fRouteArray : ArrayInt;
    function GetRouteArray(I: Integer): Integer;
    procedure SetRouteArray(I: Integer; const Value: Integer);
    procedure SetSteps(const Value: Integer);
    function GetSteps: Integer;
  public
    // Constructor, called with initial route size
    constructor Create(Size : TInt); reintroduce;
    destructor Destroy; override;
    property RouteArray[I : Integer] : Integer read GetRouteArray write SetRouteArray;
    // The number of steps on the route
    property Steps : Integer read GetSteps write SetSteps;
    property Fitness : TFloat read GetFitness write SetFitness;
  end;

  TTSPCreator = class(TInterfacedObject, ITSPCreator)
  private
    // The Control component we are associated with
    fController: ITSPController;
    function GetController: ITSPController;
    procedure SetController(const Value: ITSPController);
  public
    // Function to create a random individual
    function CreateIndividual : IIndividual;
    property Controller : ITSPController read GetController write SetController;
  end;

  TKillerPercentage = class(TInterfacedObject, IKillerPercentage)
  private
    fPer: TFloat;
    procedure SetPercentage(const Value: TFloat);
    function GetPercentage: TFloat;
  public
    function Kill(Pop : IPopulation): Integer;
    // Percentage of population to be killed
    property Percentage: TFloat read GetPercentage write SetPercentage;
  end;

  TParentSelectorTournament = class(TInterfacedObject, IParentSelector)
  public
    function SelectParent(Population: IPopulation): IIndividual;
  end;

  TTSPBreederCrossover = class(TInterfacedObject, IBreeder)
  public
    function BreedOffspring(PSelector: IParentSelector; Pop: IPopulation): IIndividual;
  end;

  TTSPMutator = class(TInterfacedObject, ITSPMutator)
  private
    fTrans: TFloat;
    fInv: TFloat;
    procedure SetInv(const Value: TFloat);
    procedure SetTrans(const Value: TFloat);
    function GetInv: TFloat;
    function GetTrans: TFloat;
  public
    procedure Mutate(Individual: IIndividual);
    published
    // Probability of doing a transposition
    property Transposition: TFloat read GetTrans write SetTrans;
    // Probability of doing an inversion
    property Inversion: TFloat read GetInv write SetInv;
  end;

  TTSPExaminer = class(TInterfacedObject, ITSPExaminer)
  private
    // The Control component we are associated with
    fController: ITSPController;
    function GetController: ITSPController;
    procedure SetController(const Value: ITSPController);
  public
    // Returns the fitness of an individual as a real number where 0 => best
    function GetFitness(Individual : IIndividual) : TFloat;
    property Controller : ITSPController read GetController write SetController;
  end;

  TPopulation = class(TInterfacedObject, IPopulation)
  private    
    // The population
    fPop : TInterfaceList;
    // Worker for breeding
    fBreeder: IBreeder;
    // Worker for killing
    fKiller: IKiller;
    // Worker for parent selection
    fParentSelector: IParentSelector;
    // Worker for mutation
    fMutator: IMutator;
    // Worker for initial creation
    fCreator: ICreator;
    // Worker for fitness calculation
    fExaminer: IExaminer;
    // On Change event
    FOnChange: TNotifyEvent;
    procedure Change;
    // Getters and Setters
    function GetIndividual(I: Integer): IIndividual;
    function GetCount: Integer;
    function GetBreeder: IBreeder;
    function GetCreator: ICreator;
    function GetExaminer: IExaminer;
    function GetKiller: IKiller;
    function GetMutator: IMutator;
    function GetOnChange: TNotifyEvent;
    function GetParentSelector: IParentSelector;
    procedure SetBreeder(const Value: IBreeder);
    procedure SetCreator(const Value: ICreator);
    procedure SetExaminer(const Value: IExaminer);
    procedure SetKiller(const Value: IKiller);
    procedure SetMutator(const Value: IMutator);
    procedure SetOnChange(const Value: TNotifyEvent);
    procedure SetParentSelector(const Value: IParentSelector);
    // not interfaced
    procedure DanQuickSort(SortList: TInterfaceList; L, R: Integer; SCompare: TInterfaceCompare);
    procedure Sort(Compare: TInterfaceCompare);
  protected
    // Comparison function for Sort()
    function CompareIndividuals(I1, I2: IIndividual): Integer;
    // Sort the population
    procedure SortPopulation;
  public
    // The constructor
    constructor Create;
    // The destructor
    destructor Destroy; override;
    // Adds an individual to the population
    procedure Add(New : IIndividual);
    // Deletes an individual from the population
    procedure Delete(I : Integer);
    // Runs a single generation
    procedure Generation;
    // Initialise the population
    procedure Initialise(Size : Integer);
    // Clear ourselves out
    procedure Clear;
    // Get the fitness of an individual
    function FitnessOf(I : Integer) : TFloat;
    // Access to the population members
    property Pop[I : Integer] : IIndividual read GetIndividual; default;
    // The size of the population
    property Count : Integer read GetCount;
    property ParentSelector : IParentSelector read GetParentSelector write SetParentSelector;
    property Breeder : IBreeder read GetBreeder write SetBreeder;
    property Killer : IKiller read GetKiller write SetKiller;
    property Mutator : IMutator read GetMutator write SetMutator;
    property Creator : ICreator read GetCreator write SetCreator;
    property Examiner : IExaminer read GetExaminer write SetExaminer;

⌨️ 快捷键说明

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