A "Hello World!" Genetic Algorithm Example in PHP
This is a hello world example genetic algorithm example written in php. You can use the same algorithm to build useful applications.
The output is something like this:
hello wojed - 0.81818181818182
stay still
mutated unexpectedly!
hello sorhd - 0.81818181818182
stay still
mutated unexpectedly!
hella woryd - 0.81818181818182
stay still
mutated unexpectedly!
hello worpe - 0.81818181818182
stay still
mutated unexpectedly!
hello porbd - 0.81818181818182
stay still
mutated unexpectedly!
hella worfd - 0.81818181818182
stay still
mutated unexpectedly!
hello world - 1
mutated unexpectedly!
hello woead - 0.81818181818182
crossed nothing!
mutated unexpectedly!
mutation
hellxrworzd - 0.72727272727273
hello world found after 1900 try
Here is the class:
class Gac{ const POPULATION_SIZE = 20; const MUTATION_RATE = 10; const MUTATION_SIZE = 100; const SURVIVORS = 10; const SUCCESS_RATE = 1; const LETTERS = "abcdefghijklmnopqrstuvwxyz "; const OFFSPRING = 2; public function Gac($text) { $this->text = $text; $this->population = 0; $this->max_rate = 0; $this->avarage_suc_rate = 0; $this->passed = FALSE; $this->generations = 0; } private function check_success($data) { $rate = 0; for($i=0;$i<$this->lenght;$i++) { if($original_letter == $text_letter) { $rate++; } } $rate = $rate/$this->lenght; return $rate; } private function first_population($gene_code) { for($i=0;$i<self::POPULATION_SIZE;$i++) { $this->population++; $mutation = TRUE; //this is the first population, so mutate everything $new_ind = $this->generate($gene_code,$mutation); $words[$i]["word"] = $new_ind["word"]; $words[$i]["rate"] = $new_ind["rate"]; $words[$i]["gene_code"] = $new_ind["gene_code"]; echo $new_ind["word"] . " - " . $new_ind["rate"] ."<br>\n"; } echo "end of first generation <br>\n"; echo "----------------------------<br>\n"; return $words; } private function kill($genes) { { for($i=0;$i<$diff;$i++) { } echo "killed $diff individuals<br>\n"; } return $genes; } private function populate($genes) { $this->generations++; echo "------------ START OF " . $this->generations . " th GENERATION ----------------<br>\n"; //cross everything for($j=0;$j<self::OFFSPRING;$j++) { for($i=0;$i<count($genes);$i++) { $this->population++; $best = FALSE; if($genes[$i]["rate"]>=$this->max_rate) { $new_gene = $genes[$i]["gene_code"]; $best = TRUE; echo "stay still<br>"; } else { if($genes[$i]["gene_code"]!==$genes[$i+1]["gene_code"] && $genes[$i+1]["gene_code"]) { $new_gene = $this->cross($genes[$i]["gene_code"],$genes[$i+1]["gene_code"]); } else if($genes[$i]["gene_code"]!==$genes[$i+2]["gene_code"] && $genes[$i+2]["gene_code"]) { $new_gene = $this->cross($genes[$i]["gene_code"],$genes[$i+2]["gene_code"]); } else { $new_gene = $genes[$i]["gene_code"]; echo "crossed nothing!<br>\n"; } } if($new_gene==$genes[$i]["gene_code"] && $i!==0) { $new_gene = $this->mutate($new_gene); echo "<span style='color:red'>mutated unexpectedly!</span><br>\n"; } $mutation = FALSE; if($this->population % self::MUTATION_SIZE == 0) { //mutate the new created gene if the mutation size reached echo "mutation<br>\n"; $mutation = TRUE; } $new_ind = $this->generate($new_gene,$mutation); $new_genes[$i]["word"] = $new_ind["word"]; $new_genes[$i]["rate"] = $new_ind["rate"]; $new_genes[$i]["gene_code"] = $new_ind["gene_code"]; { $this->max_rate = $new_ind["rate"]; $this->best[] = $new_ind; } echo $new_ind["word"] . " - " . $new_ind["rate"] ."<br>\n"; } } return $new_genes; } private function cross($gene1,$gene2) { for($i=0;$i<$this->lenght;$i++) { if($rand) { $new_gene[$i] = $gene1[$i]; } else { $new_gene[$i] = $gene2[$i]; } } if($new_gene !== $gene1 && $new_gene !== $gene2) { echo "<span style='color:green'>cross successfull </span><br>"; } return $new_gene; } public function execute() { //the first gene code $gene_code = $this->generate_gene_code(); $first_population = $this->first_population($gene_code); $result = $this->evolution($first_population); return $result; } private function evolution($genes_data) { //return $genes_data; if($genes_data[0]["rate"]>=self::SUCCESS_RATE) { echo $genes_data[0]["word"]. " found after ". $this->population . " try"; return $genes_data; } else { { $this->best = $this->kill($this->best); $genes = $this->best; $this->passed = TRUE; } else { $genes = $genes_data; } return $this->evolution($this->populate($genes)); } } private function generate_gene_code() { for($i=0;$i<$this->lenght;$i++) { } return $code; } private function generate($gene_code,$mutation) { //generates new individuals according to genetic code if($mutation) { $gene_code = $this->mutate($gene_code); } $new_word = ""; for($i=0;$i<$this->lenght;$i++) { $new_word .= $letter; } $new_ind["gene_code"] = $gene_code; $new_ind["word"] = $new_word; $new_ind["rate"] = $this->check_success($new_word); return $new_ind; } private function mutate($gene_code) { //mutate original data and returns it for($i=0;$i<$mutate_letter_num;$i++) { $mutate_letters[] = $which; } foreach($mutate_letters as $letter_num) { } return $gene_code; } }
and here is the usage:
function cmp($a, $b) { if ($a["rate"] == $b["rate"]) { return 0; } return ($a["rate"] > $b["rate"]) ? -1 : 1; } include("gac.php"); $text = "hello world"; $my_ga = new Gac($text); $first_gene_code = $my_ga->execute();
