2012-04-12 7 views
0

Ich versuche, das beliebte Problem zu tun, das so geht.Prolog Brücke Puzzle mit unbegrenzten Menschen

Eine 4-köpfige Familie versucht nachts eine Brücke zu überqueren. Man braucht eine Taschenlampe, um die Brücke zu überqueren, und nur zwei Personen können gleichzeitig die Brücke überqueren und sich mit der Geschwindigkeit des langsameren der beiden bewegen. Vater überquert die Brücke in 1 Minute, Mutter in 2 Minuten, Kind in 5 Minuten und Oma in 10. Was ist der schnellste Weg für sie, die Brücke zu überqueren?

Außer ich muss alle möglichen Wege finden, in denen eine Familie die Brücke überqueren könnte, und die Zeit, die jeder Weg nehmen würde. Die Familie könnte jedoch eine beliebige Anzahl von Leuten darin haben.

Ich habe diesen Code, aber ich kann nicht herausfinden, warum es nicht funktioniert.

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). 

Ich versuchte dies:

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). 

mir jemand sagen könnte, warum dies nicht funktioniert?

+1

Wenn diese Hausaufgaben ist es, Ihnen zeigen, sollten Sie uns, was Sie getan haben und was ist das Problem mit Ihrer Lösung . – gusbro

+0

Nun, ich habe Probleme beim Starten des Prädikats. Es muss diese Parameter haben. 1. Der Name der Familie (wie in einer Familie Tatsache angegeben) - muss gebunden werden 2. Eine Liste der Züge, die die Familie über den Fluss nehmen würde - müssen 3. Die Zeit die Reihenfolge der Züge würde annehmen - muss ungebunden sein – user1204349

+0

Ihre Lösung scheint Probleme mit dem if-then-else Konstrukt zu haben. Klammergröße, um es zu beheben – gusbro

Antwort

1

Ich bin nicht hier eine Lösung zu geben, so dass Sie es für sich selbst arbeiten, aber hier geht einige Vorschläge:

Sie müssen nur zwei Listen halten, eine für die Menschen in der linken Seite und eine andere für diejenigen, auf der rechten Seite. Anfangs sind alle Leute auf der linken Seite (Liste).

Dann haben Sie grundsätzlich zwei Fälle:

  • , in dem Sie die letzten beiden Personen von links nach rechts bewegen
  • einem anderen, in dem Sie zwei Personen aus der linken Liste und „move“ wählen sie auf die rechte Liste, wählen Sie dann eine Person aus der resultierenden rechten Liste aus und verschieben Sie sie auf die linke Seite. An diesem Punkt können Sie eine Rekursion durchführen, um das Problem zu lösen.
  • Sobald Sie die Reise haben, zählen Sie nur die Gesamtzeit und Sie sind fertig.

[Edit: Hier geht meine Lösung builtins, wie Sie eine fast funktionierende Version haben mit]

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). 
+0

danke. könntest du mir mit der Familiensache helfen? – user1204349

+0

Vielen Dank für diese Lösung. Ich brauche das Problem, mit jeder Familie zu arbeiten, nicht nur mit dieser bestimmten Familie. Um eine Familie zu definieren, muss ich eine "Familien" -Fakten geben, wobei der erste Parameter ein Name für die Familie ist und der zweite eine Liste der Familienmitglieder ist. Jedes Familienmitglied hat die Form Name/Zeit. Zum Beispiel würden wir die Familie im ursprünglichen Beispiel mit dieser Tatsache definieren: 'Familie (Original, [Vater/1, Mutter/2, Kind/5, Oma/10]).' Ich werde versuchen, zu verstehen etwas heraus, aber das ist im Allgemeinen, wo alle meine Probleme mit der kleinen Aufgabe gewesen sind. – user1204349

+0

Es sollte einfach sein. Zum Beispiel müssten Sie in meiner Lösung eine andere Parameterfamilie erhalten und das erste Suchergebnis durch 'family (Family, Left) 'ersetzen und'/'anstelle von' -' als Paarungsbegriff für Person-Time verwenden. Beachten Sie auch, dass Sie Bridge/3 mit einem anderen Namen umbenennen müssen. – gusbro