Skip to content

Instantly share code, notes, and snippets.

@vitprado
Forked from nitrix/gahello.php
Last active July 15, 2022 19:53
Show Gist options
  • Save vitprado/41f2257314c2480f4a9f956607e0707b to your computer and use it in GitHub Desktop.
Save vitprado/41f2257314c2480f4a9f956607e0707b to your computer and use it in GitHub Desktop.
Genetic Algorithms in PHP
<?php
$POPULATION = array(); //population of individuals
$GEN_COUNT = 1;
$TEST_COUNT = 0;
$GENE_OPTIONS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !@#$%&*1234567890";
if( isset($_GET['goal']) ){
$GOAL = $_GET['goal'];
} else {
$GOAL = "Hello World!";
}
$DNA_SIZE = strlen($GOAL);
if( isset($_GET['population_size'])){
$POPULATION_SIZE = (int)$_GET['population_size'];
} else {
$POPULATION_SIZE = 100;
}
genInitPopulation();
while (true) {
naturalSelection();
recreatePopulation();
}
//========================== FUNCTIONS ============================
function mutate($s) {
global $DNA_SIZE;
$sample = randomIndividual();
for ($i=0; $i<$DNA_SIZE; $i++) {
if (rand(0,100) == 100) {
$s[$i] = $sample[$i];
}
}
return $s;
}
function reproduction($ia, $ib)
{
global $DNA_SIZE;
$crosspoint = rand(0, $DNA_SIZE-1);
$ia_before_cp = substr($ia, 0, $crosspoint);
//$ia_after_cp = substr($ia[0], $crosspoint);
//$ib_before_cp = substr($ib[0], 0, $crosspoint);
$ib_after_cp = substr($ib, $crosspoint);
$child = $ia_before_cp.$ib_after_cp;
$child = mutate($child);
return array($child, fitness($child));
}
function recreatePopulation()
{
global $POPULATION, $POPULATION_SIZE, $GEN_COUNT;
//echo '* Recreating population by reproducing randomly...'."\n";
$GEN_COUNT++;
$c = count($POPULATION);
for ($i=$c; $i<$POPULATION_SIZE; $i++) {
$a = rand(0, $c-1);
$b = rand(0, $c-1);
array_push($POPULATION, reproduction($POPULATION[$a][0], $POPULATION[$b][0]));
}
}
function naturalSelection()
{
global $POPULATION, $POPULATION_SIZE, $GEN_COUNT;
//echo '* Natural selection...'."\n";
usort($POPULATION, "cmp");
array_splice($POPULATION, ceil($POPULATION_SIZE/2));
echo '<p>Best fit gen '.$GEN_COUNT.': '.$POPULATION[0][0].' ('.$POPULATION[0][1].')'."</p>";
}
function cmp($a, $b)
{
if ($a[1] == $b[1]) return 0;
return ($a[1] > $b[1]) ? -1 : 1;
}
function genInitPopulation()
{
global $POPULATION, $POPULATION_SIZE;
//echo '* Generating inital population...'."\n";
for($i=0; $i<$POPULATION_SIZE; $i++) {
$individual = randomIndividual();
array_push($POPULATION, array($individual,fitness($individual)));
}
}
function randomIndividual()
{
global $DNA_SIZE, $GENE_OPTIONS;
$individual = '';
for($i=0; $i<$DNA_SIZE; $i++) {
$individual .= str_shuffle($GENE_OPTIONS)[0];
}
return $individual;
}
function fitness($individual)
{
global $GEN_COUNT, $POPULATION_SIZE, $TEST_COUNT, $GOAL, $DNA_SIZE, $GENE_OPTIONS;
$TEST_COUNT++;
$delta = 0;
for($i=0; $i<strlen($individual); $i++) {
$delta -= abs(ord($GOAL[$i]) - ord($individual[$i]));
}
if ($delta == 0) {
echo "<p>".'Solution found in '.$GEN_COUNT.' generation(s) of '.$POPULATION_SIZE.' individual(s)!'."</p>";
echo '<h1>'.$individual."</h1>";
echo 'There was '.$TEST_COUNT.' tests performed'."\n";
$gene_qty = strlen($GENE_OPTIONS);
$combinations = number_format(pow($gene_qty, $DNA_SIZE),0,',','.');
echo "Out of {$gene_qty}^{$DNA_SIZE} possible combinations ({$combinations})";
exit();
}
return $delta;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment