Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Delphi - Algoritmi genetici in Delphi
Forum - Delphi - Algoritmi genetici in Delphi

Avatar
systemgvp (Normal User)
Expert


Messaggi: 296
Iscritto: 14/04/2008

Segnala al moderatore
Postato alle 15:39
Mercoledì, 08/08/2012
Salve,

siccome avevo bisogno di trovare quando la funzione Tsim = a*a + b*b + c fosse pari a Treale = 10, ho riscritto per delphi l'algoritmo genetico riportato fra i tutorial scritto in VB. Il mio problema è leggermente differente da quello, in quanto nell'esempio si cerca un massimo, mentre io cerco di minimizzare l'errore Fitness = Treale - Tsim per avvicinarmi alla soluzione.

Il problema però è che l'algoritmo non trova un errore minimo globale, ma, a ogni ricerca, tanti minimi locali. Esiste un modo per giungere ad una soluzione "minima"?

Per chi servisse riporto l'intero codice funzionante della mia applicazione:

Codice sorgente - presumibilmente Delphi

  1. unit MenuGE;
  2.  
  3. interface
  4.  
  5. uses
  6.   System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  7.   FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts, FMX.Memo,
  8.   FMX.Objects, FMX.Edit;
  9.  
  10. type
  11.   TMenuGEN = class(TForm)
  12.     Avvia: TButton;
  13.     Console_TXT: TMemo;
  14.     FermaRicerca: TCheckBox;
  15.     MostraPassaggi: TCheckBox;
  16.     Layout_sopra: TLayout;
  17.     Layout_sotto: TLayout;
  18.     ErroreMax_TXT: TEdit;
  19.     ErroreMax_LAB: TText;
  20.     ProbabilitaMutazione_TXT: TEdit;
  21.     ProbabilitaMutazione_LAB: TText;
  22.     popolazione_TXT: TEdit;
  23.     popolazione_LAB: TText;
  24.     SoluzioniPossibili_TXT: TEdit;
  25.     SoluzioniPossibili_LAB: TText;
  26.     MaxEminUguali_TXT: TEdit;
  27.     MaxEminUguali_LAB: TText;
  28.     MaxFitUguali_TXT: TEdit;
  29.     MaxFitUguali_LAB: TText;
  30.     procedure CreaPopolazione(variabili,popolazione,Max:integer);
  31.     function  CalcolaFitness(idVettore:integer):real;
  32.     procedure SceltaSoluzioni_TipoRoulette(SoluzioniPossibili,popolazione:integer);
  33.     procedure Combina_Crossover(idPadre,idMadre,variabili:integer);
  34.     procedure Combina_Mutazione(soluzione,variabili,popolazione,Max:integer; ProbabilitaMutazione:real);
  35.     procedure GeneraFigli(SoluzioniPossibili,variabili,popolazione,Max:integer;ProbabilitaMutazione:real);
  36.     procedure NuovaGenerazione(SoluzioniPossibili,variabili,popolazione:integer);
  37.     procedure MostraGenerazione(variabili,popolazione,SoluzioniPossibili,generazione:integer);
  38.     procedure VediSoluzioniOrdinate(variabili,popolazione:integer);
  39.     procedure MostraListaSoluzioniOrdinate(variabili,popolazione,generazione:integer);
  40.     procedure AvviaClick(Sender: TObject);
  41.   private
  42.     { Private declarations }
  43.     var Vettori, VettoriTemp, VettoriFigli : array of array of real;
  44.         Treale : real;
  45.         Fitness,Probabilita : array of real;
  46.         Soluzioni : array of integer;
  47.         //risultati
  48.         ListaSoluzioniOrdinate : array of array of real;
  49.         FitnessOrdinate : array of real;
  50.   public
  51.     { Public declarations }
  52.   end;
  53.  
  54. var
  55.   MenuGEN: TMenuGEN;
  56.  
  57. implementation
  58.  
  59. {$R *.fmx}
  60.  
  61. procedure TMenuGEN.CreaPopolazione(variabili,popolazione,Max:integer);
  62. var p,v,i:integer; numero:real; confermato:boolean;
  63. begin
  64. //Per iniziare, dobbiamo disporre di un insieme di soluzioni possibili, ossia
  65. //dei vettori casuali. Non è detto che queste soluzioni siano le migliori per il
  66. //problema, anzi, è altamente improbabile che lo siano poiché sono per ipotesi
  67. //casuali. Esse costituiscono il cosiddetto genetic pool, o, più semplicemente,
  68. //la popolazione della cui evoluzione ci occuperemo. Il numero di soluzioni
  69. //possibili presenti nel pool iniziale è arbitrario e definisce uno dei 4/5
  70. //parametri importanti dell'algoritmo: piùindividui favoriscono una maggiore
  71. //varietà, ma al contempo incrementano il tempo necessario per passare alla
  72. //generazione successiva (poiché ci sono più informazioni da processare).
  73.   //casualità
  74.   Randomize;
  75.   //imposta le dimensioni
  76.   SetLength(Vettori,popolazione,variabili);
  77.   //riempie la popolazione
  78.   for p := 0 to popolazione-1 do
  79.   begin
  80.     for v := 0 to variabili-1 do
  81.     begin
  82.       //valore
  83.       numero := Random(Max*10000)/10000;
  84.       //se non è il primo valore controlla che lo stesso valore non sia
  85.       //già stato assegnato alla stessa variabile di un'altra popolazione
  86.       if (p > 0) then
  87.       begin
  88.         confermato := False;
  89.         while (confermato = False) do
  90.         begin
  91.           confermato := True;
  92.           for i := 0 to p-1 do
  93.           begin
  94.             //se è già presente assegna un altro valore
  95.             if (Vettori[i,v] = numero) then
  96.             begin
  97.               confermato := False;
  98.               numero := Random(Max*10000)/10000;
  99.               break;
  100.             end;
  101.           end;
  102.         end;
  103.       end;
  104.       //assegna il valore
  105.       Vettori[p,v] := numero;
  106.     end;
  107.   end;
  108. end;
  109.  
  110. function TMenuGEN.CalcolaFitness(idVettore:integer):real;
  111. var Tsimulato : real;
  112. begin
  113. //Una volta generato il pool genetico iniziale, occore dare una spinta all'algoritmo
  114. //verso l'evoluzione. Con questo termine intendiamo il miglioramento della
  115. //popolazione attraverso il passaggio in molte generazioni successive. Ogni
  116. //generazione ha una determinata popolazione, che si è sviluppata dalla precedente
  117. //mediante selezione. Come la scienza insegna, in una popolazione ci sono individui
  118. //più o meno adatti alla riproduzione. Quelli più adatti in genere vantano
  119. //caratteristiche migliori e perciò hanno più probabilità di accoppiarsi. Nella
  120. //scrittura dell'algoritmo occorre quindi definire una funzione che ci dica
  121. //quanto buona è una soluzione. In base a questo potremmo eseguire altri calcoli
  122. //sulle probabilità di sopravvivenza.
  123.  
  124.   Tsimulato := sqr(Vettori[idVettore,0]) + sqr(Vettori[idVettore,1]) + Vettori[idVettore,2];
  125.   CalcolaFitness := abs(Treale - Tsimulato);
  126. end;
  127.  
  128. procedure TMenuGEN.SceltaSoluzioni_TipoRoulette(SoluzioniPossibili,popolazione:integer);
  129. var p,s,soluzione,EstrazioniMassime,estrazione:integer;
  130.     sommaFitness,Max,Min,numero,Pini,valoreMin:real;
  131.     idSoluzioniPossibili : array of integer;  confermato:boolean;
  132. begin
  133. //In questo tipo di selezione, l'individuo con fitness maggiore ha maggiori
  134. //probabilità di accoppiarsi, ma non è certo che questo succeda. Per calcolare
  135. //questa probabilità si prende la sua fitness e la si divide per la fitness
  136. //totale di tutta la popolazione (ossia la somma di tutte le fitness calcolate).
  137. //Il nome deriva dal fatto che, se immaginassimo di avere una lunga striscia che
  138. //rappresenta la superficie della corona circolare di una roulette e di
  139. //suddividere questa striscia in porzioni proporzionali alla fitness di ogni
  140. //individuo, allora lanciando la pallina e facendo girare la roulette, l'individuo
  141. //con la fetta più grande avrebbe maggiori possibilità che la pallina si fermi
  142. //sulla sua parte di striscia. La relazione tra f e p, tuttavia, non è proprio
  143. //proporzionale, ma piuttosto asintotica. Infatti, qualora f tendesse a infinito,
  144. //p tenderebbe a 1, rendendo certo l'evento "accoppiamento" per la soluzione data.
  145.   //limite di estrazioni per evitare loop infiniti
  146.   EstrazioniMassime := 50;
  147.   //casualità
  148.   Randomize;
  149.   //imposta le dimensioni dei vettori
  150.   SetLength(Probabilita,popolazione);
  151.   SetLength(Soluzioni,SoluzioniPossibili);
  152.   //calcola la somma degli errori
  153.   sommaFitness := 0;
  154.   Max := 0;
  155.   Min := Fitness[0];
  156.   for p := 0 to popolazione-1 do
  157.   begin
  158.     sommaFitness := sommaFitness + Fitness[p];
  159.     if (Max < Fitness[p]) then Max := Fitness[p];
  160.     if (Min > Fitness[p]) then Min := Fitness[p];
  161.   end;
  162.   //anche se improbabile controllo il minimo della somma
  163.   if (sommaFitness = 0) then sommaFitness := 1;
  164.   //calcola le probabilità singole
  165.   for p := 0 to popolazione-1 do Probabilita[p]:=((Max+Min)-Fitness[p])/sommaFitness;
  166.   //le converte in intervalli
  167.   for p := 1 to popolazione-1 do Probabilita[p]:=Probabilita[p]+Probabilita[p-1];
  168.   //imposta gli indici delle soluzioni possibili
  169.   SetLength(idSoluzioniPossibili,popolazione);
  170.   for p := 0 to popolazione-1 do idSoluzioniPossibili[p] := p;
  171.   //seleziona le possibili soluzioni dall'insieme della popolazione
  172.   for s := 0 to SoluzioniPossibili-1 do
  173.   begin
  174.     //azzera la posizione
  175.     estrazione:= 0;
  176.     soluzione := 0;
  177.     //genera una probabilità casuale, e a seconda di quale intervallo ricade,
  178.     //ne deduce la soluzione, se l'intervallo in esame non è già stato scelto
  179.     numero := Random(1000)/1000;
  180.     confermato := False;
  181.     while (confermato = False) do
  182.     begin
  183.       //cerca l'intervallo di appartenenza
  184.       soluzione := 0;
  185.       Pini      := 0;
  186.       for p := 0 to popolazione-1 do
  187.       begin
  188.         if (numero >= Pini) and (numero < Probabilita[p]) then
  189.         begin
  190.           soluzione := p;
  191.           break;
  192.         end
  193.         else Pini := Probabilita[p];
  194.       end;
  195.       //controlla che la soluzione non sia già stata scelta
  196.       if (idSoluzioniPossibili[soluzione] <> -1) then
  197.       begin
  198.         idSoluzioniPossibili[soluzione] := -1;
  199.         confermato := True;
  200.       end;
  201.       //se si deve rigenerare la probabilità
  202.       if (confermato = False) then
  203.       begin
  204.         //se il numero di estrazioni è arrivato al limite è si è entrati
  205.         //in un loop si prende il valore con Fitness più basso rimasto
  206.         if (estrazione >= EstrazioniMassime) then
  207.         begin
  208.           valoreMin := 1000000;
  209.           for p := 0 to popolazione-1 do
  210.           begin
  211.             //se la soluzione non è già stata assegnata
  212.             if (idSoluzioniPossibili[p] <> -1)  then
  213.             begin
  214.               //se possiede il valore minimo
  215.               if (Fitness[p] < valoreMin) then
  216.               begin
  217.                 valoreMin := Fitness[p];
  218.                 soluzione := p;
  219.               end;
  220.             end;
  221.           end;
  222.           //toglie la soluzione dalle scelte
  223.           idSoluzioniPossibili[soluzione] := -1;
  224.           //ferma il ciclo
  225.           confermato := True;
  226.         end
  227.         //altrimenti
  228.         else
  229.         begin
  230.           numero    := Random(1000)/1000;
  231.           estrazione:= estrazione + 1;
  232.         end;
  233.       end;
  234.     end;
  235.     //assegna la soluzione
  236.     Soluzioni[s] := soluzione;
  237.   end;
  238. end;
  239.  
  240. procedure TMenuGEN.Combina_Crossover(idPadre,idMadre,variabili:integer);
  241. var v,punto,j:integer;
  242. begin
  243. //Per far avveniare questa operazione servono due genitori: il nuovo individuo
  244. //è formato combinando i dati dei due genitori in modo "casuale". In genere, si
  245. //punta a rappresentare ogni soluzione come array di dati o stringhe di caratteri,
  246. //detti cromosomi, poiché è molto semplice mescolarli: basta scegliere un punto
  247. //qualsiasi dell'array e formarne uno nuovo attaccando ai dati che lo precedono
  248. //i dati dell'altro genitore che seguono quello stesso punto.
  249.   //casualità
  250.   Randomize;
  251.   //punto in cui spezzare il dna //cerca di prendere il punto centrale
  252.   punto := 0;
  253.   if (variabili > 2) then punto := Random(variabili-2) + 1;
  254.   //incrementa il vettore
  255.   j := Length(VettoriFigli);
  256.   SetLength(VettoriFigli,j+1,variabili);
  257.   //genera il figlio
  258.   for v := 0 to variabili-1 do
  259.   begin
  260.     if (v <= punto) then VettoriFigli[j,v] := Vettori[idPadre,v]
  261.     else VettoriFigli[j,v] := Vettori[idMadre,v];
  262.   end;
  263. end;
  264.  
  265. procedure TMenuGEN.Combina_Mutazione(soluzione,variabili,popolazione,Max:integer; ProbabilitaMutazione:real);
  266. var p,variabile:integer; valore:real; confermato:boolean;
  267. begin
  268. //E' naturale che durante l'evoluzione si verifichino degli eventi imprevisti
  269. //che cambiano il codice gentico degli individui. È proprio la mutazione che
  270. //favorisce l'evoluzione, poiché altrimenti non si potrebbero affermare nuove
  271. //caratteristiche. La probabilità di mutazione è un altro importante parametro
  272. //dell'algoritmo. Dopo il crossover c'è una certa probabilità che un esemplare
  273. //venga modificato casualmente.
  274. //casualità
  275. Randomize;
  276. //se si ha la possibilità di avere una mutazione
  277. if (Random(100)/100 >= ProbabilitaMutazione) then
  278. begin
  279.   //variabile da mutare
  280.   variabile := Random(variabili);
  281.   //genera il nuovo valore
  282.   valore := Random(Max*10000)/10000;
  283.   //procedura di conferma del valore per vedere che non esista già
  284.   confermato := False;
  285.   while (confermato = False) do
  286.   begin
  287.     confermato := True;
  288.     for p := 0 to popolazione-1 do
  289.     begin
  290.       //se questo valore esiste già
  291.       if (Vettori[p,variabile] = valore) then
  292.       begin
  293.         confermato := False;
  294.         //genera un nuovo valore
  295.         valore := Random(Max*10000)/10000;
  296.         break;
  297.       end;
  298.     end;
  299.   end;
  300.   //assegna il nuovo valore
  301.   VettoriFigli[soluzione,variabile] := valore;
  302. end;
  303. end;
  304.  
  305. procedure TMenuGEN.GeneraFigli(SoluzioniPossibili,variabili,popolazione,Max:integer;ProbabilitaMutazione:real);
  306. var sol,figlio:integer;
  307. begin
  308.   //azzera il vettore dei figli
  309.   SetLength(VettoriFigli,0,variabili);
  310.   //azzera gli indici
  311.   figlio := 0;
  312.   sol    := 0;
  313.   //per tutte le soluzioni probabilisticamente migliori genera i figli
  314.   while (sol <= SoluzioniPossibili-2) do
  315.   begin
  316.     Combina_Crossover(Soluzioni[sol],Soluzioni[sol+1],variabili);
  317.     Combina_Mutazione(figlio,variabili,popolazione,Max,ProbabilitaMutazione);
  318.     //incrementa i contatori
  319.     sol    := sol    + 2;
  320.     figlio := figlio + 1;
  321.   end;
  322. end;
  323.  
  324. procedure TMenuGEN.NuovaGenerazione(SoluzioniPossibili,variabili,popolazione:integer);
  325. var p,v,s,ind:integer; indici : array of integer; temporanea:real;
  326. begin
  327. //In ogni generazione si susseguono le seguenti fasi: calcolo della fitness di
  328. //ogni invidiuo, selezione, crossover, mutazione, morte dei meno adatti.
  329. //Nell'ultima fase, gli individui peggiori "muoiono", vengono rimossi dalla
  330. //popolazione. Al loro posto sopraggiungono i figli dei candidati all'accoppiamento.
  331. //La dimensione della popolazione rimane comunque costante. Un algoritmo
  332. //genetico è costituito dal succedersi delle generazioni.
  333.   //copia i vettori in una matrice di vettori temporanea
  334.   SetLength(VettoriTemp,popolazione,variabili);
  335.   for p := 0 to popolazione-1 do
  336.   begin
  337.     for v := 0 to variabili-1 do VettoriTemp[p,v] := Vettori[p,v];
  338.   end;
  339.   //genera la lista degli indici
  340.   SetLength(indici,popolazione);
  341.   for p := 0 to popolazione-1 do indici[p] := p;
  342.   //ordina il vettore delle Fitness dal più grande al più piccolo spostando
  343.   //anche gli indici delle posizioni
  344.   for v := 1 to popolazione-1 do
  345.   begin
  346.    for p := 0 to popolazione-2 do
  347.    begin
  348.      if (Fitness[p]<Fitness[p+1]) then
  349.      begin
  350.        temporanea   := Fitness[p+1];
  351.        Fitness[p+1] := Fitness[p];
  352.        Fitness[p]   := temporanea;
  353.        //indici
  354.        ind          := indici[p+1];
  355.        indici[p+1]  := indici[p];
  356.        indici[p]    := ind;
  357.      end;
  358.    end;
  359.   end;
  360.   //ordina i vettori della popolazione in funzione delle Fitness ordinate
  361.   for p := 0 to popolazione-1 do
  362.   begin
  363.     for v := 0 to variabili-1 do Vettori[p,v] := VettoriTemp[indici[p],v];
  364.   end;
  365.   //sostituisce gli individui con Fitness (errore) alti con i
  366.   //figli di quelli che hanno avuto Fitness basse
  367.   for s := 0 to Length(VettoriFigli)-1 do
  368.   begin
  369.     for v := 0 to variabili-1 do Vettori[s,v] := VettoriFigli[s,v];
  370.   end;
  371. end;
  372.  
  373. procedure TMenuGEN.MostraGenerazione(variabili,popolazione,SoluzioniPossibili,generazione:integer);
  374. var p,v,s:integer; stringa:string;
  375. begin
  376.   //intestazione
  377.   Console_TXT.Lines.Append('GENERAZIONE : '+intToStr(generazione));
  378.   Console_TXT.Lines.Append('');
  379.   stringa := 'ind';
  380.   for v := 0 to variabili-1 do stringa := stringa +#9+ intToStr(v+1);
  381.   stringa := stringa +#9+ 'Fitness' +#9+ 'scelta';
  382.   Console_TXT.Lines.Append(stringa);
  383.   //dati
  384.   for p := 0 to popolazione-1 do
  385.   begin
  386.     stringa := inttostr(p);
  387.     for v := 0 to variabili-1 do stringa := stringa +#9+ CurrToStr(Vettori[p,v]);
  388.     stringa := stringa +#9+ CurrToStr(Fitness[p]);
  389.     for s := 0 to SoluzioniPossibili-1 do
  390.     begin
  391.       if (Soluzioni[s] = p) then stringa := stringa +#9+ 'x';
  392.     end;
  393.     Console_TXT.Lines.Append(stringa);
  394.   end;
  395.   Console_TXT.Lines.Append('');
  396.   //figli
  397.   for s := 0 to Length(VettoriFigli)-1 do
  398.   begin
  399.     stringa := inttostr(s);
  400.     for v := 0 to variabili-1 do stringa := stringa +#9+ CurrToStr(VettoriFigli[s,v]);
  401.     Console_TXT.Lines.Append(stringa);
  402.   end;
  403.   Console_TXT.Lines.Append('');
  404.   //aggiorna la grafica
  405.   Application.ProcessMessages;
  406. end;
  407.  
  408. procedure TMenuGEN.VediSoluzioniOrdinate(variabili,popolazione:integer);
  409. var p,v,ind:integer; indici:array of integer; temporanea:real;
  410. begin
  411.   //dimensiona le matrici e i vettori
  412.   SetLength(FitnessOrdinate,popolazione);
  413.   SetLength(ListaSoluzioniOrdinate,popolazione,variabili);
  414.   //riempie i vettori
  415.   for p := 0 to popolazione-1 do FitnessOrdinate[p] := Fitness[p];
  416.   //genera la lista degli indici
  417.   SetLength(indici,popolazione);
  418.   for p := 0 to popolazione-1 do indici[p] := p;
  419.   //ordina il vettore delle Fitness dal più grande al più piccolo spostando
  420.   //anche gli indici delle posizioni
  421.   for v := 1 to popolazione-1 do
  422.   begin
  423.    for p := 0 to popolazione-2 do
  424.    begin
  425.      if (FitnessOrdinate[p]>FitnessOrdinate[p+1]) then
  426.      begin
  427.        temporanea   := FitnessOrdinate[p+1];
  428.        FitnessOrdinate[p+1] := FitnessOrdinate[p];
  429.        FitnessOrdinate[p]   := temporanea;
  430.        //indici
  431.        ind          := indici[p+1];
  432.        indici[p+1]  := indici[p];
  433.        indici[p]    := ind;
  434.      end;
  435.    end;
  436.   end;
  437.   //ordina i vettori della popolazione in funzione delle Fitness ordinate
  438.   for p := 0 to popolazione-1 do
  439.   begin
  440.     for v := 0 to variabili-1 do ListaSoluzioniOrdinate[p,v] := Vettori[indici[p],v];
  441.   end;
  442. end;
  443.  
  444. procedure TMenuGEN.MostraListaSoluzioniOrdinate(variabili,popolazione,generazione:integer);
  445. var p,v:integer; stringa:string;
  446. begin
  447.   //intestazione
  448.   Console_TXT.Lines.Append('GENERAZIONE : '+intToStr(generazione));
  449.   Console_TXT.Lines.Append('');
  450.   stringa := 'ind';
  451.   for v := 0 to variabili-1 do stringa := stringa +#9+ intToStr(v+1);
  452.   stringa := stringa +#9+ 'Fitness';
  453.   Console_TXT.Lines.Append(stringa);
  454.   //dati
  455.   for p := 0 to popolazione-1 do
  456.   begin
  457.     stringa := inttostr(p);
  458.     for v := 0 to variabili-1 do stringa := stringa +#9+ CurrToStr(ListaSoluzioniOrdinate[p,v]);
  459.     stringa := stringa +#9+ FloatToStr(FitnessOrdinate[p]);
  460.     Console_TXT.Lines.Append(stringa);
  461.   end;
  462.   Console_TXT.Lines.Append('');
  463.   //aggiorna la grafica
  464.   Application.ProcessMessages;
  465. end;
  466.  
  467. procedure TMenuGEN.AvviaClick(Sender: TObject);
  468. var p,variabili,popolazione,Max,SoluzioniPossibili,AggiornamentoSchermo:integer;
  469.     ContFitUguali,MaxFitUguali,generazione,ContEminUguali,MaxEminUguali:integer;
  470.     ProbabilitaMutazione,ErroreMax,FitTotPrec,FitnessTot:real;
  471. begin
  472.   Console_TXT.Lines.Clear;
  473.   if (FermaRicerca.IsChecked = True) then FermaRicerca.IsChecked := False;
  474.   //variabile da ricercare
  475.   Treale := 10;
  476.   //variabili
  477.   variabili            := 3;
  478.   //valore massimo delle variabili
  479.   Max                  := 20;
  480.   //popolazione
  481.   popolazione          := StrToInt(popolazione_TXT.Text);
  482.   //individui selezinabili
  483.   //deve essere sempre un numero pari emassimo il doppio della popolazione
  484.   SoluzioniPossibili   := StrToInt(SoluzioniPossibili_TXT.Text);
  485.   //probabilità do avere una mutazione
  486.   ProbabilitaMutazione := StrToFloat(ProbabilitaMutazione_TXT.Text);
  487.   //massimo errore accettabile
  488.   ErroreMax            := StrToFloat(ErroreMax_TXT.Text) * popolazione;
  489.   //iterazioni massime costanti per evitare loop
  490.   MaxFitUguali         := StrToInt(MaxFitUguali_TXT.Text);
  491.   //soluzione costante per avere la certezza della soluzione
  492.   MaxEminUguali        := StrToInt(MaxEminUguali_TXT.Text);
  493.   //aggiornamento dello schermo
  494.   AggiornamentoSchermo := 250;
  495.   //crea la popolazione
  496.   generazione := 0;
  497.   CreaPopolazione(variabili,popolazione,Max);
  498.   //calcola le funzioni di Fitness per ogni individuo
  499.   SetLength(Fitness,popolazione);
  500.   for p := 0 to popolazione-1 do
  501.   begin
  502.     Fitness[p] := 10000;
  503.     Fitness[p] := CalcolaFitness(p);
  504.   end;
  505.   //col metodo della Roulet scegli gli individui per la riproduzione
  506.   SceltaSoluzioni_TipoRoulette(SoluzioniPossibili,popolazione);
  507.   //dalle soluzioni probabilisticamente migliori genera i figli
  508.   GeneraFigli(SoluzioniPossibili,variabili,popolazione,Max,ProbabilitaMutazione);
  509.   //mostra i dati
  510.   if (MostraPassaggi.IsChecked = True) then MostraGenerazione(variabili,popolazione,SoluzioniPossibili,generazione);
  511.   //calcola l'errore totale
  512.   FitnessTot := 0;
  513.   for p := 0 to popolazione-1 do FitnessTot := FitnessTot + Fitness[p];
  514.   //aggiorna l'errore precedente
  515.   ContFitUguali := 1;
  516.   ContEminUguali:= 1;
  517.   FitTotPrec    := FitnessTot;
  518.   //ciclo iterativo di calcolo
  519.   while ((FitnessTot>=ErroreMax) and (ContEminUguali<MaxEminUguali)) or (ContFitUguali<MaxFitUguali) or (FermaRicerca.IsChecked = False) do
  520.   begin
  521.     generazione := generazione + 1;
  522.     //crea la nuova generazione di individui
  523.     NuovaGenerazione(SoluzioniPossibili,variabili,popolazione);
  524.     //calcola le funzioni di Fitness per ogni individuo
  525.     for p := 0 to popolazione-1 do
  526.     begin
  527.       Fitness[p] := 10000;
  528.       Fitness[p] := CalcolaFitness(p);
  529.     end;
  530.     //col metodo della Roulet scegli gli individui per la riproduzione
  531.     SceltaSoluzioni_TipoRoulette(SoluzioniPossibili,popolazione);
  532.     //dalle soluzioni probabilisticamente migliori genera i figli
  533.     GeneraFigli(SoluzioniPossibili,variabili,popolazione,Max,ProbabilitaMutazione);
  534.     //mostra i dati
  535.     if (MostraPassaggi.IsChecked = True) then MostraGenerazione(variabili,popolazione,SoluzioniPossibili,generazione);
  536.     //calcola l'errore totale
  537.     FitnessTot := 0;
  538.     for p := 0 to popolazione-1 do FitnessTot := FitnessTot + Fitness[p];
  539.     //controlla se uguale a quello precedente
  540.     if (FitnessTot = FitTotPrec) then ContFitUguali := ContFitUguali + 1
  541.     else ContFitUguali := 1;
  542.     if (FitnessTot = FitTotPrec) and (FitnessTot<ErroreMax) then ContEminUguali := ContEminUguali + 1
  543.     else ContEminUguali := 1;
  544.     //aggiorna l'errore precedente
  545.     FitTotPrec    := FitnessTot;
  546.     //ipotesi di fermo il ciclo
  547.     if ((FitnessTot<ErroreMax) and (ContEminUguali>=MaxEminUguali)) or (ContFitUguali>=MaxFitUguali) or (FermaRicerca.IsChecked = True) then
  548.     begin
  549.       Console_TXT.Lines.Append('CICLO INTERROTTO-----------------------------');
  550.       if (FitnessTot<ErroreMax) and (ContEminUguali>=MaxEminUguali) then Console_TXT.Lines.Append('...per errore minimo');
  551.       if (ContFitUguali >= MaxFitUguali) then Console_TXT.Lines.Append('...per errori tipo loop');
  552.       if (FermaRicerca.IsChecked = True) then Console_TXT.Lines.Append('...manualmente');
  553.       Console_TXT.Lines.Append('');
  554.       Application.ProcessMessages;
  555.       break;
  556.     end;
  557.     //aggiorna lo schermo
  558.     if (generazione >= AggiornamentoSchermo) then
  559.     begin
  560.       Application.ProcessMessages;
  561.       AggiornamentoSchermo := AggiornamentoSchermo + 250;
  562.     end;
  563.   end;
  564.   VediSoluzioniOrdinate(variabili,popolazione);
  565.   //mostra i dati dell'ultima soluzione trovata
  566.   MostraListaSoluzioniOrdinate(variabili,popolazione,generazione);
  567. end;
  568.  
  569.  
  570. end.


