我正在swi-prolog中使用Hill Climbing算法查找路径,正在查找正确的结果,但它们都是重复的,这是不可能发生的。
爬山算法适用于关系图中已包含的图形,其思想是在棕榈树之间找到路线,在这里您有足够的水来浇灌每棵树。我已经尝试使用或而不是额外的关系,我直觉这与匿名变量有关,但我似乎找不到该错误。
% Relationships
bucket(5).
palm(sheherazade).
palm(jasmine).
palm(nina).
palm(elisa).
palmToPalm(jasmine,sheherazade,18).
palmToPalm(sheherazade,nina,12).
palmToPalm(jasmine,nina,19).
palmToPalm(elisa,nina,8).
palmToPalm(elisa,sheherazade,20).
palmToWell(jasmine,13).
palmToWell(sheherazade,19).
palmToWell(nina,22).
palmToWell(elisa,34).
palmNeeds(jasmine,2).
palmNeeds(sheherazade,1).
palmNeeds(nina,2).
palmNeeds(elisa,4).
% Initial State
initialState(palmTrees,palms(well,T,T,[sheherazade,jasmine,nina,elisa],[],X),X) :- bucket(T).
% Final State
finalState(palms(well,X,0,[],_,Y)) :- X >= Y.
% Moves
move(palms(X,_,_,[],_,_),well) :- X \= well.
move(palms(X,_,0,_,_,_),well) :- X \= well.
move(palms(well,_,_,PalmTrees,_,_),Move) :- palmToWell(Move,_), member(Move,PalmTrees).
move(palms(Palm,_,_,PalmTrees,_,_),Move) :- palmToPalm(Palm,Move,_), member(Move,PalmTrees).
move(palms(Palm,_,_,PalmTrees,_,_),Move) :- palmToPalm(Move,Palm,_), member(Move,PalmTrees).
% Update
update(palms(_,Time,Bucket,[],Watered,Given),Move,palms(Move,Time1,0,[],Watered,Given)) :- Time1 is Time + Bucket.
update(palms(M,Time,Bucket,PalmTrees,Watered,Given),Move,palms(Move,Time1,Bucket1,PalmTrees1,Watered1,Given)) :-
updateTime(Time,Time1,M,Move),
updateBucket(Bucket,Bucket1,Move),
updatePalmTrees(Move,PalmTrees,Watered,PalmTrees1,Watered1).
updateTime(Time,Time1,M,well) :- bucket(X), palmToWell(M,Y), Time1 is Time + X + Y.
updateTime(Time,Time1,well,M) :- bucket(X), palmToWell(M,Y), Time1 is Time + X + Y.
updateTime(Time,Time1,M,Move) :- palmNeeds(Move,X), (palmToPalm(M,Move,Y);palmToPalm(Move,M,Y)), Time1 is Time + X + Y.
%updateTime(Time,Time1,M,Move) :- palmNeeds(Move,X),palmToPalm(Move,M,Y),, Time1 is Time + X + Y.
%(nina,shehehrazada)
%(X,nina)
updateBucket(Bucket,Bucket1,well) :- bucket(X), Bucket1 is Bucket + X.
updateBucket(Bucket,Bucket1,Move) :- palmNeeds(Move,X), Bucket1 is Bucket - X.
updatePalmTrees(well,PalmTrees,Watered,PalmTrees,Watered).
updatePalmTrees(Move,PalmTrees,Watered,PalmTrees1,Watered1) :- select(Move,PalmTrees,PalmTrees1), insert(Move,Watered,Watered1).
select(X,[X|Xs],Xs).
select(X,[Y|Ys],[Y|Zs]) :- select(X,Ys,Zs).
insert(X,[Y|Ys],[X,Y|Ys]).
insert(X,[],[X]).
% Legal
legal(palms(_,_,Bucket,_,_,_)) :- not(ilegal(Bucket)).
ilegal(Bucket) :- Bucket < 0.
% Value
value(palms(_,_,_,[_,_,_,_],[],_),0).
value(palms(_,_,_,[_,_,_],[_],_),1).
value(palms(_,_,_,[_,_],[_,_],_),2).
value(palms(_,_,_,[_],[_,_,_],_),3).
value(palms(_,_,_,[],[_,_,_,_],_),4).
% Hill Climbing
solveHC(State,_,[]) :- finalState(State).
solveHC(State,History,[Move|Moves]) :-
hillClimb(State,Move),
update(State,Move,State1),
legal(State1),
not(member(State1,History)),
solveHC(State1,[State1|History],Moves).
hillClimb(State,Move) :-
findall(M,move(State,M),Moves),
evaluateAndOrder(Moves,State,[],MVs),
member((Move,_),MVs).
evaluateAndOrder([Move|Moves],State,MVs,OrderedMVs) :-
update(State,Move,State1),
value(State1,Value),
insertPair((Move,Value),MVs,MVs1),
evaluateAndOrder(Moves,State,MVs1,OrderedMVs).
evaluateAndOrder([],_,MVs,MVs).
insertPair(MV,[],[MV]).
insertPair((M,V),[(M1,V1)|MVs],[(M,V),(M1,V1)|MVs]) :-
V >= V1.
insertPair((M,V),[(M1,V1)|MVs],[(M1,V1)|MVs1]) :-
V < V1,insertPair((M,V),MVs,MVs1).
testHC(Problem,Moves,Time) :-
initialState(Problem,State,Time),
solveHC(State,[State],Moves).
预期结果应该是:
?- testHC(palmTrees, X, 0).
X = [elisa, sheherazade, well, nina, jasmine, well] ;
X = [elisa, sheherazade, well, jasmine, nina, well] ;
X = [nina, jasmine, sheherazade, well, elisa, well] ;
X = [nina, sheherazade, jasmine, well, elisa, well] ;
X = [sheherazade, elisa, well, nina, jasmine, well] ;
X = [sheherazade, elisa, well, jasmine, nina, well] ;
X = [sheherazade, jasmine, nina, well, elisa, well] ;
X = [sheherazade, nina, jasmine, well, elisa, well] ;
X = [jasmine, nina, sheherazade, well, elisa, well] ;
X = [jasmine, sheherazade, nina, well, elisa, well] ;
false.
当实际输出为:
?- testHC(palmTrees, X, 0).
X = [elisa, sheherazade, well, nina, jasmine, well] ;
X = [elisa, sheherazade, well, nina, jasmine, well] ;
X = [elisa, sheherazade, well, jasmine, nina, well] ;
X = [elisa, sheherazade, well, jasmine, nina, well] ;
X = [nina, jasmine, sheherazade, well, elisa, well] ;
X = [nina, jasmine, sheherazade, well, elisa, well] ;
X = [nina, sheherazade, jasmine, well, elisa, well] ;
X = [nina, sheherazade, jasmine, well, elisa, well] ;
X = [sheherazade, elisa, well, nina, jasmine, well] ;
X = [sheherazade, elisa, well, nina, jasmine, well] ;
X = [sheherazade, elisa, well, jasmine, nina, well] ;
X = [sheherazade, elisa, well, jasmine, nina, well] ;
X = [sheherazade, jasmine, nina, well, elisa, well] ;
X = [sheherazade, jasmine, nina, well, elisa, well] ;
X = [sheherazade, nina, jasmine, well, elisa, well] ;
X = [sheherazade, nina, jasmine, well, elisa, well] ;
X = [jasmine, nina, sheherazade, well, elisa, well] ;
X = [jasmine, nina, sheherazade, well, elisa, well] ;
X = [jasmine, sheherazade, nina, well, elisa, well] ;
X = [jasmine, sheherazade, nina, well, elisa, well] ;
false.