-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgau.php
94 lines (80 loc) · 2.09 KB
/
gau.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php
// GENETIC ALGORITHM UTILLITY
abstract class GAU
{
#public abstract static function fitness(){}
public static function crossover(Genome $mom, Genome $dad)
{
$length = $dad->get_length();
$type = $dad->get_type();
$child1 = new Genome(['length' => $length, 'type' => $type]);
$child2 = new Genome(['length' => $length, 'type' => $type]);
$child1->initialize();
$child2->initialize();
// Crossover Borad
$cb = floor(self::rndNum() * $length);
for($i = 0; $i < $cb; $i++)
{
$child1->chromo[$i] = $mom->chromo[$i];
$child2->chromo[$i] = $dad->chromo[$i];
}
for($i = $cb; $i < $length; $i++)
{
$child1->chromo[$i] = $dad->chromo[$i];
$child2->chromo[$i] = $mom->chromo[$i];
}
return [$child1, $child2];
}
// Roullete Selection
public static function selection($population)
{
$slice = self::rndNum() * $population->totalFitness();
$silce = ceil($slice);
$sum = 0;
for($i = 0; $i < $population->size; $i++)
{
if($sum > $slice)
return $population->members[$i];
$sum += $population->members[$i]->fitness;
}
return $population->members[mt_rand(0, $population->size - 1)];
}
public static function mutation($population, $rate)
{
$length = $population->length;
$rate = $rate / 100;
$members = $population->members;
if($rate == 0)
return;
$number = floor($population->size * $rate);
$indexs = array_rand($members, $number);
if( sizeof($indexs) < 2)
$indexs = [$indexs];
foreach($indexs as $index)
{
for($i = 0; $i < $length; $i++)
{
if(self::rndNum() < $rate)
{
$temp = $members[$index]->chromo[$i];
$nextI = $length - $i - 1;
$members[$index]->chromo[$i] = $members[$index]->chromo[$nextI];
$members[$index]->chromo[$nextI] = $members[$index]->chromo[$i];
}
}
}
}
public static function elitism($newPopulation, $population, $rate)
{
$number = floor($population->size * ( $rate / 100 ));
$bests = $population->best($number);
foreach($bests as $best)
{
$newPopulation->add($best);
}
}
public static function rndNum()
{
return mt_rand() / mt_getrandmax();
}
}