Bridge-Flashlight Prolog 中的谜题
Bridge-Flashlight Puzzle in Prolog
在我陈述之前,我逻辑上理解这个问题的解决方案,只是很难编码。一家四口试图在晚上过桥。过桥需要打着手电筒,同时只能有两个人过桥,以两人中较慢的人的速度行进。父亲在 1 分钟内过桥,母亲在 2 分钟内过桥,Child 在 5 分钟内过桥,奶奶在 10 分钟内过桥。我正在尝试编写一个 Prolog 程序来处理此类问题,但对于任何规模的家庭来说,任何速度。总穿越时间必须小于最大指定时间。我们以事实形式 family(Name,[X1/T1,X2/T2...etc])
给出了家庭。我们被要求定义一个谓词 MoveFamily(FamilyName, MAxTime, Moves, Time)
,其中 familyName
和 Max time
是绑定变量,移动绑定到从一侧到另一侧穿过每个人所采取的移动,时间绑定到它的总时间需要。这是我目前所拥有的:
moveSouth(North,South,Moves,Time):-
member(X/T1,North), % x is a member of the north list
member(Y/T2,North), %y is a member of the north list
X \= Y,
Big is max(T1,T2),
select(X/T1, North, List2), %List2 is North with x removed
select(Y/T2, List2, NewNorth), %newNorth is north with x and y removed
New is Time+Big, %new time is old time plus maximum time
moveNorth(NewNorth, [X/T1,Y/T2|South], [X+Y|Moves], New).
moveNorth([],_,[],_,_). %this will be the last move
moveNorth(North,South,Moves,Time):-
member(X/T1,South),
select(X/T1, South, NewSouth),
New is Time + T1,
moveSouth([X/T1|North], NewSouth, [X|Moves], New).
getList(Name,List):-
family(Name,List).
moveFamily(Name, Max, Moves, Time):-
getList(Name,People),
Time =< Max,
moveSouth(People, [], Moves, Time).
family(two, [fred/1, george/2]).
当我运行这个就事实family(two, [fred/1, george/2])
。
我得到:
[debug] ?- moveFamily(two,20,Moves,Time).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [9] _10170=<20
ERROR: [8] moveFamily(two,20,_10200,_10202)
ERROR: [7] <user>
Exception: (9) _9500=<20 ? creep
Exception: (8) moveFamily(two, 20, _9498, _9500) ? creep
有谁知道为什么这不起作用?
编辑:一次穿过两个时,它们以较慢成员的速度移动
edit2:家庭 "Two" 是 family(two, [fred/1, george/2])
。
edit3:查询 moveFamily(two,20,Moves,Time)
的期望输出应该是
Moves = [fred+george],
Time = 2
edit4:我把家庭事实放在了代码块中,我是个傻瓜,应该意识到这就是你的意思哈哈
一夜之间出现了一些奇怪的评论。
这似乎有效:
moveFamily(Name,Max,Moves,Time) :-
getList(Name,People),
moveSouth(People,[],Moves,Time),
Time =< Max.
getList(Name,List) :-
family(Name,List).
moveSouth(North,South,[X+Y|Moves],New) :-
member(X/T1,North), member(Y/T2,North), X \= Y,
Big is max(T1,T2),
select(X/T1,North,List2), select(Y/T2,List2,NewNorth),
moveNorth(NewNorth,[X/T1,Y/T2|South],Moves,Time), New is Time + Big.
moveSouth([],_,[],0).
moveNorth(North,South,[X|Moves],New) :-
member(X/T1,South), select(X/T1,South,NewSouth),
moveSouth([X/T1|North],NewSouth,Moves,Time), New is Time + T1.
moveNorth([],_,[],0).
添加:当你在递归调用的参数#3 中说 [X|Moves]
时,这意味着你正在从调用中分离出 return 值,但你想要做的是添加 X
,当你把它放在子句的头部时会发生什么。
在我陈述之前,我逻辑上理解这个问题的解决方案,只是很难编码。一家四口试图在晚上过桥。过桥需要打着手电筒,同时只能有两个人过桥,以两人中较慢的人的速度行进。父亲在 1 分钟内过桥,母亲在 2 分钟内过桥,Child 在 5 分钟内过桥,奶奶在 10 分钟内过桥。我正在尝试编写一个 Prolog 程序来处理此类问题,但对于任何规模的家庭来说,任何速度。总穿越时间必须小于最大指定时间。我们以事实形式 family(Name,[X1/T1,X2/T2...etc])
给出了家庭。我们被要求定义一个谓词 MoveFamily(FamilyName, MAxTime, Moves, Time)
,其中 familyName
和 Max time
是绑定变量,移动绑定到从一侧到另一侧穿过每个人所采取的移动,时间绑定到它的总时间需要。这是我目前所拥有的:
moveSouth(North,South,Moves,Time):-
member(X/T1,North), % x is a member of the north list
member(Y/T2,North), %y is a member of the north list
X \= Y,
Big is max(T1,T2),
select(X/T1, North, List2), %List2 is North with x removed
select(Y/T2, List2, NewNorth), %newNorth is north with x and y removed
New is Time+Big, %new time is old time plus maximum time
moveNorth(NewNorth, [X/T1,Y/T2|South], [X+Y|Moves], New).
moveNorth([],_,[],_,_). %this will be the last move
moveNorth(North,South,Moves,Time):-
member(X/T1,South),
select(X/T1, South, NewSouth),
New is Time + T1,
moveSouth([X/T1|North], NewSouth, [X|Moves], New).
getList(Name,List):-
family(Name,List).
moveFamily(Name, Max, Moves, Time):-
getList(Name,People),
Time =< Max,
moveSouth(People, [], Moves, Time).
family(two, [fred/1, george/2]).
当我运行这个就事实family(two, [fred/1, george/2])
。
我得到:
[debug] ?- moveFamily(two,20,Moves,Time).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [9] _10170=<20
ERROR: [8] moveFamily(two,20,_10200,_10202)
ERROR: [7] <user>
Exception: (9) _9500=<20 ? creep
Exception: (8) moveFamily(two, 20, _9498, _9500) ? creep
有谁知道为什么这不起作用?
编辑:一次穿过两个时,它们以较慢成员的速度移动
edit2:家庭 "Two" 是 family(two, [fred/1, george/2])
。
edit3:查询 moveFamily(two,20,Moves,Time)
的期望输出应该是
Moves = [fred+george],
Time = 2
edit4:我把家庭事实放在了代码块中,我是个傻瓜,应该意识到这就是你的意思哈哈
一夜之间出现了一些奇怪的评论。
这似乎有效:
moveFamily(Name,Max,Moves,Time) :-
getList(Name,People),
moveSouth(People,[],Moves,Time),
Time =< Max.
getList(Name,List) :-
family(Name,List).
moveSouth(North,South,[X+Y|Moves],New) :-
member(X/T1,North), member(Y/T2,North), X \= Y,
Big is max(T1,T2),
select(X/T1,North,List2), select(Y/T2,List2,NewNorth),
moveNorth(NewNorth,[X/T1,Y/T2|South],Moves,Time), New is Time + Big.
moveSouth([],_,[],0).
moveNorth(North,South,[X|Moves],New) :-
member(X/T1,South), select(X/T1,South,NewSouth),
moveSouth([X/T1|North],NewSouth,Moves,Time), New is Time + T1.
moveNorth([],_,[],0).
添加:当你在递归调用的参数#3 中说 [X|Moves]
时,这意味着你正在从调用中分离出 return 值,但你想要做的是添加 X
,当你把它放在子句的头部时会发生什么。