2012-04-12 2 views
0

私はこれのような行く人気の問題をしようとしています。プロログ無限の人々とブリッジパズル

4の家族が夜間に橋を渡ろうとしています。 1つは橋を渡るために懐中電灯が必要で、2人だけが同時に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). 

誰かが私に教えてもらえますか?

私はあなたが自分自身でそれを働かせることができるので、ここに解決策を与えますが、ここではいくつかの提案を行くわけではない
+1

これは宿題であれば、あなたがやったとあなたの解決策の問題は、何が何であるかを私たちに示すべきです。 – gusbro

+0

まあ、私は述語を始めることに問題があります。これらのパラメータを持つ必要があります。 1.家族の名前(家族の事実に示されている) - 縛られている必要があります。 2.川の向こう側に家族を連れて行くことのあるリスト - 縛られていないことが必要です 3.移動の順序あなたの解決策はif-then-else構造に問題があるようです。 – user1204349

+0

ありがとうございました。 – gusbro

答えて

1

あなたはちょうど2つのリストを保持する必要があり、左側にある人々のための1ともののために別の右側にあります。当初はすべての人が左側(リスト)にいます。

その後、あなたは基本的に2例があります:あなたは2つの左のリストから人々と「移動」を選択

  • 別いる右に左から最後の2人を移動する1

    • をそれらを右のリストに追加し、結果の右のリストから1人を選択し、左側に「移動」します。この時点で、再帰を実行して問題を解決できます。
    • 旅行を済ませたら、撮影した合計時間を数えれば完了です。

    は、[編集:あなたはほとんどの作業バージョンを持っているとして、ここでは組み込みコマンドを使用して私の解決策を行く]

    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

    ありがとうございました。 家族事実の事を私に助けてくれますか? – user1204349

    +0

    その解決に大変感謝しています。 私は、この特定の家族だけでなく、家族と一緒に働くには問題が必要です。ファミリを定義するには、「ファミリ」ファクトを与える必要があります。最初のパラメータはファミリの名前で、2番目のパラメータはファミリのリストです。各家族は名前/時間の形式です。たとえば、元の例のファミリをこのファクトで定義するとします。 'family(オリジナル、[father/1、mother/2、child/5、granny/10])。 私は理解しようとします何か外に出てきましたが、これは一般的に私の小さな課題のすべての問題があった場所です。 – user1204349

    +0

    これは簡単です。例えば私のソリューションでは、別のパラメータFamilyを受け取り、最初のfindallを 'family(Family、Left)'に置き換え、 '-'の代わりに' -'をPerson-Timeのペアリング用語として使用する必要があります。また、bridge/3の名前を別の名前に変更する必要があることにも注意してください。 – gusbro