Stratégie martingale gagnante ??

Résolu/Fermé
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 - 20 juin 2023 à 15:15
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 21 juin 2023 à 14:36

Bonjour à tous,

J'ai développer un programme en langage C et je ne comprends pas que la stratégie de martigale fonctionne... (on ma toujours dit que sur des grands nombres cette stratégie était perdante)

J'ai vérifié mon code à plusieurs reprises et je n'ai trouvé aucune erreur évidente. J'ai également essayé de rechercher des solutions en ligne, fais vérifié le code par chatGPT et il me dit aussi que la strat est perdante...

Si quelqu'un a déjà rencontré une situation similaire ou a des connaissances, je vous serais reconnaissant de bien vouloir partager vos expérience. Toute aide ou suggestion serait grandement appréciée.

Merci d'avance pour votre attention et votre aide.

lien vers le projet git: https://github.com/g3noce/martingale

Cordialement, Genoce

A voir également:

4 réponses

blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024 3 317
20 juin 2023 à 15:20

Salut,

il joue à quoi ton programme ?

Parce qu'un programme de ce type doit être prévu pour un type de jeu et ne peut pas être générique.

Une différence dans la gestion des probabilités doit être gérée entre les différents jeux de casino : roulette, craps, black-jack...


0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1
20 juin 2023 à 15:27

Ce que j'ai essayé de faire, c'est de créer un script simulant une roulette où je parie 1 avec une probabilité de victoire de 45%. À chaque fois que je perds, je double ma mise initiale. J'ai également mis en place un système de bankroll avec 10 buy-ins au cas où, pour le début de la séquence des paries.

N'hésite pas à réenvoyer un message si j'ai pas été très claire.

0
blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024 3 317
20 juin 2023 à 16:11

Pas tout compris, tu tiens d'où ton 45 % ?

A la roulette, la seule probabilité qui soit supérieure à 45 % est celle où on mise une double douzaine ou une double colonne. Elle est dans ce cas de 64 % mais elle impose de jouer 24 numéros sur 37 !

Quant à doubler en cas de perte, c'est un vieux truc connu, qui n'est efficace que si tu as une somme infinie à ta disposition.

Sinon, n'oublie pas que la génération d'un nombre aléatoire via informatique n'est pas si aléatoire, elle suit la plupart du temps un algorithme (donc un processus déterministe).


0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1
Modifié le 20 juin 2023 à 16:23

Je coirs que tu n'as pas regarder le script, je n'ai pas fais le jeu de roulette de casino que tu connais, j'ai simplement fais un simulation avec seulement 49.5% de victoire pour le joueurs.

Et justement je veux tester le "vieux truc connu" avec une simulation pour mieux comprendre comment le "vieux truc connu" fonction.

Et pour la génération des nombres j'ai fais des test pour connaître l'aléa et ma simulation a bien un aléa d'environ 49.5/50.5 (et non pas 45% comme je l'avait précisé au début).

0
blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024 3 317 > CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023
20 juin 2023 à 16:47

Je n'ai pas regardé le script, il ne m'intéresse pas.

Seules tes hypothèses sont à prendre en compte dans le cadre des calculs des probabilités.

Donc, partir avec un postulat de 49,5 % de victoire, c'est une tricherie. Tu peux donc imaginer gagner mais pas à tous les coups. Et sur le long terme, ce n'est pas évident si tu n'as pas un portefeuille infini.

Et justement je veux tester le "vieux truc connu" avec une simulation pour mieux comprendre comment le "vieux truc connu" fonction.

Il fonctionne de la manière la plus simple : tu doubles ce que tu as perdu en espérant le regagner+ ta mise en cours... Pas besoin d'informatique pour ça !

0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1 > blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024
20 juin 2023 à 16:57

Je ne vois pas en quoi c'est une "triche" ?

Que ton portefeuille soit infini ou non, si tu ne mets aucune stratégie en place et que tu n'as qu'un taux de victoire de 49,5 %, tu finiras par perdre de l'argent. Cependant, sans vouloir t'offenser, je crois que tu n'as pas les connaissances requises pour répondre à ce problème...

0
blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024 3 317 > CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023
Modifié le 20 juin 2023 à 17:24

