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

Prolog Discussion :

SWI prolog / Résolution nonogramme


Sujet :

Prolog

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI prolog / Résolution nonogramme
    Je souhaite ecrire un predicat solution ligne(Num,Arg2,Arg3,Arg4,Arg5,Taille) où
     Num est le numero de la ligne,
     Arg2 la liste des couples (cases) deja contruits,
     Arg3 la solution cherchee,
     Arg4 la colonne a laquelle on est arrive,
    Arg5 les contraintes restantes,
     Arg6, la taille du nonogramme.

    tel que solution ligne(Num,[],S,1,LC,Taille) avec LC et Taille donnés, donne en resultats les di fférentes listes de couples de points correspondant aux contraintes LC.
    Dans l'exemple ci-dessous, on obtient toutes les solutions possibles pour satisfaire la contrainte [2;1] sur la ligne 2 de longueur 6.

    ?- solution_ligne(2,[],S,1,[2,1],6).
    S = [ (2, 1), (2, 2), (2, 4)] ;
    S = [ (2, 1), (2, 2), (2, 5)] ;
    S = [ (2, 1), (2, 2), (2, 6)] ;
    S = [ (2, 2), (2, 3), (2, 5)] ;
    S = [ (2, 2), (2, 3), (2, 6)] ;
    S = [ (2, 3), (2, 4), (2, 6)] ;
    false.

    Quelqu'un a t'il une idée sachant que des predicats annexes sont nécessités?

  2. #2
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 12
    Points : 4
    Points
    4
    Par défaut
    [Edit] : Je supprime ma solution car tu cherche à solver tout le tp par les autres, ce n'est vraiment pas un comportement de futur ingénieur!

    ref : http://www.developpez.net/forums/d13...liste-couples/

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    @darksamus1 :
    Je ne vois pas trop l'intérêt de poster une telle solution
    -- C'est mieux de pousser les gens à chercher

    @adissa357 :
    As-tu déjà commencé par chercher un peu, il semble que ça ne soit pas si compliqué que cela ... Après comme on ne connaît pas ce que tu as défini au préalable ... le concept sera sûrement à revoir ...
    Tu dois concevoir un prédicat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    solution ligne(Ligne,Temp,Solution,Colonne,Contraintes,Taille)
    Il s'agît de générer tous les couples (Ligne,Colonne), de la colonne 1 à Taille respectant les Contraintes.

    Pourquoi ne pas utiliser un prédicat qui te créé les couples pour une seule contrainte donnée ? Ce prédicat ne retourne rien ou fail. si jamais les couples retournés débordent par rapport à la Taille ...

    Il ne te reste plus qu'à utiliser ce prédicat pour créer des solutions ... Attention toute fois, pour parcourir le plus de solutions possibles, il te faut composer les solutions respectant les contraintes pour différentes colonnes de départ.

    NB : Réfléchis à la condition de fin, elle est très simple : quand tu n'as plus de contrainte, tu retournes Temp dans Solution ...

    Cdt,

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut Prolog
    Le fruit de mes pensées


    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
    ncouple(_,Y,N,[],Y) :-
    	N == 0,!.
    ncouple(X,Y,N,[(X,Y)|L],Last) :-
    	N1 is N - 1,
    	Y1 is Y + 1,
    	ncouple(X,Y1,N1,L,Last).
     
    solution_ligne(_,Tmp,S,_,[],_) :-
    	tri(Tmp,S).
    solution_ligne(Lig,Couples,Sol,Col,[Ct|Cts],Taille) :-
    	ncouple(Lig,Col,Ct,R,Last),
    	Last =< Taille,
    	Last1 is Last + 1,
    	between(Last1,Taille,Col),
    	write(Col),nl,
    	append(R,Couples,CouplesR),
    	solution_ligne(Lig,CouplesR,Sol,Col,Cts,Taille).

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    Je suppose que ton prédicat ncouple fait référence à :
    Pourquoi ne pas utiliser un prédicat qui te créé les couples pour une seule contrainte donnée ? Ce prédicat ne retourne rien ou fail. si jamais les couples retournés débordent par rapport à la Taille ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ncouple(_,Y,N,[],Y) :-
         N == 0,!.
     
    ncouple(X,Y,N,[(X,Y)|L],Last) :-
         N1 is N - 1,
         Y1 is Y + 1,
         ncouple(X,Y1,N1,L,Last).
    Juste pour information, la valeur retournée par ta variable Last correspond normalement à : Y + N, tu n'as pas spécialement besoin d'elle ... ?
    Sinon pour ta condition d'arrêt, tu peux remplacer directement N par 0 ... ça te simplifie une ligne, et je ne suis pas certain que le "!" (cut) soit d'une grande utilité.
    Autre point qui me choque un peu, tu ne vérifie pas que N soit supérieur strictement à zéro ... si tu avais fais un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    trace,ncouple(2,5,3,S,Last).
    Tu te serai rendu compte pourquoi tu as besoin d'un cut ... tu provoque une boucle infinie qui utilise des valeurs négatives ... (C'est assez évident avec la pratique quand on réfléchie un peu et qu'on exécute ton prédicat à la main )

    Je pourrais te donner la solution, mais avec toutes les explications ci-dessus, tu vas pouvoir corriger ton prédicat.

    ---

    Pour ce morceau de code là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    solution_ligne(_,Tmp,S,_,[],_) :-
         tri(Tmp,S).
         solution_ligne(Lig,Couples,Sol,Col,[Ct|Cts],Taille) :-
         ncouple(Lig,Col,Ct,R,Last),
         Last =< Taille,
         Last1 is Last + 1,
         between(Last1,Taille,Col),
         write(Col),nl,
         append(R,Couples,CouplesR),
         solution_ligne(Lig,CouplesR,Sol,Col,Cts,Taille).
    C'est un peu "bordélique" si je peux me permettre ...
    Surtout qu'il te manque la condition d'arrêt pour ta récurrence ...

    Reprenons la définition que tu nous as donnée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    solution ligne(Ligne,Temp,Solution,Colonne,Contraintes,Taille)
    • Ligne : le numéro de ligne
    • Temp : la liste des couples en cours de création
    • Solution : la solution cherchée
    • Colonne : le numéro de colonne
    • Contraintes : les contraintes
    • Taille : la taille du nonogramme (je suppose, et à la vue de ton code, tu travailles que sur des nonogrammes "carrés" (NxN))


    La condition d'arrêt est plutôt évidente ... quand tu n'as plus de contraintes (quand ta liste de contraintes est vide), tu retournes le contenu de Temp dans Solution, et tu ne tiens pas compte des autres variables.

    Pour le code même de solution_ligne, j'utiliserai l'algorithme suivant (que j'ai peut-être mal expliqué tout à l'heure) :
    • Tirer un numéro de colonne entre Colonne et Taille
    • Générer un ncouple à partir de la colonne tirée
    • Vérifier que le bout de solution générée ne sort pas du cadre du nonogramme (ne dépasse pas taille)
    • Allez à la dernière colonne + 1 (espace blanc)
    • Ajouter le bout de solution à Temp
    • Effectuer la récurrence avec les nouvelles valeurs
    Avec toutes ces indications tu devrais, je pense t'en sortir !
    N'hésites pas si tu as d'autres question.

    Cdt,

  6. #6
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI /Nonogramme
    En effet ma variable Last me sert à rien ici dans ncouple. Mais je l'utilise dans solution_ligne.
    jai apporté des modifications à n couple qui devient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ncouple(_,Y,0,[],Y) .
    ncouple(X,Y,N,[(X,Y)|L],Last) :-
    	N1 is N - 1,
    	Y1 is Y + 1,
    	N > 0,
    	ncouple(X,Y1,N1,L,Last).
    mais j'obtiens une tonne de ligne quand je fais
    trace,ncouple(2,5,3,S,Last).
    afin de verifier son fonctionnement

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI
    Pour ce qui est de l'algo, tiré un numéro de colonne, je ne pense pas que ce soit approprié puisqu'on doit commencé par la premier colonne je pense?

  8. #8
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ncouple(_,Y,0,[],Y) .
    ncouple(X,Y,N,[(X,Y)|L],Last) :-
         N1 is N - 1,
         Y1 is Y + 1,
         N > 0,
         ncouple(X,Y1,N1,L,Last).
    Ton code est correct cette fois. Concernant le prédicat trace, il est assez repoussant à l'utilisation et il faut une bonne concentration pour le comprendre. Mais il permet toutefois de comprendre quels sont les appels effectués par prolog et les potentielles erreurs.
    Dans le cas de trace sur ton prédicat tu obtiens normalement :
    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
    ?- trace,ncouple(2,5,3,S,Last).
       Call: (8) ncouple(2, 5, 3, _G369, _G370) ? creep
       Call: (9) _G507 is 3+ -1 ? creep << Correspond au calcul de N - 1
       Exit: (9) 2 is 3+ -1 ? creep      << qui se passe très bien
       Call: (9) _G510 is 5+1 ? creep   << Correspond au calcul de Y + 1
       Exit: (9) 6 is 5+1 ? creep           << qui se passe très bien aussi
       Call: (9) 3>0 ? creep
       Exit: (9) 3>0 ? creep
       Call: (9) ncouple(2, 6, 2, _G492, _G370) ? creep << Appel récursif
       [...]
       Call: (11) ncouple(2, 8, 0, _G516, _G370) ? creep << Encore un appel récursif
       Exit: (11) ncouple(2, 8, 0, [], 8) ? creep                
     << Preuve que ton prédicat d'arrêt prend bien le relais
       Exit: (10) ncouple(2, 7, 1, [ (2, 7)], 8) ? creep
       Exit: (9) ncouple(2, 6, 2, [ (2, 6), (2, 7)], 8) ? creep
       Exit: (8) ncouple(2, 5, 3, [ (2, 5), (2, 6), (2, 7)], 8) ? creep
    << Et on remarque que la solution se construit toute seule !
    Après, pour tester ton prédicat sans forcément passer par trace qui est plutôt un outil de débug tu peux faire comme j'ai fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ?- ncouple(2,5,3,S,Last).
    Si on réfléchis : tu dois obtenir :
    (2,5),(2,6),(2,7) et la colonne suivante est 8. En testant, tu obtiens le bon résultat.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    S = [ (2, 5), (2, 6), (2, 7)],
    Last = 8
    --

    Sinon as-tu commencé à réfléchir à ton prédicat solution_ligne ?

    Cdt,

    --
    EDIT à 21h53
    Pour ce qui est de l'algo, tiré un numéro de colonne, je ne pense pas que ce soit approprié puisqu'on doit commencé par la premier colonne je pense?
    Ton prédicat doit sortir toutes les possibilités, si tu te contentes de partir tout le temps de la première tu ne trouveras pas tout le temps la/les solutions. Exemple, dans la cas ou ta ligne a pour contrainte 1 uniquement, rien ne te garanti que la case à cocher est la première ... bien au contraire, elle peut se trouver partout. Est-ce que tu comprends ?

  9. #9
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI
    le truc c'est que quand je fais ?- ncouple(2,5,3,S,Last). j'obtiens aussi toute ces lignes.
    Oui j'ai commencé et pense que la condition d'arret donnerais ceci :
    solutions_ligne(_,Temp,Solution,_,[],_) :- Solution = Temp.
    d'après les pistes que tu m'as signifié

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par adissa357 Voir le message
    le truc c'est que quand je fais ?- ncouple(2,5,3,S,Last). j'obtiens aussi toute ces lignes.
    Le mode trace peut être persistant, pour le quitter en lignes de commandes fais :
    Citation Envoyé par adissa357 Voir le message
    Oui j'ai commencé et pense que la condition d'arret donnerais ceci :
    solutions_ligne(_,Temp,Solution,_,[],_) :- Solution = Temp.
    d'après les pistes que tu m'as signifié
    Oui, la condition d'arrêt est correcte, mais tu peux encore simplifier cela, en effet, plus ton prédicat sera simple, plus il sera compréhensible ! Ton code (première ligne) peut être simplifié par le code de la troisième ligne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    solutions_ligne(_,Temp,Solution,_,[],_) :- Solution = Temp.
     
    solutions_ligne(_,Solution,Solution,_,[],_).
    Il te reste encore à déterminer le prédicat de récurrence maintenant !

    Cdt,

  11. #11
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI
    Ok, jvais voir ça

  12. #12
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI
    Plutot ceci,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,Contrainte,Taille) :-
    	ncouple(Ligne,Colonne,Contrainte,Genere,Last),
    	Last =< Taille,
    	Colonne1 is Colonne + 1,
    	append(Genere,Temp,Temp1),
    	solution_ligne(Ligne,Temp1,Solution,Colonne1,Contrainte,Taille).
    qui ressemble un peu à la derniere suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    solution_ligne(Lig,Couples,Sol,Col,[Ct|Cts],Taille) :-
    	ncouple(Lig,Col,Ct,R,Last),
    	Last =< Taille,
    	Last1 is Last + 1,
    	between(Last1,Taille,Col),
    	write(Col),nl,
    	append(R,Couples,CouplesR),
    	solution_ligne(Lig,CouplesR,Sol,Col,Cts,Taille).
    Enfin c'est ce que je pense. Qu'en pensez vous?

  13. #13
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par adissa357 Voir le message
    Plutot ceci,
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,Contrainte,Taille) :-
    ncouple(Ligne,Colonne,Contrainte,Genere,Last),
    Last =< Taille,
    Colonne1 is Colonne + 1,
    append(Genere,Temp,Temp1),
    solution_ligne(Ligne,Temp1,Solution,Colonne1,Contrainte,Taille).
    Quelques erreurs subsistent ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,Contrainte,Taille) :-
    	ncouple(Ligne,Colonne,Contrainte,Genere,Last),
    	Last =< Taille,
    	Colonne1 is Colonne + 1,     <<< (1)
    	append(Genere,Temp,Temp1),   <<< (2)
    	solution_ligne(Ligne,Temp1,Solution,Colonne1,Contrainte,Taille).

    Entre autre, ton prédicat doit s’appeler solution_ligne or tu l'appelles alternativement solutionS_ligne puis solution_ligne. Ensuite, Contrainte est une liste or ton prédicat ncouple fonctionne avec une valeur et non pas une liste.
    Petit rappel pour extraire la première valeur d'une liste :
    Permet d'isoler le premier élément de la liste dans la variable Tete et Reste est une liste qui contient les autres valeurs.

    Ensuite, la ligne que j'ai marquée par le n°1 me pause problème (la deuxième n'est qu'une question de formalisme ...). As-tu essayé ton prédicat pour voir ce qu'il te retourne (une fois corrigé les petites erreurs expliquées ci-dessus) ?

    • Comme expliqué précédemment, il faut tirer le numéro de colonne entre la dernière colonne utilisée et la taille du problème (cf. prédicat between).
      Petit exemple d'utilisation de between :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      ?- between(1,6,Val).
      Val = 1 ;
      Val = 2 ;
      Val = 3 ;
      Val = 4 ;
      Val = 5 ;
      Val = 6.
    • De ce fait, Last =< Taille n'est pas nécessaire car le prédicat between se charge de retourner des valeurs qui si celles-ci peuvent être générées
    • La nouvelle colonne est la dernière colonne utilisée (Last) + 1
    • Pour éviter d'être obligé de re-trier ta solution, le mieux reste de faire un append de ta solution actuelle avec tes couples générés et non pas dans l'ordre inverse. Mais cela n'est qu'un détail ...


    Cdt,

  14. #14
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI
    En effet, les erreurs d'appelations je les ai corrigé par la suite. Apres, pour ce qui est de contrainte, j'y travaillerai dessus de suite.
    En effet j'ai fait tourner mon programme et il me retournait ceci :
    ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character)
    ^ Exception:

  15. #15
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut
    Merci.

    Voila ce que j'ai pu modifier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,[Tete|Reste],Taille) :-
    	ncouple(Ligne,Colonne,Tete,Solution,Last),
    	Last =< Taille,
    	Colonne1 is Colonne + 1,
    	between(Colonne,Taille,Colonne1),
    	append(Solution,Temp,Temp1),
    	solutions_ligne(Ligne,Temp1,Solution,Colonne1,[Tete|Reste],Taille).
    Faut avouer que je saisi pas bien

  16. #16
    Candidat au Club
    Inscrit en
    Juin 2013
    Messages
    2
    Détails du profil
    Informations forums :
    Inscription : Juin 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Bonjour
    Je travaille sur un problème similaire et je dois écrire un predicat permettant, a chaque etape de construction des lignes, de verifi er que le nombre de cases cochees sur chaque colonne reste compatible avec les conditions imposees sur cette colonne.

    Auriez vous des idées ?

  17. #17
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par adissa357 Voir le message
    Merci.
    Voila ce que j'ai pu modifier :
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,[Tete|Reste],Taille) :-
    ncouple(Ligne,Colonne,Tete,Solution,Last),
    Last =< Taille,
    Colonne1 is Colonne + 1,
    between(Colonne,Taille,Colonne1),
    append(Solution,Temp,Temp1),
    solutions_ligne(Ligne,Temp1,Solution,Colonne1,[Tete|Reste],Taille).

    Faut avouer que je saisi pas bien
    Le problème est que vous ne faîtes pas les choses dans le bon ordre
    Regardez à nouveau l'algorithme que je vous ai proposé et qui fonctionne (je l'ai implémenté et testé) :
    • Tirer un numéro de colonne entre Colonne et Taille
    • Générer un ncouple à partir de la colonne tirée
    • Vérifier que le bout de solution générée ne sort pas du cadre du nonogramme (ne dépasse pas taille) << Grâce à la récurrence avec le prédicat between c'est vérifié
    • Allez à la dernière colonne + 1 (espace blanc)
    • Ajouter le bout de solution à Temp
    • Effectuer la récurrence avec les nouvelles valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    solutions_ligne(_,Solution,Solution,_,[],_) .
    solutions_ligne(Ligne,Temp,Solution,Colonne,[Tete|Reste],Taille) :-
    	ncouple(Ligne,Colonne,Tete,Solution,Last),
    	Last =< Taille,
    	Colonne1 is Colonne + 1,
    	between(Colonne,Taille,Colonne1),
    	append(Solution,Temp,Temp1),
    	solutions_ligne(Ligne,Temp1,Solution,Colonne1,[Tete|Reste],Taille).
    En rouge ce sont les erreurs. En orange, le conflit qui va se poser à cause du nommage similaire pour des données différentes. Trouves ci-après, une version corrigée de ton prédicat. Testé et validé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    solution_ligne(_,Solution,Solution,_,[],_).
    solution_ligne(Ligne,Temp,Solution,Colonne,[Tete|Reste],Taille) :-
    	between(Colonne,Taille,Col),
    	ncouple(Ligne,Col,Tete,S,Last),
    	append(Temp,S,Temp1),
    	Colonne1 is Last + 1,
    	solution_ligne(Ligne,Temp1,Solution,Colonne1,Reste,Taille).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ?- solution_ligne(2,[],S,1,[2,1],6).
    S = [ (2, 1), (2, 2), (2, 4)] ;
    S = [ (2, 1), (2, 2), (2, 5)] ;
    S = [ (2, 1), (2, 2), (2, 6)] ;
    S = [ (2, 2), (2, 3), (2, 5)] ;
    S = [ (2, 2), (2, 3), (2, 6)] ;
    S = [ (2, 3), (2, 4), (2, 6)] ;
    false.
     
    ?- solution_ligne(1,[],S,1,[1,2,1],6).
    S = [ (1, 1), (1, 3), (1, 4), (1, 6)] ;
    false.
    Citation Envoyé par Exploo29 Voir le message
    Bonjour
    Je travaille sur un problème similaire et je dois écrire un predicat permettant, a chaque etape de construction des lignes, de verifi er que le nombre de cases cochees sur chaque colonne reste compatible avec les conditions imposees sur cette colonne.

    Auriez vous des idées ?
    Je serai fortement tenté par sortir la contrainte associée pour chaque colonne à partir de la solution générée et de la comparer à la contrainte de départ. Pour cela, il te faut définir deux notions qui me paraissent importantes :
    • Compatibilité de deux contraintes
    • Égalité de deux contraintes


    Deux contraintes sont compatibles si le nombre de cases cochées par la solution est inférieur au nombre de cases cochées par la contrainte. Si jamais ce nombre est égal, il faut vérifier leur disposition ... Un petit exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    [2] est compatible avec [2,1]
    * [2] => 2 cases cochées
    * [2,1] => 3 cases cochées
     
    [1,2] n'est pas compatible avec [2,1]
    * [1,2] et [2,1] => 3 cases cochées,
    mais disposition différente
    À ta place je définirai les prédicats suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    nombre_cases_cochees(Contraintes,Solution) :-
         nombre_cases_cochees(Contraintes,0,Solution).
    << Remarque :
    << Voir s'il est plus judicieux de compter le nombre de cases cochées ou 
    << le nombre de cases cochées + les cases "bloquées" (cases de séparation)
    nombre_cases_cochees(Contraintes,Compteur,Solution)
    egalite(ContraintesAverifier,ContraintesReference)
    compatible(ContraintesAverifier,ContraintesReference)
    Avec ces deux prédicats, tu pourras répondre à ta question !

    Cdt,

    --
    EDIT de 16h25 :
    En effet, les erreurs d'appelations je les ai corrigé par la suite. Apres, pour ce qui est de contrainte, j'y travaillerai dessus de suite.
    En effet j'ai fait tourner mon programme et il me retournait ceci :
    ERROR: '.'/2: Type error: `[]' expected, found `1' ("x" must hold one character)
    ^ Exception:
    C'est une erreur tout à fait normale, vous demandiez à votre prédicat ncouple qui à besoin d'une valeur unique de répondre avec une liste de valeurs ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ncouple(X,Y,N,[(X,Y)|L],Last)
    N = le nombre de valeurs à générer (un des indices d'une contrainte et non pas la contrainte entière)

  18. #18
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut SWI..
    En effet je l'ai testé. Dire que j'étais pas loin de la solution merci.

  19. #19
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 144
    Points : 83
    Points
    83
    Par défaut
    À ta place je définirai les prédicats suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    nombre_cases_cochees(Contraintes,Solution) :-
         nombre_cases_cochees(Contraintes,0,Solution).
    << Remarque :
    << Voir s'il est plus judicieux de compter le nombre de cases cochées ou 
    << le nombre de cases cochées + les cases "bloquées" (cases de séparation)
    nombre_cases_cochees(Contraintes,Compteur,Solution)
    egalite(ContraintesAverifier,ContraintesReference)
    compatible(ContraintesAverifier,ContraintesReference)
    Avec ces deux prédicats, tu pourras répondre à ta question !

    Là, je vois plutot, 3 predicats moi
    Et je comprends pas trop du coup
    Cdt,

  20. #20
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Juin 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 10
    Points : 20
    Points
    20
    Par défaut
    De rien, je suppose que vous aurez besoin aussi de répondre à la même question que @Exploo29 ensuite.

    Petits conseils pour tes prochains prédicats :
    • Fais attention à ne pas mélanger tes variables (cf. post précédent)
    • Poses tes algorithmes avant de les développer. N'hésites pas non plus à les exécuter à la main avant.
    • Il existe plusieurs solutions, après à toi de regarder celle qui te paraît la plus accessible. On te demandera aussi de mettre en place des algorithmes plus efficaces ... il faudra voir s'il est possible de les améliorer.


    Quelques petites notions sur l'utilisation des listes et de gestion de variables peuvent t'apporter un plus.

    Cdt,

    --
    EDIT de 16h40 :
    Là, je vois plutot, 3 predicats moi
    Et je comprends pas trop du coup
    Cdt,
    En effet, petite erreur de ma part dans l'édition de mon post. Il faut voir là trois prédicats, j'ai ajouté le prédicat nombre_cases_cochees(...) comme indication pour vous mettre sur la voie.

    Si j'essaie d'expliquer plus clairement le raisonnement auquel j'ai pensé, je dirai :

    Ton prédicat solution_ligne(...) génère la solution pour une ligne. La solution finale est la concaténation des solutions pour toutes les lignes. Tu souhaites vérifier que cette concaténation progressive colle bien avec tes contraintes de départ.

    Pour cela, je te propose d'extraire la contrainte qui a générée la colonne par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SolutionAverifier = [(1,1),(1,3),(2,1),(2,2),(4,1)].
    La solution pour la colonne numéro 1 est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SolutionColonne1 = [(1,1),(2,1),(4,1)].
    Si on en déduit la contrainte associée à cette colonne tu dois obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ContrainteAssociee = [2,1]
    Il ne te reste plus ensuite au travers des prédicats nombre_cases_cochees(),egalite() et compatible de t'assurer que cette contrainte associée correspond à la contrainte de départ.

    Comprends-tu ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Swi-Prolog][Xpce] Alignement négatif
    Par je®ome dans le forum Prolog
    Réponses: 4
    Dernier message: 12/03/2007, 13h37
  2. Réponses: 1
    Dernier message: 09/01/2007, 14h33
  3. Le mode debug de swi-prolog
    Par Boubou Balrog dans le forum Prolog
    Réponses: 2
    Dernier message: 18/12/2006, 10h55
  4. Désactiver les warnings en swi-prolog
    Par Cecilka dans le forum Prolog
    Réponses: 2
    Dernier message: 15/12/2006, 11h33
  5. Réponses: 3
    Dernier message: 03/05/2006, 15h30

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