program się wiesza

0

Mam wielka prośbe...
Pisze maly programik z algorytmów genetycznych i nie wiem dlaczego ale program dosc czesto mi sie wiesza, tak jak by sie gdzies zapetlal :/ bede wdzieczny za wszelkie wskazowki na temat ewentualnych bledow w moim programiku

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    RichEdit1: TRichEdit;
    EChrom1: TEdit;
    EChrom2: TEdit;
    EChrom3: TEdit;
    EChrom4: TEdit;
    EChrom0: TEdit;
    Eliczbaiter: TEdit;
    Eliczbamut: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  chromosom: array [0..4] of string;
  tab_krzyzowania: array [0..4,0..1] of string;
  chromosomInt: array [0..4] of integer;
  sum_przystInt, przedz0,przedz1,przedz2,przedz3,przedz4, losowanie,para,cut:integer;
  make_chrom:string;
implementation

{$R *.dfm}
function BinToInt(chromosom : string) : Integer;
begin
  BinToInt:=StrToInt(copy(chromosom,1,1))*16+StrToInt(copy(chromosom,2,1))*8+StrToInt(copy(chromosom,3,1))*4+StrToInt(copy(chromosom,4,1))*2+StrToInt(copy(chromosom,5,1))*1;
end;

function wart_f (x :integer) : integer;
begin
   wart_f:=2*x;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i,j :integer;

begin
RichEdit1.Clear;

for i:=0 to 4 do
begin
  randomize;
  chromosom[i]:=IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2));
end;
  EChrom0.Text:=Chromosom[0];
  EChrom1.Text:=Chromosom[1];
  EChrom2.Text:=Chromosom[2];
  EChrom3.Text:=Chromosom[3];
  EChrom4.Text:=Chromosom[4];

for j:=1 to 100 do //bez tej petli zawiesza mi sie raz na 30 a z nia prawie za kazdym razem
begin

  for i:=0 to 4 do
  begin
   chromosomInt[i]:=BinToInt(Chromosom[i]);
   RichEdit1.Lines.Add(Chromosom[i]+'->'+IntToStr(chromosomInt[i]));
  end;
  RichEdit1.Lines.Add('**********************');
  sum_przystInt:=0;
  for i:=0 to 4 do
  begin
  sum_przystInt:=sum_przystInt+wart_f(ChromosomInt[i]);
  end;
  //RichEdit1.Lines.Add(IntToStr(sum_przystInt));

  przedz0:=wart_f(ChromosomInt[0]);
  przedz1:=przedz0+wart_f(ChromosomInt[1]);
  przedz2:=przedz1+wart_f(ChromosomInt[2]);
  przedz3:=przedz2+wart_f(ChromosomInt[3]);
  przedz4:=przedz3+wart_f(ChromosomInt[4]);

  for i:=0 to 4 do
  begin
    losowanie:=random(sum_przystInt)+1;
    //RichEdit1.Lines.Add('wylosowano '+IntToStr(losowanie));
    if (losowanie>0) AND (losowanie<=przedz0) then
    begin
      tab_krzyzowania[i,0]:=Chromosom[0];
      RichEdit1.Lines.Add(chromosom[0])
    end
    else if (losowanie>przedz0) AND (losowanie<=przedz1) then
    begin
      tab_krzyzowania[i,0]:=Chromosom[1];
      RichEdit1.Lines.Add(chromosom[1])
    end
    else if (losowanie>przedz1) AND (losowanie<=przedz2) then
    begin
      tab_krzyzowania[i,0]:=Chromosom[2];
      RichEdit1.Lines.Add(chromosom[2])
    end
    else if (losowanie>przedz2) AND (losowanie<=przedz3) then
    begin
      tab_krzyzowania[i,0]:=Chromosom[3];
      RichEdit1.Lines.Add(chromosom[3])
    end
    else if (losowanie>przedz3) AND (losowanie<=przedz4) then
    begin
      tab_krzyzowania[i,0]:=Chromosom[4];
      RichEdit1.Lines.Add(chromosom[4])
    end;
  end;

  for i:=0 to 4 do
    begin
      repeat
      begin
      para:=random(5);
      tab_krzyzowania[i,1]:=tab_krzyzowania[para,0];
      end
      until tab_krzyzowania[i,0]<>tab_krzyzowania[i,1];
    end;

  for i:=0 to 4 do
    begin
      cut:=random(5)+1;
      Chromosom[i]:=copy(tab_krzyzowania[i,0],1,cut)+copy(tab_krzyzowania[i,1],cut+1,5-cut);
    end;

end;

end;

end.
0

a więc tak

  1. Random wywołuje się TYLKO RAZ
  2. formatowanie kodu masz straszne
  3. ogólnie cały algorytm krzyżowania masz do kitu bo już po 3 przebiegach (pętli od 1 do 100) warunek wyjścia z tej pętli
      repeat
        para := random(5);
        tab_krzyzowania[i, 1] := tab_krzyzowania[para, 0];
      until tab_krzyzowania[i, 0] <> tab_krzyzowania[i, 1];

nigdy nie będzie spełniony

0

W pętli dla zmiennej j masz aż 5 pętli dla zmiennej i. Z powodzeniem możesz zamienić 5 pętli dla i na jedną pętlę dla i.

Poza tym wstaw w pętli dla j:

Application.ProcessMessages;

. Na pewno trochę spowolni to całą pracę, ale nie będzie uciążliwego "zawieszenia".

Zmienne globalne:

  tab_krzyzowania: array [0..4,0..1] of string;
  chromosomInt: array [0..4] of integer;
  sum_przystInt, przedz0,przedz1,przedz2,przedz3,przedz4, losowanie,para,cut:integer;