PM Quote
Avatar
Goblin (Member)
Expert


Messaggi: 375
Iscritto: 02/02/2011

Segnala al moderatore
Postato alle 21:02
Giovedì, 09/08/2012
Se mi butti su anche il file .fmx :) mi eviti un lavoraccio cinese :)
Anche se con questo genere di algoritmi non ci "azzecco" molto ma dato che non al momento non ho niente da fare potrei intripparmi :)
g.


Ibis redibis non morieris in bello
PM Quote
Avatar
systemgvp (Normal User)
Expert


Messaggi: 296
Iscritto: 14/04/2008

Segnala al moderatore
Postato alle 21:37
Giovedì, 09/08/2012
eccolo

Codice sorgente - presumibilmente Delphi

  1. object MenuGEN: TMenuGEN
  2.   Left = 0
  3.   Top = 0
  4.   Caption = 'Algoritmo genetico'
  5.   ClientHeight = 446
  6.   ClientWidth = 454
  7.   Position = poScreenCenter
  8.   Visible = False
  9.   Fill.Color = xFF95C2F4
  10.   Fill.Kind = bkSolid
  11.   StyleLookup = 'backgroundstyle'
  12.   object Console_TXT: TMemo
  13.     Align = alClient
  14.     Position.Point = '(4,31)'
  15.     Width = 446.000000000000000000
  16.     Height = 355.000000000000000000
  17.     Padding.Rect = '(4,0,4,4)'
  18.     TabOrder = 0
  19.     KeyboardType = vktDefault
  20.   end
  21.   object Layout_sopra: TLayout
  22.     Align = alTop
  23.     Width = 454.000000000000000000
  24.     Height = 31.000000000000000000
  25.     object Avvia: TButton
  26.       Align = alTop
  27.       Position.Point = '(230,4)'
  28.       Width = 220.000000000000000000
  29.       Height = 22.000000000000000000
  30.       Padding.Rect = '(230,4,4,4)'
  31.       OnClick = AvviaClick
  32.       TabOrder = 0
  33.       Text = 'Avvia'
  34.     end
  35.     object FermaRicerca: TCheckBox
  36.       Position.Point = '(4,5)'
  37.       Width = 110.000000000000000000
  38.       Height = 19.000000000000000000
  39.       TabOrder = 1
  40.       Text = 'Ferma la Ricerca'
  41.     end
  42.     object MostraPassaggi: TCheckBox
  43.       Position.Point = '(116,5)'
  44.       Width = 112.000000000000000000
  45.       Height = 19.000000000000000000
  46.       TabOrder = 2
  47.       Text = 'Mostra Passaggi'
  48.     end
  49.   end
  50.   object Layout_sotto: TLayout
  51.     Align = alBottom
  52.     Position.Point = '(0,390)'
  53.     Width = 454.000000000000000000
  54.     Height = 56.000000000000000000
  55.     object ErroreMax_TXT: TEdit
  56.       Position.Point = '(72,5)'
  57.       Width = 49.000000000000000000
  58.       Height = 22.000000000000000000
  59.       TabOrder = 0
  60.       TextAlign = taCenter
  61.       KeyboardType = vktDefault
  62.       Password = False
  63.       Text = '0,01'
  64.       object ErroreMax_LAB: TText
  65.         Position.Point = '(-68,0)'
  66.         Width = 70.000000000000000000
  67.         Height = 22.000000000000000000
  68.         Text = 'ErroreMax'
  69.         WordWrap = False
  70.       end
  71.     end
  72.     object ProbabilitaMutazione_TXT: TEdit
  73.       Position.Point = '(248,5)'
  74.       Width = 49.000000000000000000
  75.       Height = 22.000000000000000000
  76.       TabOrder = 1
  77.       TextAlign = taCenter
  78.       KeyboardType = vktDefault
  79.       Password = False
  80.       Text = '0,4'
  81.       object ProbabilitaMutazione_LAB: TText
  82.         Position.Point = '(-120,0)'
  83.         Width = 122.000000000000000000
  84.         Height = 22.000000000000000000
  85.         Text = 'ProbabilitaMutazione'
  86.         WordWrap = False
  87.       end
  88.     end
  89.     object popolazione_TXT: TEdit
  90.       Position.Point = '(76,30)'
  91.       Width = 49.000000000000000000
  92.       Height = 22.000000000000000000
  93.       TabOrder = 2
  94.       TextAlign = taCenter
  95.       KeyboardType = vktDefault
  96.       Password = False
  97.       Text = '10'
  98.       object popolazione_LAB: TText
  99.         Position.Point = '(-72,0)'
  100.         Width = 74.000000000000000000
  101.         Height = 22.000000000000000000
  102.         Text = 'popolazione'
  103.         WordWrap = False
  104.       end
  105.     end
  106.     object SoluzioniPossibili_TXT: TEdit
  107.       Position.Point = '(400,30)'
  108.       Width = 49.000000000000000000
  109.       Height = 22.000000000000000000
  110.       TabOrder = 3
  111.       TextAlign = taCenter
  112.       KeyboardType = vktDefault
  113.       Password = False
  114.       Text = '6'
  115.       object SoluzioniPossibili_LAB: TText
  116.         Position.Point = '(-100,0)'
  117.         Width = 102.000000000000000000
  118.         Height = 22.000000000000000000
  119.         Text = 'SoluzioniPossibili'
  120.         WordWrap = False
  121.       end
  122.     end
  123.     object MaxEminUguali_TXT: TEdit
  124.       Position.Point = '(400,5)'
  125.       Width = 49.000000000000000000
  126.       Height = 22.000000000000000000
  127.       TabOrder = 4
  128.       TextAlign = taCenter
  129.       KeyboardType = vktDefault
  130.       Password = False
  131.       Text = '3'
  132.       object MaxEminUguali_LAB: TText
  133.         Position.Point = '(-96,0)'
  134.         Width = 98.000000000000000000
  135.         Height = 22.000000000000000000
  136.         Text = 'MaxErrMinUguali'
  137.         WordWrap = False
  138.       end
  139.     end
  140.     object MaxFitUguali_TXT: TEdit
  141.       Position.Point = '(224,30)'
  142.       Width = 49.000000000000000000
  143.       Height = 22.000000000000000000
  144.       TabOrder = 5
  145.       TextAlign = taCenter
  146.       KeyboardType = vktDefault
  147.       Password = False
  148.       Text = '100'
  149.       object MaxFitUguali_LAB: TText
  150.         Position.Point = '(-96,0)'
  151.         Width = 98.000000000000000000
  152.         Height = 22.000000000000000000
  153.         Text = 'MaxFitnessUguali'
  154.         WordWrap = False
  155.       end
  156.     end
  157.   end
  158. end


PM Quote