Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use GD;
- #use strict;
- use warnings;
- main();
- my $best;
- my $prevbest;
- my $numreps;
- my $generation;
- my $timage;
- my $width;
- my $height;
- my @im;
- my @score;
- my $savedIndex;
- my $population;
- my $polygons;
- my $points;
- my @touched;
- my $firstrun;
- sub main {
- $firstrun = 1;
- get_dimensions();
- initialise();
- generate_genes();
- while(1){
- draw_images();
- score_images();
- $firstrun = 0;
- if($best < $prevbest){
- $prevbest = $best;
- output_best();
- }
- #soft mutations
- $numreps = int(rand(20));
- for(my $m = 0; $m <= $numreps; $m++){
- if(int(rand(100)) < 15){ soft_mutate_x(); }
- if(int(rand(100)) < 15){ soft_mutate_y(); }
- if(int(rand(100)) < 15){ soft_mutate_r(); }
- if(int(rand(100)) < 15){ soft_mutate_g(); }
- if(int(rand(100)) < 15){ soft_mutate_b(); }
- if(int(rand(100)) < 15){ soft_mutate_a(); }
- }
- #hard mutations
- $numreps = int(rand(20));
- for(my $m = 0; $m <= $numreps; $m++){
- if(int(rand(100)) < 5){ hard_mutate_x(); }
- if(int(rand(100)) < 5){ hard_mutate_y(); }
- if(int(rand(100)) < 5){ hard_mutate_r(); }
- if(int(rand(100)) < 5){ hard_mutate_g(); }
- if(int(rand(100)) < 5){ hard_mutate_b(); }
- if(int(rand(100)) < 5){ hard_mutate_a(); }
- }
- $numreps = int(rand($population/2));
- for(my $m = 0; $m <= $numreps; $m++){
- #if(int(rand(100)) < 100){
- crossover();
- #}
- }
- $generation++;
- }
- }
- sub generate_genes {
- for(my $i = 1; $i <= $population; $i++){
- for(my $d = 1; $d <= $polygons; $d++){
- for(my $c = 1; $c <= $points; $c++){
- push(@{"xchrom".$i}, int(rand($width + 1)));
- push(@{"ychrom".$i}, int(rand($height + 1)));
- }
- for(my $c = 1; $c <= 3; $c++){
- push(@{"rchrom".$i}, int(rand(256)));
- push(@{"gchrom".$i}, int(rand(256)));
- push(@{"bchrom".$i}, int(rand(256)));
- }
- push(@{"achrom".$i}, int(rand(128)));
- }
- }
- }
- sub get_dimensions {
- $timage = GD::Image->newFromPng("ml.png");
- ($width, $height) = $timage->getBounds;
- }
- sub initialise {
- $generation = 1;
- $best = 195010 * $width * $height;
- $prevbest = 195010 * $width * $height;
- $population = 5;
- $polygons = 20;
- $points = 4;
- }
- sub draw_images {
- for(my $i = 1; $i <= $population; $i++){
- $im[$i] = new GD::Image($width,$height,1);
- for(my $z = 0; $z <= ($polygons * $points) - $points; $z+=$points){
- my $poly = new GD::Polygon;
- $poly->addPt(${"xchrom".$i}[$z], ${"ychrom".$i}[$z]);
- $poly->addPt(${"xchrom".$i}[$z+1], ${"ychrom".$i}[$z+1]);
- $poly->addPt(${"xchrom".$i}[$z+2], ${"ychrom".$i}[$z+2]);
- $poly->addPt(${"xchrom".$i}[$z+3], ${"ychrom".$i}[$z+3]);
- my $col = $im[$i]->colorAllocateAlpha(${"rchrom".$i}[$z/$points], ${"gchrom".$i}[$z/$points], ${"bchrom".$i}[$z/$points], ${"achrom".$i}[$z/$points]);
- $im[$i]->filledPolygon($poly,$col);
- }
- }
- }
- sub score_images {
- for(my $i = 1; $i <= $population; $i++){
- my $flag = 1;
- for(my $l = 0; $l < @touched; $l++){
- if($i == $touched[$l]) { $flag = 0; }
- }
- if($flag == 0 || $firstrun == 1){
- $score[$i] = 0;
- foreach my $x ( 0 .. $width ) {
- foreach my $y ( 0 .. $height ) {
- my ($index1) = $timage->getPixel($x,$y);
- my ($index2) = $im[$i]->getPixel($x,$y);
- my ($r1,$g1,$b1) = $timage->rgb($index1);
- my ($r2,$g2,$b2) = $im[$i]->rgb($index2);
- $score[$i] += ($r1 - $r2)**2;
- $score[$i] += ($g1 - $g2)**2;
- $score[$i] += ($b1 - $b2)**2;
- }
- }
- if($score[$i] < $best){
- $best = $score[$i];
- $savedIndex = $i;
- }
- }
- }
- @touched = ();
- }
- sub output_best {
- print $generation.",".$score[$savedIndex]."\n";
- open FILE, ">".$generation."\.png" or die $!;
- binmode FILE;
- print FILE $im[$savedIndex]->png;
- close FILE;
- save_genes();
- }
- sub soft_mutate_x {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons * $points));
- ${"xchrom".$randomchrom}[$randlocus] += int(rand($points));
- ${"xchrom".$randomchrom}[$randlocus] = ${"xchrom".$randomchrom}[$randlocus] % ($width + 1);
- }
- sub soft_mutate_y {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons * $points));
- ${"ychrom".$randomchrom}[$randlocus] += int(rand(4));
- ${"ychrom".$randomchrom}[$randlocus] = ${"ychrom".$randomchrom}[$randlocus] % ($height + 1);
- }
- sub soft_mutate_r {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- if(${"rchrom".$randomchrom}[$randlocus] > 3){
- ${"rchrom".$randomchrom}[$randlocus] += int(rand(7)) - 3;
- }
- else
- {
- ${"rchrom".$randomchrom}[$randlocus] += int(rand(4));
- }
- ${"rchrom".$randomchrom}[$randlocus] = ${"rchrom".$randomchrom}[$randlocus] % 256;
- }
- sub soft_mutate_g {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- if(${"gchrom".$randomchrom}[$randlocus] > 3){
- ${"gchrom".$randomchrom}[$randlocus] += int(rand(7)) - 3;
- }
- else
- {
- ${"gchrom".$randomchrom}[$randlocus] += int(rand(4));
- }
- ${"gchrom".$randomchrom}[$randlocus] = ${"gchrom".$randomchrom}[$randlocus] % 256;
- }
- sub soft_mutate_b {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- if(${"bchrom".$randomchrom}[$randlocus] > 3){
- ${"bchrom".$randomchrom}[$randlocus] += int(rand(7)) - 3;
- }
- else
- {
- ${"bchrom".$randomchrom}[$randlocus] += int(rand(4));
- }
- ${"bchrom".$randomchrom}[$randlocus] = ${"bchrom".$randomchrom}[$randlocus] % 256;
- }
- sub soft_mutate_a {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- if(${"achrom".$randomchrom}[$randlocus] > 3){
- ${"achrom".$randomchrom}[$randlocus] += int(rand(7)) - 3;
- }
- else
- {
- ${"achrom".$randomchrom}[$randlocus] += int(rand(4));
- }
- ${"achrom".$randomchrom}[$randlocus] = ${"achrom".$randomchrom}[$randlocus] % 128;
- }
- sub hard_mutate_x {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons*$points));
- ${"xchrom".$randomchrom}[$randlocus] = int(rand($width + 1));
- }
- sub hard_mutate_y {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons*$points));
- ${"ychrom".$randomchrom}[$randlocus] = int(rand($height + 1));
- }
- sub hard_mutate_r {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- ${"rchrom".$randomchrom}[$randlocus] = int(rand(256));
- }
- sub hard_mutate_g {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- ${"gchrom".$randomchrom}[$randlocus] = int(rand(256));
- }
- sub hard_mutate_b {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- ${"bchrom".$randomchrom}[$randlocus] = int(rand(256));
- }
- sub hard_mutate_a {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons));
- ${"achrom".$randomchrom}[$randlocus] = int(rand(128));
- }
- sub crossover {
- my $randomchrom = int(rand($population)) + 1;
- while($randomchrom == $savedIndex){
- $randomchrom = int(rand($population)) + 1;
- }
- push(@touched, $randomchrom);
- my $randlocus = int(rand($polygons * $points));
- for(my $i = 0; $i <= $randlocus; $i++){
- ${"xchrom".$randomchrom}[$i] = ${"xchrom".$savedIndex}[$i];
- ${"ychrom".$randomchrom}[$i] = ${"ychrom".$savedIndex}[$i];
- }
- $randlocus = int(rand($polygons));
- for(my $i = 0; $i <= $randlocus; $i++){
- ${"rchrom".$randomchrom}[$i] = ${"rchrom".$savedIndex}[$i];
- ${"gchrom".$randomchrom}[$i] = ${"gchrom".$savedIndex}[$i];
- ${"bchrom".$randomchrom}[$i] = ${"bchrom".$savedIndex}[$i];
- ${"achrom".$randomchrom}[$i] = ${"achrom".$savedIndex}[$i];
- }
- }
- sub save_genes(){
- system("del genes.txt");
- open FILE, ">genes.txt";
- print FILE "xchrom: ";
- for(my $i = 0; $i < @{"xchrom".$savedIndex}; $i++){
- print FILE ${"xchrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- print FILE "ychrom: ";
- for(my $i = 0; $i < @{"ychrom".$savedIndex}; $i++){
- print FILE ${"ychrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- print FILE "rchrom: ";
- for(my $i = 0; $i < @{"rchrom".$savedIndex}; $i++){
- print FILE ${"rchrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- print FILE "gchrom: ";
- for(my $i = 0; $i < @{"gchrom".$savedIndex}; $i++){
- print FILE ${"gchrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- print FILE "bchrom: ";
- for(my $i = 0; $i < @{"bchrom".$savedIndex}; $i++){
- print FILE ${"bchrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- print FILE "achrom: ";
- for(my $i = 0; $i < @{"achrom".$savedIndex}; $i++){
- print FILE ${"achrom".$savedIndex}[$i].",";
- }
- print FILE "\n";
- close FILE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement