Jeżeli chcesz komentować kliknij na tytuł artykułu, wyświetli się tylko ten artykuł z możliwością komentowania.

wtorek, 3 listopada 2020

Prognozy przypomnienie i "paskuda" czyli prognozy nieco inaczej...

 Cykliczność występowania liczb w kolejnych losowaniach jest podstawą działania predykcji w module "Prognozy" programu "LottoCAD". Do obejrzenia na YouTube...

Prognozy cz.1 na YouTube


Prognozy cz.2 na YouTube


Prognozy cz.3 na YouTube



Ale w module "Prognozy" okresy cykli są o stałej szerokości a sposób wybierania polega na podziale częstosci w zadany stosunek procentowy liczb pobieranych z histogramów czestosci (czyli podział na liczby "zimne" - rzadziej wystepujace i liczby "gorące" czesciej wystepujace naprzemian w kolejnych okresach o stałej szerokości (ilości losowań).

Wyniki gry z zastosowaniem "prognoz" są zachęcajace i okresowo mozna liczyc na dobre prognozowane wyniki. Dlatego spróbowałem napisać skrypt który szuka podobnych zaleznosci ale nieco inaczej.
    // wirtualny układ matrycy parametrów (wiersze kolumny):
    // [4, 6 ,8]
    // [1, 1 ,1]
    // [0, 1 ,2]
    // Przykład parametrów w kodzie PHP odpowiada powyższej matrycy:
    $back_range = array(4,6,8); // przedziały wstecz (w trzech cyklach po 4,6,8 = 18 losowań)
	$back_level = array(1,1,1); // poziom trafień w histogramie z każdego przedziału
	$back_mode  = array(0,1,2); // kryteria -2:mniejszy, -1:mniejszy lub równy, 0:równy, 1:większy lub równy, 2:wiekszy
  • Okresy i zawartość okresów zadajemy parametrami. Zawartymi w tablicy prostokatnej (matrycy) np: jak powyżej
  • Parametry to matryca o ilosci wierszy = 3 elementy, natomiast kolumny to parametry dla poszczególnych okresów analizy
  • Kolejne okresy są badane a liczby spełniające kryteria są wybierane a ich wspólne elementy przechodzą selekcję (są wybierane jako prognoza, ponieważ spełniają kryteria)
  • Ponieważ cięzko jest z góry okreslić zestaw parametrów dlatego stworzyłem drugi skrypt "symulator" który losowo wybiera zestaw parametrów, szereguje je w tablicy wg skutecznosci trafień (ranking=0 jezeli żadna liczba nie trafiła lub ranking=1 /100%/ jeżeli wszystkie liczby trafiły w następnym losowaniu) od danego offsetu (przesuniecia od odtatniego losowania). Ostatnie losowanie ma offset= 0 /zero/.
Skrypty mozna pobrać z linku : Tu pobierzesz skrypty spakowane do archiwum zip Przykład jak skrypt wybiera liczby znajdziesz w komentarzu w skrypcie "paskuda-symulator" :

Skrypt paskuda

<php
error_reporting(5);
require_once("include/class_Utils.php");
/*

            Skrypt wybiera liczby które w zadanych przedziałach spełniają kryteria
            podane w ustawieniach zmiennych, dla offsetów większych niż jeden
            skrypt podaje trafienia wybranych liczb.
            Należy tak dobrać kryteria aby uzyskać najwięcej trafień.
            Ilść zakresów i kryterium jest dowolna ale ilść kryterium
            powinna być równa ilości zakresów. Należy o tym pamiętać ( float $arg );

Kryteria oznaczaj1 :

$back_range = array(4,6,8); // przedziały wstecz (pierwszy ostatnie losowanie)
$back_level = array(1,1,1); // poziom trafień w przedziałach
$back_mode  = array(0,1,2); // -2:mniejszy, -1:mniejszy lub równy, 0:równy, 1:większy lub równy, 2:wiekszy

wybierz liczby które w 4 ostatnich losowaniach trafione były dokładnie jeden raz
        a w następnych 6 losowaniach trafione były więcej niż 1 raz

*/

//-------------------------------------- ustawienie zmiennych---------------------------------------

$offsetstart=0;
$offsetstop=200;
//[ 14,  7,  ]
//[  1,  3,  ]
//[  1,  1,  ]
$back_range = array(14,7); // przedziały wstecz (pierwszy element od ostatniego losowania)
$back_level = array(1,3); // poziom trafień w przedziałach
$back_mode  = array(1,1); // liczba oznacza -2:mniejszy, -1:mniejszy lub równy, 0:równy, 1:większy lub równy, 2:wiekszy

// -------------------------------------------------------------------------------------------------

    $back_array=array($back_range,$back_level,$back_mode);
    $offset = 0; // ostatnie losowanie w bazie
    
    $cutting = $offsetstop+array_sum($back_range)+100;
    $drawtable= delphi_get_draw_arr();
    Utils::draw_to_set_array($drawtable);
    $drawtable = array_reverse($drawtable);
    $drawtable = array_splice($drawtable,0,$cutting);
    $out=array();    
         for ($offset=$offsetstart;$offset<=$offsetstop;$offset++) {   // dla każdego offsetu
        //echo "offset $offset\n";

            $rank=get_paskuda($drawtable,$offset,$back_array);            // wybiera paskudę

            if ($offset>0) {                                              // jeżeli offset>0 sprawdza trafienia tej paskudy
                $lastdraw=$offset-1;
                $xhit=array_intersect ( $rank,$drawtable[$lastdraw]);
                $countXHit = count($xhit);
                $rankcount = count($rank);
                //echo sprintf("cnt.rank : %3d, cnt.hit: %3d\n",$rankcount,$countXHit);
                if ($countXHit>0) {
                    $ranking = $countXHit/$rankcount;
                    $out[]=array("offset"=>$offset, "rank"=>$ranking,$back_array,"psk"=>$rank,"hit"=>$xhit);
                } else
                continue;
            }

        } // for   
        foreach ($out as $arr) {
            echo sprintf ("offset: %3d ranking: %1.2f\n%s%s",$arr['offset'],$arr['rank'],array2line("paskuda:",$arr['psk']),array2line("    hit:",$arr['hit']));
            echo params2matrix($arr[0]);
        }

//    for ($offset=$offsetstart;$offset<=$offsetstop;$offset++) {   // dla każdego offsetu
//        $rank=get_paskuda($drawtable,$offset,$back_array);            // wybiera paskudę
//        print array2line("paskuda : ",$rank);
//        if ($offset>0) {                                              // jeżeli offset>0 sprawdza trafienia tej paskudy
//            $lastdraw=$offset-1;
//            $xhit=array_intersect ( $rank,$drawtable[$lastdraw]);
//            echo array2line("trafila : ",$xhit); // wypisuje trafienia
//        }
//    print " ----------- offset $offset ------\n";
//    }


function array2line($title,$arr) {
$s="";
foreach($arr as $item)  $s.=sprintf("%2d ",$item);
$s=trim($s);
return sprintf("%s (%3d): %s\n",$title, count($arr),$s);
}

function params2matrix($arr) {
  $s="";
  foreach($arr as $line) {
     $s.="[ ";
     foreach($line as $par) {
           $s.=sprintf("%2d, ",$par);
     }
     $s.=" ]\n";
  }
return $s;
}

function get_paskuda($draw,$offset,$back_array) {       // procedura paskuda                                     // ostatnie losowanie danego offsetu
$zx=array();
$lastdraw=$offset;                                           // delkaracja tablicy zx
foreach($back_array[0] as $brkey=>$br) {                // dla kazdej tróki parametru $back_range
$blevel=$back_array[1][$brkey];
$bmode=$back_array[2][$brkey];


$x=array();
$z=array();                                              // tablice pomocnicze
// oblicza kolejne grupy wg kryterii
for ($i=0;$i<$br ;$i++) {                                // robi harmonogram liczb w zakresach z parametrami
    foreach($draw[$lastdraw] as $num)
        if (isset($z[$num]))
          $z[$num]++;
        else
          $z[$num]=1;
        $lastdraw++; // zwiększ licznik o jeden
   };


foreach($z as $nkey=>$num) {
       if ($bmode==-2) {
        //echo $num." < ".$blevel."\n";                             // dodaje liczby do tablicy $x jeżeli :
       if ($num<$blevel) $x[]=$nkey;                   // jeżeli mode==-2 (trafienia mniejsze niż $blevel)
        }
   elseif ($bmode==-1) {                               
        if ($num<=$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia mniejsze
        }
   elseif ($bmode==0) {                                
        if ($num==$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia równe
        }
   elseif ($bmode==1) {
        //echo $num." >= ".$blevel."\n";
        if ($num>=$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia większe    
        }
   elseif ($bmode==2) {
        if ($num>$blevel) $x[]=$nkey;                  // jak wyżej ale trafienia większe lub równe
        };
   
}

$zx[$brkey]=$x;  // tablicę $x ładuje do odpowiedniej tablicy zakresu $zx
};

$out=$zx[0]; // bierze tablicę pierwszego zakresu 

foreach($zx as $key=>$arr)
     if ($key>0) $out=array_intersect ( $out, $arr); // i wybiera wspólne liczby z wszystkich zakresów
return $out; // zwraca te liczby jako paskudę.
}

Skrypt paskuda, symulator

<php
error_reporting(5);
require_once("include/class_Utils.php");
/*
Znaleziona paskuda z parametrami jak powyżej. Prognoza znalazła 
18 liczb z czego w następnym losowaniu zostało trafione 7 liczb
co stanowi skuteczność 18%. Po znalezieniu tych parametrów wpisujemy
je do skryptu paskuda i robimy analizę dla np 100 offsetów. Obserwując 
wyniki patrzymy na obliczona skuteczność (ranking) stwierdzany jak 
często uzyskujemy dobry wynik.
Parametry kolejnych okresów losowań są w kolumnach matrycy:

offset:  16 ranking: 0.39 paskuda: paskuda: ( 18): 43 34 42 22 46 32 18 58 53 75  4 13 11  9 16 63 35 40 hit: hit: (  7): 34 58 53 75 13 16 35
[ 14,  7,  ]
[  1,  3,  ]
[  1,  1,  ]

Jak to jest budowane? Skrypt pobiera pierwszą kolumnę (pack=0) i buduje 
w okresie back=14 losowań histogram częstości wystąpień liczb. Dla mode=1 i level=1 Wybiera
z histogramu częstości te liczby które wystąpiły w tych 14 losowaniach (back=14) 
wiecej lub równo (mode=1) jeden raz (level=1). Więc są to wszystkie liczby z tego zakresu.
W histogramie widać częstość a tablica jest posortowana wg częstości właśnie. Przykład:
liczba 65 w 14 losowaniach wystąpiła 7 razy, liczba 60 pieć razy a liczba 77 trzy razy. 
########################## back=14 level=1 mode=1
---  pack : 0 ---
--- histo : 7  6  6  6  6  6  6  6  6  6  5  5  5  5  5  5  5  5  5  5  5  5  4  4  4  4  4  4  4  4  4  4  4  4  4  4  4  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  3  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  1  1  1  1  1  1
--- liczby:65 45 16 35 30 70 11 20 27 79 60  2 17 56 41  6 42 40 69 51 49 78 75 73 55  5 12 24  1 26  7 64 37 38 39 48 80 33 72 77 21 57  9 15 25 50 61 47 10 14 29 53 59 58 13 44 68  8 31 52 32 28 46 18 62 19 74  4 54 23 36 76 71 34 43 63 66 22 67

To samo robi z paczką drugą (druga kolumna parametrów) back=7 level=3 mode=1 
Jak widać ma za zadanie z paczki następnych back=7 losowań, zrobic histogram
częstości i wybrać z niego liczby które wystąpiły (więcej lub równo (mode=1) 
3 krotnie (level=3)). Poniżej to liczby z linii (---output)

--- output :65 45 16 35 30 70 11 20 27 79 60  2 17 56 41  6 42 40 69 51 49 78 75 73 55  5 12 24  1 26  7 64 37 38 39 48 80 33 72 77 21 57  9 15 25 50 61 47 10 14 29 53 59 58 13 44 68  8 31 52 32 28 46 18 62 19 74  4 54 23 36 76 71 34 43 63 66 22 67
--- select :43 34 42 22 46 32 18 58 53 75  4 13 11  9 16 63 35 40
--- output :43 34 42 22 46 32 18 58 53 75  4 13 11  9 16 63 35 40

teraz paczkę z pierwszej kolumny (---output) porównuje z paczką z drugiej kolumny
(---output) robi logiczną operację I (AND) na zbiorach liczb i pobiera jako paskudę 
(---output) zestaw wspólny (liczb występujących w obu zbiorach)


Paczkę tę sprawdza z losowaniem następnym od losowania offset (następne losowanie)
  
*/

//-------------------------------------- ustawienie zmiennych---------------------------------------
    $offsetstart=0;                          // od offsetu zero ostatnie losowanie
    $offsetstop=20;                         // ilosc sprawdzanych offsetow
    $ranges["back_range"]= array(1,20);      // zakres paczek losowan (okresy)
    $ranges["back_level"]=array(0,10);       // ilosc trafien w zakresie od zero do 10
    $ranges["back_mode"]=array(-2,2);        // zakresy od -2 do 2 oznaczaja rodzaj porownania "<, <=, =, >=, >"
    $ranges["count"] = 2;                    // ilosc okresow glownych
    $iterations = 100;                      // ilosc losowan kombinacji parametr??//-------------------------------------------------------------------------------------------------------

    $cutting = ($offsetstop-$offsetstart)+($ranges["count"]*$ranges["back_range"][1])+100;
    $drawtable= delphi_get_draw_arr();
    Utils::draw_to_set_array($drawtable);
    $drawtable = array_reverse($drawtable);
    $drawtable = array_splice($drawtable,0,$cutting);


//    $back_range = array(4,6,8); // przedzia3y wstecz (pierwszy element od ostatniego losowania)
//    $back_level = array(1,1,1); // poziom trafien w przedzia3ach
//    $back_mode  = array(1,1,1); // liczba oznacza -2:mniejszy; -1:mniejszy lub rowny 0:równy 1:wiekszy lub równy 2:wiekszy



// Pętla główna    
// -------------------------------------------------------------------------------------------------

    $items=array();
    For ($i=$ranges["back_range"][0];$i<=$ranges["back_range"][1];$i++) {
        For ($j=$ranges["back_level"][0];$j<=$ranges["back_level"][1];$j++) {
            For ($k=$ranges["back_mode"][0];$k<=$ranges["back_mode"][1];$k++) {
                $items[]=array($i,$j,$k);
            }
        }
    }
    
    
    $cnt = count($items);
    
    $out=array();
    
    do {
    $back_range = array();
    $back_level = array();
    $back_mode  = array();
        for ($i=0;$i<$ranges["count"];$i++) { // dla każdej kolumny (okresu)
            $rnd = rand(0,$cnt);
            //echo "rand: $rnd, i: $i, cnt: $cnt\n";
            $back_range[] = $items[$rnd-1][0];
            $back_level[] = $items[$rnd-1][1];
            $back_mode[]  = $items[$rnd-1][2];
        }
  
    $back_array=array($back_range,$back_level,$back_mode);
    //echo params2line($back_array);
    $offset = 0; // ostatnie losowanie w bazie
     
        for ($offset=$offsetstart;$offset<=$offsetstop;$offset++) {   // dla każdego offsetu
        //echo "offset $offset\n";
            $rank=get_paskuda($drawtable,$offset,$back_array);            // wybiera paskudę

            if ($offset>0) {                                              // jeżeli offset>0 sprawdza trafienia tej paskudy
                $lastdraw=$offset-1;
                $xhit=array_intersect ( $rank,$drawtable[$lastdraw]);
                $countXHit = count($xhit);
                $rankcount = count($rank);
                //echo sprintf("cnt.rank : %3d, cnt.hit: %3d\n",$rankcount,$countXHit);
                if ($countXHit>0) {
                    $ranking = $countXHit/$rankcount;
                    $out[]=array("offset"=>$offset, "rank"=>$ranking,$back_array,"psk"=>$rank,"hit"=>$xhit);
                } else
                continue;
            }

        } // for
    $iterations--; 
    //echo "iteracja $iterations\n";
    } while ($iterations>0);

usort($out,"cmp");

foreach ($out as $arr) {
echo sprintf ("offset: %3d ranking: %1.2f %s %s\n",$arr['offset'],$arr['rank'],array2line("paskuda:",$arr['psk']),array2line("hit:",$arr['hit']));
echo params2matrix($arr[0]);
}
//echo "rank: {$out["ranking"]}";
//echo ", params:"


 
// Koniec programu zasadniczego    
// funkcje pomocnicze

function params2line($arr) {
  $s=sprintf("[%2d %2d %2d], [%2d %2d %2d], [%2d %2d %2d]\n",$arr[0][0],$arr[0][1],$arr[0][2],$arr[1][0],$arr[1][1],$arr[1][2],$arr[2][0],$arr[2][1],$arr[2][2]);
return $s;
}

function params2matrix($arr) {
  $s="";
  foreach($arr as $line) {
     $s.="[ ";
     foreach($line as $par) {
           $s.=sprintf("%2d, ",$par);
     }
     $s.=" ]\n";
  }
return $s;
}


function array2line($title,$arr) {
$s="";
foreach($arr as $item)  $s.=sprintf("%2d ",$item);
$s=trim($s);
return sprintf("%s (%3d): %s",$title, count($arr),$s);
}

function get_paskuda($draw,$offset,$back_array) {       // procedura paskuda                                     // ostatnie losowanie danego offsetu
$zx=array();
$lastdraw=$offset;                                           // delkaracja tablicy zx
foreach($back_array[0] as $brkey=>$br) {                // dla kazdej tróki parametru $back_range
$blevel=$back_array[1][$brkey];
$bmode=$back_array[2][$brkey];
//echo "########################## back=$br level=$blevel mode=$bmode\n";
$x=array();
$z=array();                                              // tablice pomocnicze
// oblicza kolejne grupy wg kryterii
for ($i=0;$i<$br ;$i++) {                                // robi harmonogram liczb w zakresach z parametrami
    foreach($draw[$lastdraw] as $num)   $z[$num]++;
    $lastdraw++; // zwiększ licznik o jeden
   };
    arsort($z);
    //echo "---  pack : $brkey ---\n";
    //echo "--- histo :",Utils::printTicket($z),"\n";
    //echo "--- liczby:",Utils::printTicket(array_keys($z)),"\n";
    
foreach($z as $nkey=>$num) {
       if ($bmode==-2) {                               // dodaje liczby do tablicy $x jeżeli :
       if ($num<$blevel) $x[]=$nkey;                   // jeżeli mode==-2 (trafienia mniejsze niż $blevel)
        }
   elseif ($bmode==-1) {                               
        if ($num<=$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia mniejsze
        }
   elseif ($bmode==0) {                                
        if ($num==$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia równe
        }
   elseif ($bmode==1) {                            
        if ($num>=$blevel) $x[]=$nkey;                 // jak wyżej ale trafienia większe    
        }
   elseif ($bmode==2) {
        if ($num>$blevel) $x[]=$nkey;                  // jak wyżej ale trafienia większe lub równe
        };
}

$zx[$brkey]=$x;  // tablicę $x ładuje do odpowiedniej tablicy zakresu $zx
};


$out=$zx[0]; // bierze tablicę pierwszego zakresu 

//echo "offset: $offset  -------------------\n";
//echo "lastdraw: $lastdraw  ---------------\n";
//echo params2matrix($back_array);
foreach($zx as $key=>$arr) { 
  //  echo "--- output :",Utils::printTicket($out),"\n"; 
    if ($key>0) $out=array_intersect ( $arr,$out); // i wybiera wspólne liczby z wszystkich zakresów
  //  echo "--- select :",Utils::printTicket($arr),"\n";
  //  echo "--- output :",Utils::printTicket($out),"\n";   
    }
return $out; // zwraca te liczby jako paskudę.
}


function cmp($a, $b)
{
    if ($a["rank"] == $b["rank"]) {
        return 0;
    }
    return ($a["rank"] < $b["rank"]) ? 1 : -1;
}