2

我正在尝试解决这样的流行问题。

一家四口试图在夜间过桥。一个人过桥需要一个手电筒,而且只有两个人可以同时过桥,以两个人中较慢的速度移动。爸爸1分钟过桥,妈妈2分钟,孩子5分钟,奶奶10分钟。他们过桥最快的方法是什么?

除了我必须找到一个家庭可以过桥的所有可能方式,以及每种方式所需的时间。不过,这个家庭可以有任何数量的人。

我有这段代码,但我不知道为什么不起作用。

cross(Max, Plan):-
touristList(Ts),
Ts = [Single] -> time(Single, Time),
Time =< Max,
Plan = [[Single]];
solve_left(s(Ts,[]),Max,Plan,[]).

touristList([t1,t2,t3,t4]).

time(t1,6).
time(t2,7).
time(t3,10).
time(t4,15).

member_rest(E,[E|Es],Es).
member_rest(M,[E|Es],[E|Rest]):-
    member_rest(M,Es,Rest).

solve_left(s(Lefts0,Rights0),Time0,Plan0,Plan):-
    member_rest(T1,Lefts0,Lefts1),
    member_rest(T2,Lefts1,Lefts2),
    time(T1,TT1),
    time(T2,TT2),
    Time1 is Time0 - max(TT1,TT2),
    Time1 >= 0,
    Plan0 = [[T1,T2]|Rest],
    solve_right(s(Lefts2,[T1,T2|Rights0]),Time1,Rest,Plan).


solve_right(s(Lefts0,Rights0),Time0,Plan0,Plan):-
    Lefts0 == [] -> Plan0 = Plan;
    member_rest(T,Rights0,Rights1),
    time(T,TT),
    Time1 is Time0 - TT,
    Time1 >= 0,
    Plan0 = [[T]|Rest],
    solve_left(s([T|Lefts0],Rights1),Time1,Rest,Plan).

我试过这个:

    ruleMaker(Name) :-
    family(Name,[Title/Speed|_]),
    person(Title,Speed).

moveFamily(Name,Journey, TotalTime):-
  ruleMaker(Name),
  findall(Person-Time, person(Person, Time), Left),
  moveFamily(Left, [], Journey),
  findall(Time, member([Time|_], Journey), LTime),
  sumlist(LTime, TotalTime).

有人可以告诉我为什么这不起作用吗?

4

1 回答 1

2

我在这里没有给出解决方案,因此您可以自己解决,但这里有一些建议:

你只需要保存两个列表,一个用于左侧的人,另一个用于右侧的人。最初所有人都在左侧(列表)。

那么你基本上有两种情况:

  • 将最后两个人从左向右移动的一种
  • 另一种是从左侧列表中选择两个人并将他们“移动”到右侧列表中,然后从生成的右侧列表中选择一个人并将其“移动”到左侧。此时你可以做一个递归来解决问题。
  • 完成旅程后,您只需计算所花费的总时间即可。

[编辑:这是我使用内置的解决方案,因为你有一个几乎可以工作的版本]

person(father, 1).
person(mother, 2).
person(child, 5).
person(granny, 1).

bridge(Journey, TotalTime):-
  findall(Person-Time, person(Person, Time), Left),
  bridge(Left, [], Journey),
  findall(Time, member([Time|_], Journey), LTime),
  sumlist(LTime, TotalTime).

bridge([P1-T1, P2-T2], _, [[T, [P1-P2]]]):-
  T is max(T1, T2).
bridge(Left, Right, [[LT, [P1-P2]],[RT, [P3]]|Journey]):-
  select(P1-T1, Left, MLeft1),
  select(P2-T2, MLeft1, MLeft2),
  LT is max(T1, T2),
  select(P3-RT, [P1-T1,P2-T2|Right], MRight),
  bridge([P3-RT|MLeft2], MRight, Journey).
于 2012-04-12T21:25:56.380 回答