IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Demande d'aide pour élaborer un algo pour un pb simple mais long


Sujet :

Algorithmes et structures de données

  1. #61
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    Citation Envoyé par fremen167 Voir le message
    Sur le traitement effectué après l'échec des candidats c(pc,-) :
    - tu commences par calculer le max des c(j,4) pour 0 < j < pc-2
    ==> 3) pourquoi pas pc - 1 ?
    - puis pour pc, tu recherches le plus grand k tel que c(pc,k) > ce max.
    ==> 4) ne faut-il pas écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    While (c(pc, k) > l And k > 0)
    Sur les points précédents 1 & 2, précise, je ne comprends pas trop tes questions... mais peut-être suis-je fatigué, j'essayerai de relire demain...

    concernant l'après échec:

    - en pc, ça à foiré;
    - on recule donc en pc-1 en l'annulant & en mettant à jour libre et inn();
    - en pc-1, on s'intéresse à ce qu'il y a en 1....pc-2, car "dans le compteur c(pc-1,_), si on a essayé des sommets "nouveaux" (= supérieur à ce qu'il y a en 1...(pc-2)), c'est plus la peine". Je m'explique:

    imagine que pour

    pc=1: c(1,-) = 02345
    pc=2: c(2,-) = 13456
    pc=3: c(3,-)= 24567
    pc=4: ECHEC

    ICI, en pc=3, on a testé par rapport à pc=1 & 2 un nouveau sommet: 7, qui a donné un échec. Tester en c=3 le sommet 8 ne sert à rien: car dans cette configuration, les sommets 7 et 8 fournissent les mêmes possibilités....

    Dans l'algo, la variable "l" donne le plus haut sommet des c(x,-) pour x<=pc-2. Ce qui permet d'incrémenter correctement le compteur c(pc-1,_), en reculant jusqu'à c(pc-1,y) où les c(pc-1,x) pour x>y sont TOUS "nouveaux"...

    Autre Exemple:

    pc=1: c(1,-) = 02345
    pc=2: c(2,-) = 01345
    pc=3: c(3,-)= 012567
    pc=4: ECHEC

    Pas la peine de tester c(3,-)=012578

  2. #62
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    @Nemerle
    Je ne crois pas que le formalisme des graphes apporte quelque chose. C'est simplement une autre façon de voir, plus parlante pour certains.
    De fait on a trois façons de voir les choses.
    La façon 'relationelle' au sens relation d'un ensemble vers un autre. Ici il s'agit des relations d'un ensemble à 9 éléments vers lui-même, on cherche en particulier les relations pour lesquelles, tout élément de la source est relié à 5 éléments du but et à 5 exactement, et pour lesquelles chaque élément du but possède exactement 5 antécedents.
    Par le biais du 'graphe' au sens usuel des relations (partie de ExE) on est immédiatemment ramené à ta description du problème.
    Cela dit, partant du graphe, en prenant la matrice d'adjacence, on revient immédiatement au pb initial.
    J'ai eu un peu de mal à lire ton algo en vba mais j'en comprends les idées.
    Je ne comprends cependant pas pourquoi tu refuses les flèches retombant sur le sommet dont elles sont issues, cela revient à éliminer les matrices avec des 1 sur la diagonale, au nom de quoi ?
    Je comprends ce qui motive ton enthousiasme (2000 soluces avec Excel en 20 secondes, c'est encourageant, on peut se dire qu'avec une bonne bécane, un vrai langage de programmation on va aller au bout).
    Je crois que c'est une erreur.
    Je joins un programme en C pur et dur, itératif, ne consommant ni pile ni mémoire. Ce programme donne 100000 solutions en moins de 30 secondes, mais il ne sort pas. Je pense que l'algo est bon mais que le temps de calcul est trop long. Il faudrait encore simplifier, mais je sèche toujours:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    #include <stdio.h>
    #include <stdlib.h>
     
    // tableau des 126 lignes possibles
    unsigned int possibles[126];
     
    // Accès aux chiffres binaires
    unsigned char Digit(unsigned int i,unsigned int n)
    {
        int k;
        for (k=0;k<i;k++) n/=2;
        return n%2;
    }
    // représentation des matrices
    // par une suite d'indices dans le tableau
    typedef struct
    {
        int n;
        unsigned char C[9];
    } Matrix;
     
    // recopie d'une matrice
    void Copy (Matrix * pM,Matrix * pR)
    {
        int i;
        for (i=0;i<pM->n;i++)
            pR->C[i]=pM->C[i];
        pR->n=pM->n;
    }
     
    // ajout d'une ligne
    void Append (Matrix * pM, unsigned char c)
    {
        pM->C[pM->n]=c;
        (pM->n)++;
    }
     
    // calcule la somme des coefficients de la colonne d'indice i
    unsigned int SumCol(unsigned int i,Matrix * pM)
    {
        unsigned int s=0;
        int j;
        for (j=0; j<pM->n; j++)
            s+=Digit(i,possibles[pM->C[j]]);
        return s;
    }
     
    // prédicat logique
    // dit si c peut être une nouvelle ligne
    // pour la matrice pointée par pM
    int CanFollow( Matrix * pM, unsigned char c)
    {
        Matrix R;
        Copy(pM,&R);
        Append(&R,c);
        int i;
        for (i=0;i<R.n;i++)
        {
            if (SumCol(i,&R)>5)
                return 0;
            if ((SumCol(i,&R)+9-R.n)<5)
                return 0;
        }
        return 1;
    }
     
    // calcule le nombre de chiffres de n en binaire
    int NumberDigits(unsigned int n)
    {
        if (n==1) return 1;
        else
            return (n%2)+NumberDigits(n/2);
    }
     
    // détermine si la représentation binaire d'un entier
    // comporte 5 fois le chiffre 1
    int Has5Digits(unsigned int n)
    {
        return NumberDigits(n)==5;
    }
     
    // initialise le tableau des 126 possibles pour les lignes
    void FillPossibles()
    {
        int i,j;
        for (i=1,j=0;i<512;i++)
            if (Has5Digits(i))
                possibles[j++]= i;
    }
     
     
    // Calcul le nombre de chiffres de l'élément d'inice i
    // du tableau des possibles
    unsigned char DigitI(unsigned int i, unsigned int n)
    {
        return Digit(i,possibles[n]);
    }
     
    // affiche une ligne
    void pprintl(unsigned int n)
    {
        int i;
        for (i=0;i<9;i++)
            printf("%d",DigitI(i,n));
        printf("\n");
    }
     
    // affiche toute une matrice
    void pprintM(Matrix *pM)
    {
        int i;
        printf("-------------------\n");
        for (i=0;i<9;i++)
        {
            pprintl(pM->C[i]);
        }
        printf("-------------------\n");
    }
     
    // recherche de max solutions
    void Recherche(unsigned int max)
    {
        Matrix M0;
        unsigned char n1,n2,n3,n4,n5,n6,n7,n8;
        Matrix M1,M2,M3,M4,M5,M6,M7,M8;
        unsigned int nbsol=0;
        unsigned char i;
        for (i=0;i<9;i++)
            M0.C[i]=0;
        M0.n=1;
        M0.C[0]=0;
        for (n1=0;n1<126;n1++)
        {
            if (CanFollow(&M0,n1))
            {
                Copy(&M0,&M1);
                Append(&M1,n1);
                for (n2=n1;n2<126;n2++)
                {
                    if (CanFollow(&M1,n2))
                    {
                        Copy(&M1,&M2);
                        Append(&M2,n2);
                        for (n3=n2;n3<126;n3++)
                        {
                            if (CanFollow(&M2,n3))
                            {
                                Copy(&M2,&M3);
                                Append(&M3,n3);
                                for (n4=n3;n4<126;n4++)
                                {
                                    if (CanFollow(&M3,n4))
                                    {
                                        Copy(&M3,&M4);
                                        Append(&M4,n4);
                                        for (n5=n4;n5<126;n5++)
                                        {
                                            if (CanFollow(&M4,n5))
                                            {
                                                Copy(&M4,&M5);
                                                Append(&M5,n5);
                                                for (n6=n5;n6<126;n6++)
                                                {
                                                    if (CanFollow(&M5,n6))
                                                    {
                                                        Copy(&M5,&M6);
                                                        Append(&M6,n6);
                                                        for (n7=n6;n7<126;n7++)
                                                        {
                                                            if (CanFollow(&M6,n7))
                                                            {
                                                                Copy(&M6,&M7);
                                                                Append(&M7,n7);
                                                                for (n8=n7;n8<126;n8++)
                                                                {
                                                                    if (CanFollow(&M7,n8))
                                                                    {
                                                                        Copy(&M7,&M8);
                                                                        Append(&M8,n8);
                                                                        //pprintM(&M8);
                                                                        nbsol++;
                                                                        if(nbsol==max)
                                                                        return;
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
     
        }
     
    }
     
     
    int main()
    {
        FillPossibles();
        Recherche(100000);
        return 0;
    }
    Les perfs sont un peu moins que linéaires en max.
    211 s pour 1000000
    617 s pour 3000000

  3. #63
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    @Nemerle
    Je ne crois pas que le formalisme des graphes apporte quelque chose. C'est simplement une autre façon de voir, plus parlante pour certains.
    Bein oui, tu as raison ! Cela n'apporte effectivement presque rien, si ce n'est:
    - une façon de voir les choses qui me va bien (à moi )
    - une façon "visuelle" qui permet d'écrire un algo rapidement et de s'éviter une liste de règles matricielles pas forcément exhaustive
    - un façon qui permet si on le désire de PROUVER plus facilement l'intégrité de l'algo (ex: la "preuve" concernant l'algorithme donnant les classes des représentations unitaires des groupes de Lie de rang 1 passe... par des "parcours" de graphes plutôt que des manipulations matricielles).
    - enfin, une façon d'appréhender la complexité a minima du problème.

    Trois dernières remarques:

    - tu as raison concernant les boucles, j'ai effectivement ajouté cette contrainte sans aucune raison! J'ai inventé que cela était une condition du problème initial, ce qui n'est pas la cas. Mais l'algo des graphes se modifie en deux coups de cuillière à pot si l'on veut supprimer cette contrainte!
    - il me semble qu'il est ILLUSOIRE de chercher un algo qui termine le problème RAPIDEMENT. On voit bien qu'il y a un nombre hallucinant de chemins à parcourir & tester a minima...
    - 100 000 soluces en 30s en C, cela me semble "long". As-tu essayé de coder l'algo des graphes en pur "C" ?? Je lance un appel d'offre ()

  4. #64
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut On avance, on avance !
    Je viens de modifier la fonction CanFollow, la nouvelle ne nécessite plus aucune copie de matrice.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int CanFollow( Matrix * pM, unsigned char   c)
    {
        int i;
        for (i=0;i<9;i++)
        {
            if (pM->Scol[i]+digits[c][i]>5)
                return 0;
            if (pM->Scol[i]+digits[c][i]+9-pM->n < 5)
                return 0;
        }
        return 1;
    }
    Par ailleurs, je viens de changer de compilo et de machine (VISUAL C++ EXPRESS sous Vista avec 2GB au lieu de MINGW sous XP 512 MB).
    Résultat:
    Le programme turbo peut sortir en moins de deux heures le nombre des solutions ordonnées lexico. Estimation: autour de 300000000.
    C'est parti !
    à suivre .....
    C'est terminé.
    Estimation pessimiste, le nombre exact: 66916396
    Evidemment cela ne correspond qu'aux matrices dont les lignes sont ordonnées.
    Pour parvenir au résulat total il faut donc permuter de toutes les façons possibles les lignes et les colonnes, éliminer les doublons, etc...
    Le traitement a duré 30 minutes.
    Mais mon programme ne fait que 'trouver' les solutions et les compter.
    Evidemment si l'on veut les afficher à l'écran, ou mieux les imprimer dans un fichier il sera beaucoup plus long (il passera certainement plus de temps à écrire qu'à calculer.

  5. #65
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Pour finir j'ai l'ensemble des solutions dans un fichier compressé (7z)
    une fois décompressé chaque matrice apparaît comme une ligne de 18 chiffres hexa. Il faut décomposer en 9 tranches de 2 chiffres, qui une fois en binaire, donneront les lignes de la matrice.
    Pour toute personne qui le souhaite je peux envoyer l'original du programme qui génère le fichiers des solutions 1.7 GB
    le compressé ne fait que 18 MB

  6. #66
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    whoua... quel acharnement à résoudre ce problème. Félicitations et respect a Zavonen et Nemerle pour leur dévouement.



    @Zavonen: pense a prendre un peu de repos, quand meme...

  7. #67
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Bon, et bien moi aussi, j'ai un programme qui tourne .

    J'ai implémenté les différentes règles énoncées plus haut (qui permettent de dédoublonner, comme le souhaitait Mougel), plus une nouvelle :

    Lors de l'ajout d'une ligne, je vérifie qu'il n'y a pas plus d'exemplaire de cette ligne que le la ligne 1 (sinon, par permutation, on a une solution équivalente plus grande).

    Il tourne en moins d'une minute 30, et génère 4 961 521 solutions, écriture dans un fichier compris, en format étendu :
    Solution n° 1 :
    111110000
    111110000
    111110000
    111110000
    100001111
    010001111
    001001111
    000101111
    000011111

    Solution n° 2 :
    111110000
    111110000
    111110000
    111101000
    110000111
    001001111
    000101111
    000011111
    000011111
    etc.

    ce qui donne un fichier de 600 Mo environ.
    Je peux fournir le code et le fichier résultat à qui serait intéressé

  8. #68
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Oui, cela me trottait en tête depuis un moment, parce que je crois il y a quelques mois, ce problème avait été posé et que je m'étais planté.
    Pour finir je n'ai aucun intérêt pour le résultat, c'est juste pour le 'fun'.
    Je vais suivre tes conseils même si, par force, j'ai maintenant beaucoup de temps.

  9. #69
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Bon, et bien moi aussi, j'ai un programme qui tourne .
    Bravo à toi, et pour le turbo.
    Comptons nous les mêmes choses ?
    Je me restreins aux matrices ordonnées, je ne peux pas avoir de doublons, regarde comment mes boucles sont imbriquées.
    n2 démarre avec la valeur n1
    n3 avec la valeur n2
    etc...
    de sorte qu'avec la boucle la plus profonde, il est mpossible d'avoir
    le même n1
    le même n2
    et ainsi de suite jusqu'à n8
    Sauf grosse erreur de ma part mes matrices sont toutes distinctes, et j'en ai beaucoup plus que toi.
    Où est l'erreur ?
    Peux tu poster ton programme, s'il te plaît ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    // Pour écrire les solutions
    FILE *fp;
    // tableau des 126 lignes possibles
    unsigned int possibles[126];
    // décomposition binaire de chacune des possibilités
    unsigned char digits[126][9];
     
    // Accès aux chiffres binaires
    unsigned char Digit(unsigned int i,unsigned int n)
    {
    	int k;
    	for (k=0;k<i;k++) n/=2;
    	return n%2;
    }
    // représentation des matrices
    // par une suite d'indices dans le tableau
    typedef struct
    {
    	int n;
    	unsigned char C[9]; // chaque ligne est représentée par un indice du tableau
    	unsigned char Scol[9];// mémorise les sommes des colonnes
    } Matrix;
     
    // recopie d'une matrice
    Copy (Matrix * pM,Matrix * pR)
    {
    	memcpy(pR,pM,sizeof(Matrix));
    }
     
    // ajout d'une ligne
    void Append (Matrix * pM, unsigned char  c)
    {
    	int i;
    	pM->C[pM->n]=c;
    	(pM->n)++;
    	for (i=0;i<9;i++)
    		pM->Scol[i]+=digits[c][i]; // mise à jour des sommes
    }
     
    // prédicat logique
    // dit si c peut être une nouvelle ligne
    // pour la matrice pointée par pM
    // une matrice dans la pile pour chaque appel à CanFollow
    int CanFollow( Matrix * pM, unsigned char   c)
    {
    	int i;
    	for(i=0;i<9;i++)
    	{if (pM->Scol[i]+digits[c][i]>5)
    	return 0;
    	if(pM->Scol[i]+digits[c][i]+9-pM->n < 5)
    		return 0;
    	}
    	return 1;
     
    }
     
    // calcule le nombre de chiffres de n en binaire
    int NumberDigits(unsigned int n)
    {
    	if (n==1) return 1;
    	else
    		return (n%2)+NumberDigits(n/2);
    }
     
    // détermine si la représentation binaire d'un entier
    // comporte 5 fois le chiffre 1
    int Has5Digits(unsigned int n)
    {
    	return NumberDigits(n)==5;
    }
     
    // initialise le tableau des 126 possibles pour les lignes
    void FillPossibles()
    {
    	int i,j;
    	for (i=1,j=0;i<512;i++)
    		if (Has5Digits(i))
    			possibles[j++]= i;
     
    	for (i=0;i<126;i++)
    		for (j=0;j<9;j++)
    			digits[i][j]=Digit(j,possibles[i]);
    }
     
     
    // écrit une ligne dans un fichier
    void pprintl(unsigned int n)
    {
    	int i;
    	fprintf(fp,"%02x",possibles[n]);
    }
     
    // écrit toute une matrice
    void pprintM(Matrix *pM)
    {
    	int i;
    	for (i=0;i<9;i++)
    	{
    		pprintl(pM->C[i]);
    	}
    	fprintf(fp,"\n");
    }
     
     
    void Recherche()
    {
    	Matrix M0,M1,M2,M3,M4,M5,M6,M7,M8;
    	unsigned char n1,n2,n3,n4,n5,n6,n7,n8;
    	unsigned int nbsol=0;
    	unsigned char i;
    	double elapsed;
    	for (i=0;i<9;i++)
    		M0.C[i]=0;
    	M0.n=1;
    	M0.C[0]=0;
    	for (i=0;i<9;i++)
    		M0.Scol[i]=digits[0][i];
    	for (n1=0;n1<126;n1++)
    	{	elapsed=100*n1/125.0;
    	printf("%2.0lf %s\n",elapsed,"% accomplis"); // pour voir l'avancement
    	if (CanFollow(&M0,n1))
    	{
    		Copy(&M0,&M1);
    		Append(&M1,n1);
    		for (n2=n1;n2<126;n2++)
    		{
    			if (CanFollow(&M1,n2))
    			{
    				Copy(&M1,&M2);
    				Append(&M2,n2);
    				for (n3=n2;n3<126;n3++)
    				{
    					if (CanFollow(&M2,n3))
    					{
    						Copy(&M2,&M3);
    						Append(&M3,n3);
    						for (n4=n3;n4<126;n4++)
    						{
    							if (CanFollow(&M3,n4))
    							{
    								Copy(&M3,&M4);
    								Append(&M4,n4);
    								for (n5=n4;n5<126;n5++)
    								{
    									if (CanFollow(&M4,n5))
    									{
    										Copy(&M4,&M5);
    										Append(&M5,n5);
    										for (n6=n5;n6<126;n6++)
    										{
    											if (CanFollow(&M5,n6))
    											{
    												Copy(&M5,&M6);
    												Append(&M6,n6);
    												for (n7=n6;n7<126;n7++)
    												{
    													if (CanFollow(&M6,n7))
    													{
    														Copy(&M6,&M7);
    														Append(&M7,n7);
    														for (n8=n7;n8<126;n8++)
    														{
    															if (CanFollow(&M7,n8))
    															{
    																Copy(&M7,&M8);
    																Append(&M8,n8);
    																// à remplacer par un fprintf
    																pprintM(&M8);
    																nbsol++;
     
     
     
    															}
    														}
    													}
    												}
    											}
    										}
    									}
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    	}
     
    	}
    	printf("%u\n",nbsol);
    }
     
     
    int main()
    {
    	fp=fopen("solutions.txt","wt");
    	FillPossibles();
    	Recherche();
    	fclose(fp);
    	system("Pause");
    	return 0;
    }

  10. #70
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Peux tu poster ton programme, s'il te plaît ?
    Oui, le voici (en Delphi 3) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
     
    TLigne    = array[1..9] OF integer ;
    TMatrice  = array[1..9] OF TLigne ;
    var
      Form1   : TForm1;
      Ficsor : Text ;
      Matrice, LastMatrice : TMatrice ;
      LigneModele, SumCol : TLigne ;
      Modele  : array[1..126] OF TLigne ;
      L2      : array[1..3] OF integer ;
      CumulL2, NumL2, IndiceModele, NumSoluce, NbMaxSoluces, L, C : integer ;
     
    implementation
     
    {$R *.DFM}
     
     
    Procedure AjouterModele ;
    Var Col : Integer ;
    Begin
       IndiceModele := IndiceModele + 1 ;
       Modele[IndiceModele] := LigneModele ;
       Writeln('Modele n° ', IndiceModele) ;
       For Col := 1 to 9 do Write(LigneModele[Col]) ;
       Writeln ;
    End ; {de Afficher}
     
     
    Procedure GenererModeles(pos, restant : integer) ;
    Var i : integer ;
    Begin
    if restant = 0
    then
       begin
          for i := pos to 9 do LigneModele [i] := 0 ;
          AjouterModele ;
       end
    else
       begin
       if pos + restant = 10
       then
          begin
          for i := pos to 9 do LigneModele [i] := 1 ;
          AjouterModele ;
          end
       else
          begin
          {Génération des modèles avec 1 en position pos -
           on commence par 1 pour avoir l'ordre lexicographique descendant}
          LigneModele [pos] := 1 ;
          GenererModeles(pos+1,restant-1) ;
          {Génération des modèles avec 0 en position pos}
          LigneModele [pos] := 0 ;
          GenererModeles(pos+1,restant) ;
          end
       end ;
    End ; {de GenererModeles}
     
    Procedure Afficher ;
    Var Lig, Col : integer ;
    Begin
    Inc (NumSoluce) ;
    If (NumSoluce > NbMaxSoluces) and (NbMaxSoluces <> 0)
    Then
       begin
       Write   ('Nombre de solution maxi atteint ') ;
       Writeln (NumSoluce, ' / ', NbMaxSoluces) ;
       Readln ;
       Halt(1) ;
       end ;
     
    LastMatrice := Matrice ;
    Writeln (Ficsor) ;
    Writeln (FicSor,'Solution n° ', NumSoluce, ' :') ;
    For Lig := 1 to 9 do
       begin
       For Col := 1 to 9 do Write(Ficsor, Matrice[Lig,Col]) ;
       Writeln (Ficsor) ;
       end ;
    End ; {de Afficher}
     
    {Ajoute Modele[NumModele] en ligne NumLigne de Matrice
     et incrémente les cumuls par colonne correspondant}
    Procedure AjouterLigne(NumLigne, NumModele : integer) ;
    Var
    Col : integer ;
    Begin
    Matrice[Numligne] := Modele[NumModele] ;
    For Col := 1 to 9 do
      SumCol [Col] := SumCol [Col] + Modele[NumModele,Col] ;
    End ; {de AjouterLigne}
     
    {Décrémente les cumuls par colonne correspondant à la ligne à supprimer
     (on ne la supprime pas physiquement)}
    Procedure RetirerLigne(Lig : integer) ;
    Var
    Col : integer ;
    Begin
    For Col := 1 to 9 do
      SumCol [Col] := SumCol [Col] - Matrice[Lig, Col] ;
    End ; {de RetirerLigne}
     
     
    Function ControleContraintes(NumLigne : integer) : boolean ;
    Var Lig, Col, CumulLigne, NbL1, NbLn : integer ;
        Res, Encore : boolean ;
    Begin
    Res := true ;
    CumulLigne := Matrice[NumLigne,2] +
                  Matrice[NumLigne,3] +
                  Matrice[NumLigne,4] +
                  Matrice[NumLigne,5] ;
     
    {Règle 3 étendue}
    If CumulLigne > CumulL2
    Then Res := false
    Else
      {Boucle de contrôle des cumuls de colonnes, sauf la 1ère qui par
       construction (Règle 2) est forcément OK}
      begin
      {Inutile de faire ces contrôles avant la ligne 5}
      If Numligne > 4
      Then
         begin
         Col := 2 ;
         While Res And (Col <= 9) Do
            begin
            {Plus de 5 '1' dans une colonne}
            If SumCol[Col] > 5 Then Res := False ;
         {Plus assez de ligne à créer pour avoir 5 '1' dans une colonne}
            If SumCol[Col] < NumLigne - 4 Then Res := False ;
            Inc(Col) ;
            end ;
         end ;
      end ;
    {Règle 5 (dédoublonnage) : Le plus grand nombre de lignes égales doit
     correspondre aux nombre de lignes de type L1 (=111110000).
     Dans le cas contraire, on pourrait par permutations obtenir une solution
     plus grande.
     On ne contrôle que la derniere ligne, puisque les précédentes l'ont déjà été.}
      If Res
      Then
         begin
         {Calcul nb de lignes L1}
         Lig := 1 ;
         NbL1 := 0 ;
         Encore := true ;
         While Encore do
            If Lig > Numligne Then Encore := False
            Else
               begin
               Col := 1 ;
               While Encore And (Col <= 9) do
                  If Matrice[Lig,Col] <> Matrice[1,Col]
                  Then Encore := False
                  Else Inc(Col) ;
               If Encore
               Then Inc(NbL1) ;
               Inc (Lig) ;
               end;
         {Calcul nombre de lignes NumLigne}
         Lig := NumLigne ;
         NbLn := 0 ;
         Encore := true ;
         While Encore do
            If Lig < 1 Then Encore := False
            Else
               begin
               Col := 1 ;
               While Encore And (Col <= 9) do
                  If Matrice[Lig,Col] <> Matrice[NumLigne,Col]
                  Then Encore := False
                  Else Inc(Col) ;
               If Encore
               Then Inc(NbLn) ;
               Dec (Lig) ;
               end;
     
         If NbLn > NbL1 Then Res := False ;
         end ;
      ControleContraintes := Res ;
    End ; {de ControleContraintes}
     
    Procedure Explorer (NumLigne, NumModele : integer) ;
    Var NumDeb, NumFin, i : integer ;
    Begin
    If ControleContraintes(NumLigne)
    Then
       If NumLigne = 9
       Then Afficher
       Else
          begin
          {Règle 2}
          If (NumLigne > 4)  And (NumModele < 71)
             Then NumDeb := 71
             Else NumDeb := NumModele  ;
     
          If NumDeb < 71
          Then NumFin := 70
          Else NumFin := 126 ;
     
          For i := NumDeb to NumFin Do
             Begin
             {Ajout à la ligne i du modèle en ligne (NumLigne + 1) de la matrice
              On incrémente aussi les totaux de colonnes}
             AjouterLigne (NumLigne + 1, i) ;
             Explorer (NumLigne + 1, i) ;
             {Retrait de la ligne (NumLigne + 1) de la matrice (il s'agit de décrémenter les totaux par colonne)}
             RetirerLigne (NumLigne + 1) ;
             End ; {du For}
          End ; {Du cas NumLigne <> 9}
    {Si ControleContraintes retourne faux, inutile d'aller + loin dans cette branche}
    End ;
     
    Begin
    {Ouverture du fichier de sortie}
    AssignFile(FicSor, 'D:\TestsDelphi\SolucesMougel-01.txt') ;
    Rewrite(Ficsor) ;
     
    {Génération des 126 modèles de lignes dans l'ordre lexicographique descendant}
    IndiceModele := 0 ;
    GenererModeles(1,5) ;
     
    {Règle 1}
    AjouterLigne(1,1) ;
     
    {Stockage des numero de modele des lignes 2 possibles - cf. Règle 4}
    L2[1] := 1;
    L2[2] := 2;
    L2[3] := 6;
     
    {Demande du nombre maxi de solutions}
    Write('Combien de solutions maximums ?') ;
    Readln (NbMaxSoluces) ;
     
    {Règle 4}
    For NumL2 := 1 to 3 Do
       Begin
       AjouterLigne(2,L2[NumL2]) ;
       CumulL2 := Matrice[2,2] + Matrice[2,3] + Matrice[2,4] + Matrice[2,5] ;
       Explorer(2,L2[NumL2]);
       RetirerLigne(2) ;
       End ;
    {Fermeture du fichier de sortie}
    Writeln ('Fin des solutions') ;
    Writeln ('Dernière solution obtenue : (', NumSoluce, ')') ;
    For L := 1 to 9 do
       begin
       For C := 1 to 9 do Write(LastMatrice[L,C]) ;
       Writeln ;
       end ;
    Readln ;
    End.
    Le fait que nous n'avons pas le même nombre de solutions vient de ce que l'ordre lexicographique ne suffit pas à supprimer toutes les équivalences, d'où les différentes règles que j'ai implémentées (et expliquées dans mes précédents posts). Ceci dit, je ne suis pas du tout sûr d'avoir supprimé suffisament de cas.

    Par contre, comme tu le vois, je n'ai pas recherché l'optimisation sur le plan technique (mon programme est récursif, j'utilise des tableaux d'entiers pour représenter mes matrices...) Il est certainement possible de l'optimiser... mais est-ce bien nécessaire ?

  11. #71
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Je m'adresse à Fremen167, mais bien évidemment aussi à Mougel, Rakken, Nemerle, Pseudocode et tous ceux qui ont jusqu'ici contribué.
    Le fait que nous trouvions des résultats différents n'est donc pas étonnant, si nous ne cherchons pas la même chose. Ce qui serait bien c'est d'arriver à établir la 'cohérence' qui nous prouverait que nous avons tous raison.
    Tout d'abord le résultat que j'ai été piocher sur le web:
    Le nombre cherché est: Bv[9,4,9,4] = 315031400802720
    est il EXACT ????
    Tout d'abord je n'ai aucun doute pour ce qui concerne ce qu'il PRETEND être:
    Le nombre total des solutions, sans omissions ni répétitions.
    Croire qu'il est exact pace qu'il est imprimé, qu'il est sur le web, que le papier est rédigé par des universitaires, etc... serait disons un 'péché de jeunesse' ou un excès de naïveté. Très peu de gens lisent en détail les articles spécialisés, quant à refaire les calculs...
    Enfin, il n'y a pas de raison de soupçonner qu'il est faux, mais il serait imprudent de prendre le fait comme une certitude.
    La théorie algébrique qui sous-tend tout cela est celle des 'groupes opérant sur un ensemble', (notions d'orbites, de stabilisateur, etc...).
    L'ensemble est ici un ensemble à 9 éléments, sur lequel opèrent deux groupes isomorphes de permutations ayant chacun 9!=362880 éléments
    Gc: le groupe des permutations des colonnes
    Gl: le groupe des permutations des lignes.
    On peut donc restreindre le problème en cherchant à trouver les solutions 'à une permutation près' en considérant comme équivalentes deux solutions se déduisant l'une de l'autre par une permutation de lignes composée avec une permutation de colonnes ou le contraire. Attention, nous sommes ici dans des groupes non commutatifs.
    On peut donc chercher des ensembles 'minimaux' qui vont engendrer toutes les solutions en prenant leurs orbites par les éléments de Gc puis les orbites de ces orbites par les éléments de Gl. C'est la démarche disons 'intelligente' et la vie suivie par Fremen167.
    A souligner dès à présent que même si on a réussi à déterminer cet ensemble minimal (disons de générateurs) l'algorithme qui consiste à rétablir l'ensemble exact de toutes les solutions parce que l'opération des groupes, même si elle est transitive n'est pas 'fidèle'.
    Voici un exemple: Il existe bien évidemment des solutions ayant des lignes ou des colonnes identiques, il est impossible que l'ensemble minimal, quel qu'il soit ne comporte pas de tels éléments parce que par permutation d'éléments tous distincts on arrive toujours à des éléments tous distincts.
    Donc si un élément à deux lignes égales, il est invariant par la transposition échangeant ces deux lignes.
    Bref, pour tout élément il existe un sous groupe, en général non nul, de permutations le laissant invariant (i.e: son 'stabilisateur').
    Ce qui fait que si on est parvenu à un ensemble minimal, les différentes orbites ne se recouperont pas (c'est déjà çà) mais elles n'auront pas le même nombre d'éléments. Et je ne vois pas comment faire le compte d'une façon systématique sans traiter au cas par cas.
    L'approche selon laquelle on peut se borner à rechercher toutes les solutions dont les lignes OU les colonnes (PAS les deux en même temps) sont ordonnées, par ordre lexicogaphique OU AUTRE (n'importe quel ordre arbitraire total convient aussi bien), permet de déterminer un ensemble à l'intérieur duquel le générateur se trouvera. La remarque étant que par permutations successives on peut toujours trier totalement un ensemble.
    C'est donc mon approche. Notons bien qu' à partir d'un tel résultat (supposons par exemple que mon résultat soit exact - à l'heure actuelle j'en suis encore persuadé), extraire un ensemble minimal est extraordinairement compliqué, (comment s'assurer, en pratique, que chaque solution ne peut pas être déduite d'une autre par une permutation de colonnes par exemple, ou même de lignes consécutives. La reconstruction de l'ensemble des solutions est en pratique possible mais il y aura forcément des répétitions et vu le nombre incroyablement élevé des possibilités c'est hors d'atteinte d'un calculateur (semble-t-il).
    Venons en à la première incohérence.
    Mon résultat est en contradiction avec Bv[9,4,9,4]
    En effet, si mon résultat est exact, le nombre total des solutions est AU PLUS
    9!*66916396 nettement inférieur à:
    315031400802720
    Le résultat de Fremen167 est aussi en contradiction avec ça:
    car il fixe un maximum de solutions égal à 9!*9! fois le nombre des solutions qu'il donne.
    Cependant, il n'y a pas encore de contradiction flagrante entre le résultat de Fremen167 et le mien. Comme je l'ai dit il y a dans mon ensemble de solutions des éléments qui se déduisent les unes des autres par des permutations de colonnes (je ne m'occupe pas des colonnes) ou même de lignes consécutives.
    Pour le moment je suis capable de faire une réduction sur les lignes mais pas sur les colonnes.
    Je n'ai pas encore commençé à scruter le code de Fremen167 (Dr Pseudocode m'a mis au repos...), mais peut être sait-il comment, à partir de son ensemble générer les matrices ordonnées lexico selon les lignes. S'il trouvait le même nombre que moi ce serait très encourageant et cela prouverait que le résultat du web est faux.
    Bon dimanche à tous.
    Mougel, si tu es encore là on aimerait bien te lire sur ce sujet car tu es l'initiateur et la référence.

  12. #72
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Mougel, si tu es encore là on aimerait bien te lire sur ce sujet car tu es l'initiateur et la référence.
    Reference originale: "The asymptotic number of integer stochastic matrices" by Everett & Stein (1971)

    Plus recement: "Asymptotic enumeration of 0–1 matrices with equal row sums and equal column sums" by McKay,Wang (2003)

    selon http://www.research.att.com/~njas/sequences/A008300, la réponse serait: 24046189440 (si je ne me suis pas planté en parcourant la table )

  13. #73
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    la réponse serait: 24046189440 (si je ne me suis pas planté en parcourant la table
    Moi je n'y comprends rien du tout à cette table ni à cette page d'ailleurs.

  14. #74
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    En tout cas je lis pas la même chose que PseudoCode : 315031400802720 serait bien la réponse.
    Je traduis l'explication de la réponse, en fait il est plus clair de représenter cette suite dans un triangle où la valeur T(n,k) (n ligne, k colonne) représente le nombre de matrice n*n de 0/1 pour lesquels la somme sur une ligne ou sur une colonne est toujours k, on cherche donc T(9,5), et le triangle est :
    1,
    1,1,
    1,2,1,
    1,6,6,1,
    1,24,90,24,1,
    1,120,2040,2040,120,1,
    1,720,67950,297200,67950,720,1,
    1,5040,3110940,68938800,68938800,3110940,5040,1,
    1, 40320, 187530840, 24046189440, 116963796250, 24046189440, 187530840, 40320, 1,
    1, 362880, 14398171200, 12025780892160, 315031400802720, 315031400802720, 12025780892160, 14398171200, 362880, 1

    Je rappelle que n part de 0 et que sur la ligne n, k va de 0 à n.

    --
    Jedaï

  15. #75
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Triangle read by rows: T(n,k) (n >= 0, 0<=k<=n) gives number of {0,1} n X n matrices with all row and column sums equal to k.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        |  0  1  2  3   4     5       6         7             8                9
    -----------------------------------------------------------------------------
      0 |  1  1  1  1   1     1       1         1             1                1
      1 |     1  2  6  24   120     720      5040         40320           362880
      2 |        1  6  90  2040   67950   3110940     187530840      14398171200
      3 |           1  24  2040  297200  68938800   24046189440   12025780892160
      4 |               1   120   67950  68938800  116963796250  315031400802720
      5 |                     1     720   3110940   24046189440  315031400802720
      6 |                             1      5040     187530840   12025780892160
      7 |                                       1         40320      14398171200
      8 |                                                     1           362880
      9 |                                                                      1                                                         1
    Edit: oups. bien vu Jedai.

  16. #76
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    C'est donc bien le nombre que j'avais annoncé.
    Si les sources sont différentes (se méfier des pompages), la probabilité pour qu'il soit exact est presque 100%.

  17. #77
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Prenons pour acquis le résultat.
    le nombre des matrices triées trouvé ne devrait jamais être inférieur à 870000000.
    Je viens de trouver une erreur grossière dans mon raisonnement.
    Je ne cherche que les matrices triées commençant par le premier élément (il n'y a pas de boucle n0), sous pretexte qu'on peut toujours supposer que c'est le premier. Mais cela suppose une permutation de colonnes préalable, et on a vu à maintes reprises qu'il ne faut pas mélanger les choses.
    Il faut donc examiner toutes les possibilités pour la première ligne et pas seulement le premier.
    J'y retourne de ce pas !

  18. #78
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Voilà, c'est fait !
    956154976 matrices à lignes triées, ce qui est parfaitement possible.
    Il a fallu sérieusement toiletter le programme pour obtenir ce résultat en 4 heures (plus de matrices, plus de recopies, tests scindés, effectués seulement à bon escient, boucles raccourcies, etc...).

  19. #79
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 362
    Points : 419
    Points
    419
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Le résultat de Fremen167 est aussi en contradiction avec ça:
    car il fixe un maximum de solutions égal à 9!*9! fois le nombre des solutions qu'il donne.
    Désolé Zanoven, j'ai eu un gros pépin avec ma bécanne, d'où mon silence...

    Pourquoi dis-tu que mon résultat est en contradiction avec le nombre total supposé de solutions ?

    J'en ai environ 5 * 10^6, multiplié "au maximum" comme tu le dis justement par 9! * 9!, soit environ 650 * 10^15, soit environ 2000 fois plus que le nombre en question.

    Cela semble confirmer ce que je pensais déjà : toutes mes solutions ne sont pas des génératrices (car même si c'est un maximum, il faudrait quand même beaucoup de lignes et de colonnes semblables pour diviser par 2000).

    L'avantage de ma solution, c'est que :
    1) je peux ajouter des contraintes (à condition de les définir), même en fin de traitement (c'est à dire quand une solution est complète) - c'est déjà le cas de ma règle 5 - les premières visaient surtout à limiter le nombre de cas à examiner.
    2) je peux pour un coût assez faible calculer le cardinal de la classe générée par ma solution (il suffit de compter les lignes "en double" horizontalement, puis, c'est un peu plus coûteux, verticalement). De cette manière, je peux ajouter les cardinaux de chaque classe et je dois obtenir à la fin le nombre magique !!
    3) je pourrais même à partir de chaque génératrice obtenir tous les éléments de la classe (mais je ne le ferai pas).

    Je vais continuer à travailler sur les contraintes car en gros, celles que j'ai définies jusqu'à présent concernent les 5 premières colonnes, et les 5 premières lignes...

  20. #80
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    J'en ai environ 5 * 10^6, multiplié "au maximum" comme tu le dis justement par 9! * 9!, soit environ 650 * 10^15, soit environ 2000 fois plus que le nombre en question.
    C'est exact, j'ai écrit le calcul correct avec un facteur 9!*9! mais en fait je n'ai multiplié qu'une seule fois ton total par 9!
    Désolé Zanoven, j'ai eu un gros pépin avec ma bécanne, d'où mon silence...
    Tu l'as fait exploser avec ton programme ?
    Pour moi obtenir le nombre magique à partir de mes solutions, c'est les ranger d'abord en deux catégories:
    Celles dont toutes les lignes sont distinctes (l'immense majorité car elles sont triées).
    Les autres ayant au moins deux lignes (nécessairement consécutives) égales.
    Pour chacune de la première catégorie j'aurai une contribution de 9! au total.
    Pour les autres c'est beaucoup plus compliqué. Il faut compter le nombre de permutations laissant un par un globalement invariants les groupes de lignes djacentes égales et après diviser 9! par le produit des nombres trouvés.
    Pour le moment, pas assez motivé pour continuer...

Discussions similaires

  1. aide pour alléger mon code simple mais long
    Par tuco_benedicto dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 13/03/2010, 21h52
  2. Demande d'aide pour concevoir un algo de routage sur un graphe.
    Par condor_01 dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 12/11/2007, 13h02
  3. Algo pour choisir des effets pour avoir un minimum d'agios
    Par taupin dans le forum Mathématiques
    Réponses: 18
    Dernier message: 21/08/2007, 21h11
  4. [TPW][cours]Demande d'aide pour finir un programme
    Par jf dans le forum Turbo Pascal
    Réponses: 21
    Dernier message: 16/06/2003, 19h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo