selekcja metodą ruletki

0

Mam tablicę np. double tab[10], gdzie przechowuję wartość funkcji przystosowania dla poszczególnych osobników. W tym wypadku im wartość mniejsza tym osobnik jest bardziej przystosowany. Jak zaimplementować w C++ funkcję dokonującą selekcję 10 osobników metodą ruletki ?

0

liczysz sumę stopnia przystosowania dla wszystkich osobników, obliczasz ta_suma* rand()/(double)RAND_MAX i od tej wartości po kolei odejmujesz stopień przystosowania kolejnego osobnika. Gdy dla danego osobnika osiągniesz wartość ujemną, to tego osobnika bierzesz do rozmnażania.

0

To jest tak popularny temat że dziwne że o to pytasz.

Ten algorytm to najmilsza część GA.

Odpowiedź od MarekR22 powinna wystarczyć.

0

Algorytm jaki podał @MarekR22 jest dobry i poprawny tylko że zakłada że największy element jest bardziej przystosowany. Więc przed jego użyciem trzeba do tego stanu doprowadzić.
Znajdujesz element o wartości maksymalnej MAX oraz minimalnej MIN.
f(i)=MAX+MIN-tab[i].
Sumę liczysz f(i) oraz odejmujesz f(i) wg powyższego algorytmu.

0

Można zrobić bez odejmowania - pseudo-kod:

a = suma elementów
b = wartość losowa od 0.0 do a włącznie
c = element[0]
i = 0

dopóki (c < b) oraz (i < liczba-elementów - 1)
{
   zwiększ i
   c = c + element[i];
}
 
i = nr wylosowany
0

@vpiotr, załóżmy że mamy tylko 3 elementy w tablice element[]={1,10,100};
wg podanego przez ciebie algorytmu losujemy wartość b w zakresie od 0 do 111
c=1;
i=0;
dopóki (c<b) // tu jedyną szansą na wylosowanie zerowego elementu jest warunek b=0;
czyli element 0 o wartości 1, najlepiej przystosowany wg założeń pytającego ma szanse na rozmnożenie z prawdopodobieństwem 1/112 !
No chyba że nie przeczytałeś uważnie pytania ani mojego postu.

0
_13th_Dragon napisał(a):

No chyba że nie przeczytałeś uważnie pytania ani mojego postu.

Dokładnie tak, mea culpa.
Trzeba to albo najpierw znormalizować albo zastosować inny algorytm.

0
_13th_Dragon napisał(a):

Znajdujesz element o wartości maksymalnej MAX oraz minimalnej MIN.
f(i)=MAX+MIN-tab[i].
Sumę liczysz f(i) oraz odejmujesz f(i) wg powyższego algorytmu.

Wracając do Twojego przykładu:
element[]={1,10,100};

MAX = 100
MIN = 1

element[0] = 100 + 1 - 1 = 100
element[1] = 101 - 10 = 91
element[2] = 101 - 100 = 1

po normalizacji wg sumy (192):

element[0] = 100/192 = 52% szans na wylosowanie
element[1] = 91/192 = 47% szans
element[2] = 1/192 = 1% szans

Pamiętając że "im wartość mniejsza tym osobnik jest bardziej przystosowany":

Osobnik nr 0 powinien mieć 10 razy większą szansę na wylosowanie (jest 10 razy lepszy) niż nr 1.
Czyli z grubsza licząc rozkład powinien być mniej więcej taki:

element[0] = 90 = 90% szans
element[1] = 9 = 9%
element[2] = 1 = 1%

A nie jest...

Moja propozycja do normalizacji poniżej.

Normalizacja nr 1:

f(i) = 1 / (element[i] + suma(element[k], k = 0..i-1))

Przy normalizacji:

1 / (1) = 1
1 / (1 + 10) = 0,09
1 / (11 + 100) = 0,009

Suma = 1,099

Po wykonaniu drugiej normalizacji:
g(i) = element[i] / suma

element[0] = 0,9 = 90%
element[1] = 0,081 = 8%
element[2] = 0,0082 = 1%

To jest rozkład niedokładnie taki jak oczekiwany, ale bardziej zbliżony.

1

@vpiotr, zamiast dwóch kroków normalizacji wystarczy wziąć moją addytywną normalizację:
f(i)=MAX+MIN-tab[i]
i przerobić ją na multiplikatywną:
f(i)=exp(ln(MAX)+ln(MIN)-ln(tab[i]))
co jest w zasadzie tym samym co:
f(i)=MAX*MIN/tab[i]
czyli:
1 => 100
10 => 10
100 => 1

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