use AI::Genetic::Pro; my @costs = map [split], ; my $NUM_OF_NODES = @costs; my $GROUP_SIZE = $NUM_OF_NODES/2; my @connections = sort {$a <=> $b } map { my $r=$_; map { $costs[$r][$_] } $_+1..$NUM_OF_NODES-1 } 0..$NUM_OF_NODES-1; my $numbetweengroups = $GROUP_SIZE * $GROUP_SIZE; my $numinsidegroups = @connections - $numbetweengroups; my $ideal_score = 0; my $all_conn_sum = 0; for(0..$#connections) { if($_<$numbetweengroups) { $ideal_score += $connections[$_] } $all_conn_sum += $connections[$_]; } #### sub fitness { my ($ga, $chromosome) = @_; my @queue = $ga->as_array($chromosome); my @group1ids = @queue[0..$GROUP_SIZE-1]; my @group2ids = @queue[$GROUP_SIZE..$NUM_OF_NODES-1]; my $current_score = 0; for my $src(@nodes[@group1ids]) { for my $dst(@nodes[@group2ids]) { $current_score += $costs[$src][$dst] } } return $all_conn_sum - $current_score; } #### sub terminate { my ($ga) = @_; my $result = $all_conn_sum - fitness($ga, $ga->getFittest); return $result == $ideal_score ? 1 : 0; } #### my $ga = AI::Genetic::Pro->new( -fitness => \&fitness, # fitness function -terminate => \&terminate, # terminate function -type => 'combination', # type of chromosomes -population => 1000, # population -crossover => 0.9, # probab. of crossover -mutation => 0.01, # probab. of mutation -parents => 2, # number of parents -selection => [ 'Roulette' ], # selection strategy -strategy => [ 'OX' ], # crossover strategy -cache => 0, # cache results -history => 1, # remember best results -preserve => 3, # remember the bests ); #### $ga->init([0..$#costs]); #### $ga->evolve(10); #### print "SCORE: ", $ga->as_value($ga->getFittest), " for set: ", "[".join(", ", $ga->as_array($ga->getFittest))."]", ".\n";

And if someone want's to see history of evolution:

# $ga->chart(-filename => 'evolution.png'); ##
## use AI::Genetic::Pro; my @costs = map [split], ; my $NUM_OF_NODES = @costs; my $GROUP_SIZE = $NUM_OF_NODES/2; my @connections = sort {$a <=> $b } map { my $r=$_; map { $costs[$r][$_] } $_+1..$NUM_OF_NODES-1 } 0..$NUM_OF_NODES-1; my $numbetweengroups = $GROUP_SIZE * $GROUP_SIZE; my $numinsidegroups = @connections - $numbetweengroups; my $ideal_score = 0; my $all_conn_sum = 0; for(0..$#connections) { if($_<$numbetweengroups) { $ideal_score += $connections[$_] } $all_conn_sum += $connections[$_]; } sub fitness { my ($ga, $chromosome) = @_; my @queue = $ga->as_array($chromosome); my @group1ids = @queue[0..$GROUP_SIZE-1]; my @group2ids = @queue[$GROUP_SIZE..$NUM_OF_NODES-1]; my $current_score = 0; for my $src(@nodes[@group1ids]) { for my $dst(@nodes[@group2ids]) { $current_score += $costs[$src][$dst] } } return $all_conn_sum - $current_score; } sub terminate { my ($ga) = @_; my $result = $all_conn_sum - fitness($ga, $ga->getFittest); return $result == $ideal_score ? 1 : 0; } my $ga = AI::Genetic::Pro->new( -fitness => \&fitness, # fitness function -terminate => \&terminate, # terminate function -type => 'combination', # type of chromosomes -population => 1000, # population -crossover => 0.9, # probab. of crossover -mutation => 0.01, # probab. of mutation -parents => 2, # number of parents -selection => [ 'Roulette' ], # selection strategy -strategy => [ 'OX' ], # crossover strategy -cache => 0, # cache results -history => 1, # remember best results -preserve => 3, # remember the bests ); # init population of 32-bit vectors $ga->init([0..$#costs]); # evolve 10 generations $ga->evolve(10); # best score print "SCORE: ", $ga->as_value($ga->getFittest), " for set: ", "[".join(", ", $ga->as_array($ga->getFittest))."]", ".\n"; # save evolution path as a chart # $ga->chart(-filename => 'evolution.png'); __DATA__ - 159 38 172 76 143 155 78 282 58 159 - 7 264 128 105 42 169 124 153 38 7 - 226 142 85 163 120 74 285 172 264 226 - 48 271 15 151 255 116 76 128 142 48 - 189 152 237 183 10 143 105 85 271 189 - 167 193 18 127 155 42 163 15 152 167 - 99 187 59 78 169 120 151 237 193 99 - 51 12 282 124 74 255 183 18 187 51 - 281 58 153 285 116 10 127 59 12 281 - #### #!perl -l use AI::Genetic; my $ga = new AI::Genetic ( -fitness => \&fitnessFunc, -type => 'rangevector', -population => 50, -crossover => 0.9, -mutation => 0.01, -terminate => \&terminateFunc, ); # 3x^2+2x-5 @aPoints = ([-2,3], [-1,-4], [0,-5], [1,0], [2,11], [3,28]); $ga->init([[-10, 31], [1, 3], [-10, 31], [1, 3], [-10, 31], [1, 3], [-10, 31], [1, 3], [-10, 31]]); sub translate { ($p, @aa) = @_; %operators = (1=>'+',2=>'-',3=>'*'); while(@aa) { $operator = shift @aa; $value = shift @aa; $value = '$x' if $value > 10; $p .= $operators{$operator}.'('.$value.')'; } # substitute (12) -> 12 $p=~s/\((\d+|\$x)\)/$1/g; # substitute -(-12) -> +12 $p=~s/-\(-(\d+|\$x)\)/+$1/g; # substitute +(-12) -> -12 $p=~s/\+\((-\d+|-\$x)\)/$1/g; # remove +0 lub -0 $p=~s/(\+|-)0(\+|-)/$2/g; # print $p; $p } $ga->evolve('rouletteTwoPoint', 300); print "Best score = ", $ga->getFittest->score, ", for genes: ", translate(@{$ga->getFittest->genes}), ".\n"; sub fitnessFunc { my $genes = shift; my $equation = translate(@$genes); my $fitness = 0; for(@aPoints) { ($x, $y) = @$_; $fitness -= abs($y - eval $equation); } return $fitness; } sub terminateFunc { my $ga = shift; # terminate if reached result. return 1 if $ga->getFittest->score == @aPoints; return 0; }