Je ne vois pas en quoi c'est une "triche" ?
C'est un postulat de départ arrangé. Aucun jeu de hasard de casino ne t'offre ce genre de probabilité (à part le pile ou face, qui est lui, à 50 %, mais non proposé dans les casinos...).

 

Explique-moi quelle stratégie tu peux mettre en place pour "vaincre" le hasard de tirages qui sont selon toute vraisemblance équiprobables et indépendants ?

 

Cependant, sans vouloir t'offenser, je crois que tu n'as pas les connaissances requises pour répondre à ce problème...
Le problème d'internet, c'est qu'on ne sait jamais à qui on a affaire... Peut-être que je me débrouille mieux en probabilités que tu ne le penses ?

0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1 > blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024
20 juin 2023 à 17:40

Justement, le problème ne vient pas de la stratégie, car tout le monde sait qu'elle est perdante. Le problème réside plutôt dans mon programme, car j'obtenais des résultats pour le moins étranges...


Mais je vais commencer à croire que tu es vraiment stupide. Je te l'ai déjà répété deux fois : je n'essaie pas d'imiter un jeu de casino !

Les 49,5 % de victoire proviennent simplement de la condition de victoire que j'impose moi-même. J'ai choisi ce pourcentage car il est évident qu'à long terme, le résultat soit perdant.

0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié le 20 juin 2023 à 18:16

Salut CoDForlan,

Ton lien vers le code sur ton dépôt Git n'est plus valable et comme tu n'as pas mis ton code C sur le forum, je ne peux pas voir ton code, ni le tester et te dire si quelque chose cloche.

Pour ce type de simulations, utiliser la fonction standard rand() n'est pas recommandé en raison de ses biais, qui peuvent être renforcés selon la façon dont tu détermines l'issue pour décider si le résultat renvoyé correspond tes 49,5 % de chances de succès ou pas.

Il y a de nombreuses alternatives.

Une que j'ai utilisée dernièrement en C et qui a une bonne distribution est celle-ci :

https://github.com/wangyi-fudan/wyhash

Son implémentation est disponible dans de nombreux langages.

Si tu veux un avis sur ton code, poste ton code sur le forum stp, en utilisant le bouton code du forum.

0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1
21 juin 2023 à 11:03

Salut Dal, enfin quelqu'un qui veut voir mon code plutôt que de me parler de mathématique:

Voici le lien du repo git https://github.com/g3noce/martingale .

Depuis j'ai modifié le script et je crois qu'il n'y a aucune erreur.

(Je tiens à préciser une fois de plus, pour ceux qui n'auraient pas encore compris... Je suis conscient que la stratégie martingale est mathématiquement perdante à long terme. Il s'agit simplement d'un projet d'entraînement pour améliorer mes compétences en programmation en langage C.)

0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096 > CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023
21 juin 2023 à 11:30

OK, alors, on va commencer par le début.

Ton code est celui-ci :

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

//[RAPPEL DE COMPILATION](pour Mingw en C) : gcc main.c -o main.exe

int main(int argc, char const *argv[]){
    srand((unsigned int)time(NULL));
    int balance = 1024;// a small wallet to limit bets
    int bankroll = 10240;//global money usable by the wallet
    int wheel = 0;//
    int bet = 1;// minimum bet
    int k = 0;//win percentage
    int j = 0;//loss percentage
    for (int i = 0; i < 1000; i++)// loop for the long term math
    {
    while (balance <= 2048){//limit of the small wallet when it doubles
        if (balance - bet <= 0){//if the next loss the small wallet is negative then we stop betting
            bet = 1;
            break;
        }

        wheel = rand() % 1000;//simulation wheel
        if (wheel > 0 && wheel < 492)// I put 492 / 1000 instead of 495 because I noticed that in the long term there's a 3 / 1000 percentage shift.
        {
            k += 1*bet;//I multiply by the number of bets to see the short-term variance.
            balance += bet;
            //printf("win %d balance %d\n", bet,balance);
            bet = 1;
        } else// if it's a loos
        {
            j += 1*bet;//I multiply by the number of bets to see the short-term variance.
            balance -= bet;
            //printf("loss %d balance %d\n", bet,balance);
            bet = bet*2;
        }
    }
    if (balance >= 2048){//if it's a double up
        bankroll += balance;
        balance = 1024;
        bankroll -= balance;
    }
    else{// if it's a loss down
        bankroll += balance;
        balance = 1024;
        bankroll -= balance;
    }
    }
    printf("bankroll : %d\ncashout : %d\n", bankroll, bankroll - 10240);
    printf("p(win)%f , p(loss)%f\n",(float)k/(k+j), (float)j/(k+j));// percentage of wins and losses (with variance view option)
}

