3壶问题难度输出的好方法

时间:2019-04-14 20:23:56

标签: prolog water-jug-problem

我已经更改了一些现有代码,但是输出不是我想要得到的。

% initialisation de la recherche
etat_initial([bidon(3,0), bidon(5,0), bidon(8,8)]).

% etat de réussite
etat_final([bidon(3,0), bidon(5,4), bidon(8,4)]).

% Prédicat transfert(+bidon(CX, VX), +bidon(CY, VY), -bidon(CX,VX1),-bidon(CY,VY1))
transfert(bidon(CX, VX), bidon(CY, VY), bidon(CX,VX1),bidon(CY,VY1)) :-
    VX > 0,
    VY < CY,
    DeltaV is CY-VY,
    Verse is min(DeltaV, VX),
    VX1 is VX - Verse,
    VY1 is VY + Verse.

% prédicat un_etat_suivant(+N, -NN)
% N est un noeud dont on veut calculer un voisin
% NN est un noeud voisin de N 
un_etat_suivant(N, NN) :-
    select(B1, N, N1),
    select(B2, N1, N2),
    transfert(B1, B2,B3,B4),
    sort([B3,B4|N2], NN).

% Prédicat etat_suivant(+N, -LN)
% N est le noeud dont on veut connaître "les voisins"
% LN est la liste des états voisins au noeud N
etats_suivants(N, LN) :-
      setof(NN, un_etat_suivant(N, NN), LN).

jarres:-

    etat_initial(Init),
    etape_suivante([[Init]], S),
    %afficher(S,Y).
    write(S),nl.

% Predicat afficher(X,Y)
% X est la liste chemin plus court
% Y est le numero de la jarres

%afficher(S,Y) :-


% Prédicat etape_suivante(+X, -S)
% X est la liste des chemins déjà parcourus
% Y est a liste des nouveaux chemins après une recherche d'un niveau supplémentaire de profondeur
etape_suivante(X, S) :-
    calcule_etape_suivante(X, Y) ,
    (   (   recherche_terminee(Y, R), reverse(R, S))
        ;
           etape_suivante(Y, S)
    ).

recherche_terminee(Y,R) :-
    sublist(noeud_terminal_atteint, Y, [R |_]).

% Prédicat noeud_terminal_atteint(+Chemin)  
% Chemin est une liste d'etats et on regarde le premier pour savoir 
% s'il est "terminal"
noeud_terminal_atteint([Final|_]):-
    etat_final(Final).

% prédicat calcule_etape_suivante(+X, -Y)
% X est la liste des chemins déjà parcoururs
% Y est la nouvelle liste de chemins obtenue à partir de X en 
% ajoutant un niveau supplémentaire

% Lorsque la liste est vide, on unifie le resultat avec la liste vide
% (construction en retour de récursivité)
calcule_etape_suivante([], []).

% On calcule ici la liste des nouveaux chemins issus du premier chemin de la liste
calcule_etape_suivante([H|T], X) :-
    % etape 1 : on calcule la liste des nouveaux chemins pour la liste restante
    % (on a oté le premier chemin)
    calcule_etape_suivante(T, X1),
    % On calcule la liste des nouveaux chemins issus de H
    etape_suivante_un_chemin(H, X2),
    % On concatène la liste des nouveaux chemins issus de X avec ceux déjà obtenus
    % par les appels précédents à calcule_etape_suivante
    append(X2,X1,X).

% Prédicat etape_suivante_un_chemin(+T, -X)
% T est un chemin déjà parcouru, on ne s'intéresse qu'à son premier noeud
% X est la liste de tous les chemins obtenus à partir de T en ajoutant à chaque
% fois un noeud adjacent au premier noeud de T.
etape_suivante_un_chemin([N | L] , X) :-
    etats_suivants(N, LN),
    ajoute(LN,[N| L], X).

% Prédicat ajoute(+LN, +C, -X)
% LN est la liste des noeuds ajacents au premier noeud de C
% C est un chemin 
% X est la liste des chemins obtenus en ajoutant un élément de LN en tête de C
% on ajoute les nouveaux noeuds au chemin
% dont ils sont issus, à condition qu'ils n'y figurent pas déjà.
ajoute([], _, []).

ajoute([H|T], L, [[H | L] | X]) :-
    \+memberchk(H, L), !,
    ajoute(T, L, X).

ajoute([_|T], L, X) :-
    ajoute(T, L, X).

当前输出

?- jarres.
[[bidon(3,0),bidon(5,0),bidon(8,8)],[bidon(3,0),bidon(5,5),bidon(8,3)],[bidon(3,3),bidon(5,2),bidon(8,3)],[bidon(3,0),bidon(5,2),bidon(8,6)],[bidon(3,2),bidon(5,0),bidon(8,6)],[bidon(3,2),bidon(5,5),bidon(8,1)],[bidon(3,3),bidon(5,4),bidon(8,1)],[bidon(3,0),bidon(5,4),bidon(8,4)]]
true 

那是正确的路径,但是我需要这个:

?- jarres.
1 -> 2
2 -> 3
3 -> 1
2 -> 3
1 -> 2
2 -> 3
3 -> 1
true.

其中

1 is the 8 jug
2 its 5 jug    
and 3 its the 3 jug

0 个答案:

没有答案