powinieneś zamienić na lokalne, ponieważ używasz ich tylko w jednej procedurze/funkcji.

Zmiennej globalnej nigdy nie użyłeś:

make_chrom:string;

Popraw formatowanie kodu.

0

przeczytalem artykul o poprawnym formatowaniu i poprawilem kod, mam nadzieje, ze teraz wyglada lepiej. Niestety nadal mimo wszystko nie wiem dlaczego sie zapetla w nieskonczonosc. Juz wiem, ze to prawdopodobnie wina petli repeat..until ale wydaje mi sie, ze ten warunek jest dobrze napisany. Bede wdzieczny za dalsze wskazowki

I jeszcze jedno pytanie. Dopiero zaczynam zabawe w programowanie i nie moge sobie wyobrazic jak te 3 petle po i moge zastapic jedna. Najpierw ma sie ykonac to co w petli ierwszej, potem wynik dzialani pierwszej jest wykorzystany w drugiej itd. Nie mam pomyslu jak to zrobic w jednej petli...

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    RichEdit1: TRichEdit;
    EChrom1: TEdit;
    EChrom2: TEdit;
    EChrom3: TEdit;
    EChrom4: TEdit;
    EChrom0: TEdit;
    Eliczbaiter: TEdit;
    Eliczbamut: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
//----------------zamiana lizby w ppostaci binarnej na dziesietna------------
function BinToInt(chromosom : string) : Integer;
begin
  BinToInt:=StrToInt(copy(chromosom,1,1))*16+StrToInt(copy(chromosom,2,1))*8+StrToInt(copy(chromosom,3,1))*4+StrToInt(copy(chromosom,4,1))*2+StrToInt(copy(chromosom,5,1))*1;
end;
//----------------obliczenie wartosci funkcji od x----------------------------
function wart_f (x :integer) : integer;
begin
  wart_f:=2*x;
end;

//----------------głowna czesc programu---------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
  i,j :integer;
  Chromosom: array [0..4] of string;     //tblica chromosomow w postaci binarnej
  ChromosomInt: array [0..4] of integer; //tablica chromosomow w postaci dziesietnej
  Tab_Krzyzowania: array [0..4,0..1] of string;  //tablica z parami chromosomow do krzyzowania
  Sum_PrzystInt, przedz0,przedz1,przedz2,przedz3,przedz4, losowanie,para,cut:integer;
begin
  randomize;
  RichEdit1.Clear;
  for i:=0 to 4 do
  begin
    Chromosom[i]:=IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2))+IntToStr(random(2));
  end;
  EChrom0.Text:=Chromosom[0];
  EChrom1.Text:=Chromosom[1];
  EChrom2.Text:=Chromosom[2];
  EChrom3.Text:=Chromosom[3];
  EChrom4.Text:=Chromosom[4];

  for j:=1 to StrToInt(Eliczbaiter.Text) do
  begin
    Application.ProcessMessages;
    for i:=0 to 4 do
    begin
     ChromosomInt[i]:=BinToInt(Chromosom[i]);
     RichEdit1.Lines.Add(Chromosom[i]+'->'+IntToStr(ChromosomInt[i]));
    end;
    RichEdit1.Lines.Add('**********************');
    Sum_PrzystInt:=0;
    for i:=0 to 4 do
    begin
      Sum_PrzystInt:=Sum_PrzystInt+wart_f(ChromosomInt[i]);
    end;
    //RichEdit1.Lines.Add(IntToStr(sum_przystInt));

    //----wyznaczanie 'wirtualnych przedzialow' dla losowania z roznym prawdop.
    przedz0:=wart_f(ChromosomInt[0]);
    przedz1:=przedz0+wart_f(ChromosomInt[1]);
    przedz2:=przedz1+wart_f(ChromosomInt[2]);
    przedz3:=przedz2+wart_f(ChromosomInt[3]);
    przedz4:=przedz3+wart_f(ChromosomInt[4]);

    for i:=0 to 4 do
    begin
      losowanie:=random(sum_przystInt)+1;
      RichEdit1.Lines.Add('wylosowano '+IntToStr(losowanie));
      if (losowanie>0) AND (losowanie<=przedz0) then
      begin
        tab_krzyzowania[i,0]:=Chromosom[0];
        RichEdit1.Lines.Add(chromosom[0])
      end
      else if (losowanie>przedz0) AND (losowanie<=przedz1) then
      begin
        tab_krzyzowania[i,0]:=Chromosom[1];
        RichEdit1.Lines.Add(chromosom[1])
      end
      else if (losowanie>przedz1) AND (losowanie<=przedz2) then
      begin
        tab_krzyzowania[i,0]:=Chromosom[2];
        RichEdit1.Lines.Add(chromosom[2])
      end
      else if (losowanie>przedz2) AND (losowanie<=przedz3) then
      begin
        tab_krzyzowania[i,0]:=Chromosom[3];
        RichEdit1.Lines.Add(chromosom[3])
      end
      else if (losowanie>przedz3) AND (losowanie<=przedz4) then
      begin
        tab_krzyzowania[i,0]:=Chromosom[4];
        RichEdit1.Lines.Add(chromosom[4])
      end;
    end;

   para:=0;
   for i:=0 to 4 do
      begin
        repeat
          para:=random(5);
          tab_krzyzowania[i,1]:=tab_krzyzowania[para,0];
        until tab_krzyzowania[i,0]<>tab_krzyzowania[i,1];
      end;

   for i:=0 to 4 do
     begin
       cut:=random(5)+1;
       Chromosom[i]:=copy(tab_krzyzowania[i,0],1,cut)+copy(tab_krzyzowania[i,1],cut+1,5-cut);
     end;
  end;

end;

end.

1 użytkowników online, w tym zalogowanych: 0, gości: 1