source: liacs/ccs/op4/merit.pl@ 4

Last change on this file since 4 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

  • Property svn:executable set to *
File size: 11.5 KB
Line 
1#!/usr/bin/env perl
2
3use strict;
4
5our $debug = 0;
6our %taken;
7
8our $length = 0;
9our $round_size = 100;
10our $maxstack = 150;
11our $working_mfactor = 0;
12our $best_mfactor = 0;
13our $best_vector;
14our $refill = 0;
15our $maxrounds = 20;
16our @winners;
17our $winnercompare = 10;
18
19our $total = 0;
20
21sub message {
22 our $debug;
23 my $level = shift;
24 my $message = shift;
25 if ( $level => $debug ) {
26 print "DEBUG [$level]: $message\n";
27 }
28}
29
30sub merit {
31 my $y = shift;
32 our $length;
33 my $e = 0;
34 my $f;
35 my $t;
36
37 foreach my $k (1 .. ($length - 1)) {
38 $t = 0;
39 for my $i (0 .. ($length - 1 - $k)) {
40 $t += $$y[$i] * $$y[$i+$k];
41 }
42 $e += $t ** 2;
43 }
44
45 $f = ($length ** 2) / ( 2 * $e);
46 printer('DEBUG merit', $f, $y) if $debug > 5;
47 return($f);
48}
49
50sub randarray {
51 our $debug;
52 my @output = ();
53 my ($i,$v);
54 message(1,"New randarray of length $length");
55 foreach $i ( 0 .. ($length - 1)) {
56 $v = int(rand() + 0.5);
57 $output[$i] = ( $v ) ? 1 : -1;
58 }
59 return(\@output);
60}
61
62sub flip {
63 my $rref = shift;
64 my $number = shift;
65 my $v = $$rref[$number];
66 $v = ($v == 1) ? -1 : 1;
67 $$rref[$number] = $v;
68}
69
70sub try_merit {
71 our @stack;
72 our %taken;
73 our $best_mfactor;
74 our $best_vector;
75 our $working_mfactor;
76
77 my $try_array = shift;
78 my $new_mfactor;
79 my $result = 0;
80 my $array2string = join('',@{$try_array});
81
82 if ( not exists ($taken{$array2string}) ) {
83 $new_mfactor = merit($try_array);
84 $taken{$array2string} = $new_mfactor;
85
86 if ($new_mfactor > $best_mfactor) {
87 $best_mfactor = $new_mfactor;
88 $best_vector = $try_array;
89 $result = 1;
90 unshift(@stack,$try_array);
91 }
92 }
93 if ( $debug == 5 ) {
94 print "==== " . scalar(@stack) . "====\n";
95 print join("\n",@stack) . "\n";
96 }
97 return($result);
98}
99
100sub combine {
101 our $length;
102 our $debug;
103 message(1,"Working on combine");
104
105 my $result = 0;
106 my $loop;
107 my $input = shift;
108 my $input2 = shift;
109 my @result_l;
110 my @result_r;
111
112
113 my $middle = int($length / 2);
114 @result_l = (@{$input}[0 .. $middle],
115 @{$input2}[ $middle + 1 .. ($length-1) ]);
116 @result_r = (@{$input2}[0 .. $middle],
117 @{$input}[ $middle + 1 .. ($length-1) ]);
118
119 if ($debug > 3) {
120 print "Orig l: ";
121 print @{$input};
122 print "\n";
123 print "Orig 2: ";
124 print @{$input2};
125 print "\n";
126 print "Combine l: ";
127 print @result_l;
128 print "\n";
129 print "Combine r: ";
130 print @result_r;
131 print "\n";
132 }
133 message(1,"DEBUG: Done on combine");
134 return(\@result_l,\@result_r);
135}
136
137sub crossover {
138 my $input = shift;
139 my $rev_array = shift;
140 my $result = 0;
141 my ($try_array_l,$try_array_r) = combine($input,$rev_array);
142
143 if ( try_merit($try_array_l) ) {
144 $result = 1;
145 }
146
147 if ( try_merit($try_array_r) ) {
148 $result = 1;
149 }
150 return($result);
151}
152
153
154sub mutations {
155 our $length;
156
157 my @try_array;
158 my $result = 0;
159 my @test_array = @_;
160
161 message(1,"Working on mutations");
162
163 foreach my $i ( 0 .. ($length - 1) ) {
164 my @try_array = ();
165 @try_array = @test_array;
166 flip(\@try_array, $i);
167
168 if ( try_merit(\@try_array) ) {
169 $result = 1;
170 }
171 }
172 message(1,"Done on mutations");
173 return($result) ;
174}
175
176
177sub crossovers {
178 our $length;
179
180 my @try_array;
181 my $result = 0;
182 my @test_array = @_;
183
184 my $i;
185 my $j;
186
187 message(1,"Working on crossovers");
188 foreach $i ( 0 .. ($length - 1) ) {
189 my @try_array = ();
190 @try_array = @test_array;
191 foreach $j ( $i .. ($length - 1) ) {
192 flip(\@try_array, $j);
193 }
194
195 if ( try_merit(\@try_array) ) {
196 $result = 1;
197 }
198 }
199 message(1,"Done on crossovers");
200 return($result);
201}
202
203
204
205
206sub randmutate {
207 our $length;
208 my $switchtimes = shift;
209 my $switchnumbers = shift;
210 my @test_array = @_;
211 my $result = 0;
212 my @try_array;
213 my $i;
214 my $j;
215 my $n;
216 my @flipped;
217
218 message(1,"Working on randmutate");
219
220 foreach $i ( 0 .. $switchtimes ) {
221 my @try_array = ();
222 @try_array = @test_array;
223 @flipped = ();
224 foreach $j ( 0 .. $switchnumbers ) {
225 $n = int(rand($length - 1));
226 if ( not exists $flipped[$n] ) {
227 flip(\@try_array,$n);
228 $flipped[$n] = 1;
229 }
230 }
231
232 if ( try_merit(\@try_array) ) {
233 $result = 1;
234 }
235 }
236 return($result);
237}
238
239sub printer {
240 my $message = shift;
241 my $mfactor = shift;
242 my $input = shift;
243 return("Message : $message \n" .
244 "Vector : " . join(',',array2string($input) . "\n" .
245 "mfactor : $mfactor \n" .
246 "--\n");
247}
248
249
250
251our @stack = ();
252our $best_mfactor = 0;
253our $best_vector;
254
255sub array2string {
256 my $input = shift;
257 my @result = ();
258 my $n = 1;
259 foreach my $i (1 .. $#$input) {
260 if ($$input[$i] != $$input[$i - 1]) {
261 push(@result,$n);
262 $n = 1;
263 }
264 else {
265 $n++;
266 }
267 }
268 push(@result,$n);
269 return(@result);
270}
271
272sub string2array {
273 my @output = ();
274 my $input = shift;
275 $input = split(//,$input);
276 my $c = 0;
277 my $v = 1;
278
279 my ($n,$i);
280
281 for $n ( 0 .. length($input) - 1) {
282 for $i ( 1 .. @{$input}[$n] ) {
283 $output[$c] = $v;
284 $c++;
285 }
286 $v = ( $v == 1) ? -1 : 1;
287 }
288
289 return(@output);
290}
291
292
293#
294# Vul de stack met een random arrays
295sub init {
296 our $length = shift;
297 our @stack;
298 our $best_mfactor;
299
300 my ($n,$y);
301
302 @stack = ();
303 $best_mfactor = 0;
304
305 foreach $n ( 1 .. 75 ) {
306 $y = randarray();
307 push(@stack,$y);
308 }
309
310}
311
312sub reinit {
313 our $refill;
314 our $winnercompare;
315 our $length;
316 our @winners;
317 our %taken;
318 our @stack;
319 our $best_vector;
320 our $best_mfactor;
321
322 my $maxwinners = 5;
323
324 my ($result_l,$result_r);
325 my ($i,$j);
326 my ($n,$y);
327 my ($r);
328
329 %taken = ();
330 @stack = ();
331
332 $refill++;
333 #push best array on good place
334 $i = merit($best_vector);
335 print printer("Round best vector",$i,$best_vector);
336 my $ws = $#winners - 1;
337 my $done = 0;
338 foreach $n ( 0 .. $ws ) {
339 $j = merit($winners[$n]);
340 if ( $i > $j ) {
341 foreach $r ($ws .. ($n + 1)) {
342 $winners[$r] = $winners[$r-1];
343 }
344 $winners[$n] = $best_vector;
345 $done = 1;
346 last;
347 }
348 }
349 if ( ($done == 0) && ($ws < $maxwinners) ) {
350 push(@winners,$best_vector);
351 }
352 print printer("Current best vector",merit($winners[0]),$winners[0]);
353
354 if ( $refill == $winnercompare ) {
355 push(@stack,@winners);
356 $refill = 0;
357 $r = scalar(@stack) - 1;
358 foreach $i ( 0 .. ($r - 1)) {
359 foreach $j ( ($i) .. $r ) {
360 ($result_l,$result_r) = combine($stack[$i],$stack[$j]);
361 push(@stack,$result_l);
362 push(@stack,$result_r);
363 }
364 }
365 $best_mfactor = merit($winners[0]);
366 }
367 else {
368 foreach $n ( 1 .. 75 ) {
369 $y = randarray();
370 push(@stack,$y);
371 }
372 $best_mfactor = 0;
373 }
374}
375
376sub main {
377 our $working_mfactor;
378 our $round_number;
379 our $maxstack;
380 our $maxrounds;
381
382 my $rounds = 0;
383 my $number = 0;
384 my $improvement = 0;
385 my $result;
386 my $stacksize;
387 my ($i,$j,$r,$y);
388
389 while ( 'true' )
390 {
391 $total++;
392
393 $number = ($improvement) ? 0 : $number + 1;
394 print "Number: $number\n" if $debug;
395
396 $working_mfactor = merit(@stack[$number]);
397 if ( $debug > 1 ) {
398 message(1,
399 printer("Working vector",$working_mfactor,@stack[$number]));
400 }
401
402 message(1,"\n" . $number . " of " . $stacksize );
403 $improvement = 0;
404
405 $result = try_merit(@stack[$number]);
406 if ($result > 0 ) {
407 message(1,
408 printer("better array", $best_mfactor,@stack[$number]));
409 $improvement = 1;
410 }
411
412 my @rev = reverse(@{$stack[$number]});
413 $result = crossover($stack[$number],\@rev);
414 if ($result > 0 ) {
415 message(1,
416 printer("better combine", $best_mfactor,@stack[$number]));
417 $improvement = 1;
418 }
419
420 $result = mutations(@{$stack[$number]});
421 if ($result > 0 ) {
422 message(1,
423 printer("better mutation", $best_mfactor,@stack[$number]));
424 $improvement = 1;
425 }
426
427# Experimental 'crossover make'
428 $result = crossovers(@{$stack[$number]});
429 if ($result > 0 ) {
430 message(1,
431 printer("better crossovers", $best_mfactor,@stack[$number]));
432 $improvement = 1;
433 }
434
435# Not very usefull, not value added
436# $result = randmutate($length, $length / 3,@{$stack[0]});
437# if ($result > 0 ) {
438# printer("better randmutate", $best_mfactor,@stack[0]);
439# next;
440# }
441
442 if ( $improvement ) {
443 print "Stack size: " . scalar(@stack) . "\n";
444 print "best max mfactor " . $best_mfactor . "\n";
445 print "total done " . $total . "\n";
446 print "round " . $rounds;
447 print "\n---\n";
448 }
449
450 if ( ($total % $round_size) == 0 ) {
451 print "===============================\n";
452 print "=== Completed Round $rounds ===\n";
453 print "===============================\n";
454 $rounds++;
455 reinit();
456 if ( $rounds == $maxrounds ) {
457 last;
458 }
459 $r = <> if $debug > 3;
460 $improvement = 1;
461 print "===============================\n";
462 print "=== New Round $rounds ===\n";
463 print "===============================\n";
464 next;
465 }
466
467 $stacksize = scalar(@stack);
468 if ( $stacksize > $maxstack ) {
469 while ( scalar(@stack) >= 5 ) {
470 pop(@stack);
471 }
472 }
473 message(1,"$number of " . scalar(@stack) . "\n");;
474 $stacksize = scalar(@stack);
475 if ( (($number +2) > $stacksize) ) {
476 message(1,"Start EVOLVING");
477 $number = 0;
478 while ( scalar(@stack) > 5 ) {
479 pop(@stack);
480 }
481
482 foreach ( 5 .. 9 ) {
483 $y = randarray();
484 push(@stack,$y);
485 }
486
487 foreach $i ( 0 .. 4) {
488 foreach $j ( 5 .. 9 ) {
489 my ($result_l,$result_r) = combine($stack[$i],$stack[$j]);
490 push(@stack,$result_l);
491 push(@stack,$result_r);
492 }
493 }
494 message(1,"Done EVOLVING");
495 }
496
497 #pause during debugging
498 $r = <> if $debug > 4;
499 }
500}
501
502$debug = 0;
503$round_size = 100;
504$maxstack = 150;
505$maxrounds = 20;
506$winnercompare = 5;
507init($ARGV[0]);
508main();
509
510print "\n\n\n";
511
512print "===============================\n";
513print "=== Results ===\n";
514print "===============================\n";
515
516$best_vector = $winners[0];
517$best_mfactor = merit($best_vector);
518print printer("Final", $best_mfactor,$best_vector);
519print "Total parents : $total\n";
520print "Total rounds : $maxrounds\n";
521print "Round parents : $round_size\n";
522print "Winner compare: $winnercompare\n";
523print "Max stack : $winnercompare\n";
524print "Vector size : $length\n";
Note: See TracBrowser for help on using the repository browser.