Si je compile et exécute ce code à 4 reprises (Linux Debian - gcc 8.3.0), j'obtiens ces résultats :

$ gcc -Wall -Wextra 37867713.c
37867713.c: In function ‘main’:
37867713.c:8:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
 int main(int argc, char const *argv[]){
          ~~~~^~~~
37867713.c:8:32: warning: unused parameter ‘argv’ [-Wunused-parameter]
 int main(int argc, char const *argv[]){
                    ~~~~~~~~~~~~^~~~~~
$ ./a.out 
bankroll : -116944
cashout : -127184
p(win)0.490267 , p(loss)0.509733
$ ./a.out 
bankroll : -115219
cashout : -125459
p(win)0.490360 , p(loss)0.509640
$ ./a.out 
bankroll : -107798
cashout : -118038
p(win)0.490797 , p(loss)0.509203
$ ./a.out 
bankroll : -137877
cashout : -148117
p(win)0.488383 , p(loss)0.511617

Dans ton code, je ne suis pas sûr de bien comprendre cette partie qui est exécutée à chaque itération de tes 1000 tirages :

    if (balance >= 2048){//if it's a double up
        bankroll += balance;
        balance = 1024;
        bankroll -= balance;
    }
    else{// if it's a loss down
        bankroll += balance;
        balance = 1024;
        bankroll -= balance;
    }

Peux-tu expliquer ce que tu essayes de faire ?

0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1 > [Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024
Modifié le 21 juin 2023 à 12:00

Cette partie est là pour le cas où le "petit wallet" parvient à doubler la mise de départ, soit 1024*2 (double-up). Sinon, si la stratégie ne peut pas se poursuivre, c'est-à-dire si le prochain pari est supérieur au petit wallet, comme indiqué ici :

if (balance <= bet){//if the next bet is smaller than the small wallet, we stop betting
            bet = 1;
            break;
        }

ensuite:

else{// if it's a loss down
        bankroll += balance;
        balance = 1024;
        bankroll -= balance;
    }
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096 > [Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024
Modifié le 21 juin 2023 à 12:04

aussi, ton break qui devrait te sortir du jeu lorsque ton prochain pari aboutirait à un risque de te retrouver avec un "wallet" négatif ne fonctionne pas, car tu ne sors que de la boucle while avec ce break et pas de la boucle for.

d'ailleurs, je ne vois pas à quoi sert cette boucle while à cet endroit (je la retirerai, en autres changements paraissant nécessaires sur ton code).

j'ai l'impression qu'elle est inutile et qu'elle fait partie de ce que tu veux, en réalité gérer avec les if / else qui sont en fin de boucle for et sur lesquels je t'interroge.

0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096 > CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023
21 juin 2023 à 13:35

As-tu d'autres solutions que srand avec le temps et rand() % n ?

J'ai déjà répondu à cette question ici. En regardant les sources de l'implémentation tu vois qu'en en faisant un #include "wyhash.h" (et #include <inttypes.h>) tu dois d'abord initialiser un uint64_t avec une graine aléatoire.

Par exemple, sous Linux :

    /* get a random seed for wyrand */
    uint64_t seed;
    FILE* urandom = fopen("/dev/urandom", "r");
    fread(&seed, sizeof(uint64_t), 1, urandom);
    fclose(urandom);

Puis en combinant un appel à wy2u0k() avec wyrand() tu peux obtenir un nombre entre 0 et la borne supérieure souhaitée :

int tirage = (int) wy2u0k(wyrand(&seed), borne_superieure);

Cette partie est là pour le cas où le "petit wallet" parvient à doubler la mise de départ, soit 1024*2 (double-up). Sinon, si la stratégie ne peut pas se poursuivre, c'est-à-dire si le prochain pari est supérieur au petit wallet

OK, alors est-ce que ton code ne devrait être comme ceci plutôt :

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main(void) {
        srand((unsigned int)time(NULL));
        int balance = 1024;// a small wallet to limit bets
        int bankroll = 10240;//global money usable by the wallet
        int initial_bankroll = bankroll;
        int bet = 1;// minimum bet
        int win_count = 0;
        int loss_count = 0;
        int doubled_wallet = 0;
        for (int i = 0; i < 1000; i++) {
                /* if next bet could empty our wallet, we end the game */
                if (balance - bet <= 0) {
                        bet = 1;
                        printf("stopped early after %d bets\n", i + 1);
                        break;
                }

                int wheel = rand() % 1000;
                if (wheel > 0 && wheel < 492) {
                        /* it is a win */
                        win_count++;
                        balance += bet;
                        bet = 1;
                } else {
                        /* it is a loss */
                        loss_count++;
                        balance -= bet;
                        bet = bet*2;
                }
                if (balance >= 2048) {
                        /* if we doubled the wallet or more, we remove 
                         * what is in excess of 1024 from the wallet, put 
                         * it safe in the bankroll, and continue with a
                         * wallet of 1024 only */
                        doubled_wallet = 1;
                        bankroll += balance - 1024;
                        balance = 1024;
                }
        }
        printf("bankroll before game vs after game: %d vs. %d\n"
                        "doubled_wallet: %s\n"
                        "profit: %d\n",
                        initial_bankroll, bankroll,
                        doubled_wallet ? "yes" : "no",
                        bankroll - initial_bankroll + balance - 1024
              );
        printf("p(win)%f , p(loss)%f\n",
                        (float)win_count / (win_count + loss_count),
                        (float)loss_count / (win_count + loss_count));
}
1
PierrotLeFou
20 juin 2023 à 18:15

Donc, tu as une roulette "hypothétique"? C'est toi qui décides la probabilité de gagner ou perdre?
Je n'ai pas regardé ton code non plus. Quel outil utilises-tu pour générer des nombres aléatoires, et dans quel range (entiers ou dans [0, 1) ) ?
Pour savoir si tu gagneras à long terme, il faut jouer vraiment beaucoup de parties.
Si tu utilises une fonction cyclique comme les modulo pour générer tes nombres aléatoires, après combien de cycles retournes-tu au nombre de départ? Est-ce constant?

0
blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024 3 317
20 juin 2023 à 21:55

Pour savoir si tu gagneras à long terme, il faut jouer vraiment beaucoup de parties.

Le postulat de départ est de doubler la mise en cas de perte ("À chaque fois que je perds, je double ma mise initiale"). Donc, créer ou pas un programme avec n % de probabilité de gagner n'est en aucune façon un moyen de voir comment se comporte cette martingale classique (dite "la doublante"). Son comportement est déjà connu d'avance.
 

Mais comme on me l'a fait remarquer :

Mais je vais commencer à croire que tu es vraiment stupide

Ca ne sert donc à rien d'expliquer à quelqu'un que son programme ne sert à rien..

0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096 > blux Messages postés 26539 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 20 décembre 2024
21 juin 2023 à 10:43

Salut blux,

Je peux comprendre que tu sois mécontent (comme certainement CoDForlan d'ailleurs) de cet échange qui a dégénéré.

Cependant, CoDForlan qui ne niait pas que la stratégie de mise "martingale" soit perdante, s'interrogeait sur le fonctionnement de son programme en language C qui semble-t-il ne lui permettait pas de le confirmer par la simulation qu'il implémentait.

Il voulait donc une aide sur son programme en langage C, ce que tu n'as pas voulu lui donner car tu estimes que cela ne sert à rien.

On ne doute pas que ton domaine de compétences comprenne les probabilités, mais la question de CoDForlan sur le forum concernait le fonctionnement apparemment erroné de son programme en langage C et je vois pas pourquoi on devrait lui refuser cette aide sous prétexte que mathématiquement coder une simulation ne servirait à rien.

0
CoDForlan Messages postés 44 Date d'inscription mercredi 17 juin 2020 Statut Membre Dernière intervention 21 juin 2023 1
21 juin 2023 à 11:19

J'utilise srand avec le temps et la fonction rand % 1000 pour obtenir un nombre entre 0 et 999.

J'ai effectué des tests avec 100 000, voire même 1 000 000 d'itérations, et le problème ne semblait pas provenir de là, je pense. Cependant, actuellement, je crois enfin avoir compris mon erreur, s'il n'y en avait qu'une. (Si vous pouviez jeter un coup d'œil à mon programme, ce serait sympa. Merci d'avance.)

0