Параллельные циклы заканчиваются самостоятельно? - PullRequest
7 голосов
/ 14 февраля 2020

У меня есть l oop как часть более крупной программы (это открытый исходный код, его можно загрузить и запустить в запятой, конфигурация есть):

 my $promise = start react whenever $channel-one -> @crew {
            Algorithm::Evolutionary::LogTimelineSchema::Evolutionary.log: {
                my %fitness-of;
                Algorithm::Evolutionary::LogTimelineSchema::Frequencies
                        .log( :@crew );
                my @unpacked-pop = generate-by-frequencies( $population-size, @crew );
                my $population = evaluate( population => @unpacked-pop,
                                            :%fitness-of,
                                            evaluator => &leading-ones);
                Algorithm::Evolutionary::LogTimelineSchema::GenerationsStart
                        .log( :population-size(@unpacked-pop.elems),
                              :distinct-elements( %fitness-of.keys.elems) );
                my atomicint $count = 0;
                while ($count⚛++ < $generations) &&
                        (best-fitness($population) < $max-fitness) {
                    LAST {
                        if best-fitness($population) >= $max-fitness {
                            Algorithm::Evolutionary::LogTimelineSchema::SolutionFound
                                    .log(
                                    {
                                        id => $*THREAD.id,
                                        best => best-fitness($population),
                                        found => True,
                                        finishing-at => DateTime.now.Str
                                    }
                                    );

                            say "Solution found" => $evaluations;
                            Algorithm::Evolutionary::LogTimelineSchema::SolutionFound
                                    .log( :$evaluations );
                            $channel-one.close;
                        } else {
                            say "Emitting after $count generations in thread ",
                                    $*THREAD.id, " Best fitness ",best-fitness($population);
                            if  $count < $generations {
                                Algorithm::Evolutionary::LogTimelineSchema::Weird
                                        .log(  id => $*THREAD.id,
                                                best => best-fitness($population),
                                                :$count,
                                                :population-size(@unpacked-pop.elems),
                                                :distinct-elements( %fitness-of.keys.elems)
                                        );
                            } else {
                                Algorithm::Evolutionary::LogTimelineSchema::Events.log(
                                        id => $*THREAD.id,
                                        best => best-fitness($population),
                                        :$count
                                        );
                            }
                            $to-mix.send( frequencies-best($population, 8) );
                        }
                    };
                    $population = generation( :$population, :%fitness-of,
                            evaluator => &leading-ones,
                            :$population-size
                            );
                    $evaluations += $population.elems;
                }
                Algorithm::Evolutionary::LogTimelineSchema::Generations
                        .log( :generations($count),
                              individuals => %fitness-of.keys.elems);
                $evaluations;
            };
        };

Проверьте условия l oop:

                while ($count⚛++ < $generations) &&
                        (best-fitness($population) < $max-fitness) {

$count - это локальная переменная, которая, кроме того, равна atomi c, и превышение этого числа или достижение наилучшей пригодности представляется Единственный выход.

Только это не так. L oop заканчивается сам по себе, без соблюдения каких-либо условий. Я установил два разных события журнала: «Weird» и «EndRun» (которые вы можете видеть выше), «Weird» вызывается, когда l oop заканчивается, не достигнув ни лучшей пригодности, ни количества поколений; это почти всегда называется, как видно из этой визуализации запятой enter image description here с (разреженными) треугольниками вверху, показывающими, когда l oop заканчивается, когда это необходимо, фиолетовые треугольники ниже отмечают " странные "окончания". Печатный журнал также показывает то же самое:


Emitting after 8 generations in thread 10 Best fitness 48
Mixing in 12
Emitting after 5 generations in thread 7 Best fitness 47
Mixing in 12
Emitting after 2 generations in thread 8 Best fitness 48
Mixing in 12
Emitting after 1 generations in thread 10 Best fitness 48
Mixing in 8

Он почти никогда не достигает 16 поколений, что является значением $ поколений. Я использую Raku 2019.11, но такого рода вещи случались и раньше. Я не уверен, что столкнулся с ошибкой, или я просто запускаю какой-то механизм, о котором я действительно не знаю. Есть идеи?

Обновление : Время от времени также происходит сбой ...

/home/jmerelo/.rakudobrew/moar-2020.01/install/bin/rakudo /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6
Use of Nil in numeric context
  in block  at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 68
An operation first awaited:
  in sub MAIN at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 139
  in block <unit> at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 21

Died with the exception:
    A react block:
      in code  at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 55

    Died because of the exception:
        Type check failed in binding to parameter '@chromosome1'; expected Positional but got Any (Any)
          in sub crossover at /home/jmerelo/.rakudobrew/moar-2020.01/install/share/perl6/site/sources/C405508803395DA88D77FC9B113DB20EFC0C1C4C (Algorithm::Evolutionary::Simple) line 96
          in sub produce-offspring at /home/jmerelo/.rakudobrew/moar-2020.01/install/share/perl6/site/sources/C405508803395DA88D77FC9B113DB20EFC0C1C4C (Algorithm::Evolutionary::Simple) line 115
          in sub generation at /home/jmerelo/.rakudobrew/moar-2020.01/install/share/perl6/site/sources/C405508803395DA88D77FC9B113DB20EFC0C1C4C (Algorithm::Evolutionary::Simple) line 149
          in block  at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 107
          in block  at /home/jmerelo/.rakudobrew/moar-2020.01/install/share/perl6/site/sources/0F5CDA46B783643CA4E3D746E2329D0C256CB46B (Log::Timeline) line 95
          in method log at /home/jmerelo/.rakudobrew/moar-2020.01/install/share/perl6/site/sources/0F5CDA46B783643CA4E3D746E2329D0C256CB46B (Log::Timeline) line 90
          in block  at /home/jmerelo/Papers/2020/2020-evostar-concurrent-eas/code/concurrent-ea-leading-ones.p6 line 56

Обновление 2 Попытка сыграть в гольф как запрошенный, я изменил while на for l oop, и он работает как шарм. Так что, по крайней мере, это работает для меня, но все же я хотел бы знать, что происходит с туннелированием while

...