60 likes | 214 Views
「嫉妬深い夫の問題」の解説 (前半). 情報理工学部 白井英俊. 嫉妬深い夫の問題 ( 3組版). ある洪水で、 3 組 の夫婦が水に囲まれてしまった。彼らは、その状態からボートで脱出しなければならないが、ボートには一度に 二人 しか乗ることができない。どの夫も嫉妬深く、彼自身が一緒にいない限り、ボートでも岸でも妻が他の夫といることを許さない。この 3 組の夫婦を脱出させる方法を求めよ」 状態表現として jealousy( ボートの位置、左の岸にいる男と女のリスト、右の岸にいる男と女のリスト) を使う. 状態表現. 状態表現の方法によって問題の難易度が変わる!.
E N D
「嫉妬深い夫の問題」の解説(前半) 情報理工学部 白井英俊
嫉妬深い夫の問題(3組版) • ある洪水で、3組の夫婦が水に囲まれてしまった。彼らは、その状態からボートで脱出しなければならないが、ボートには一度に二人しか乗ることができない。どの夫も嫉妬深く、彼自身が一緒にいない限り、ボートでも岸でも妻が他の夫といることを許さない。この3組の夫婦を脱出させる方法を求めよ」 • 状態表現として jealousy(ボートの位置、左の岸にいる男と女のリスト、右の岸にいる男と女のリスト) を使う
状態表現 状態表現の方法によって問題の難易度が変わる! • 夫も妻も1,2,3,...という数で表す • ただし、これではどっちが夫でどちらが妻か分からなくなるので、 「状態表現」では(「ボートに乗る人達のリスト」 においても)男と女とを分けて書いておく • 岸にいる人達を [M, W] で表すとする ここでMは男たちのリスト、Wは女たちのリスト すると、初期状態と最終状態は: initial_state(jealousy, jealousy(left,[1,2,3],[1,2,3],[ ],[ ])). final_state(jealousy(right,[ ],[ ],[1,2,3],[1,2,3])).
指し手 • ボートで移動する人達も、状態表現と同様に [M, W] で表すとする (ここでMは男たちのリスト、Wは女たちのリスト) • すると、2人乗りの場合、可能な指し手(移動)は次のように表される: (誰が移動するかはここでは指定せず、『状態更新』のところで行うー指定しても構わないが二重手間になる) • 夫だけ移動 move(jealousy(_,LM,LW,RM,RW),[[X,Y], []]). move(jealousy(_,LM,LW,RM,RW),[[X], []]). • 妻だけ移動 move(jealousy(_,LM,LW,RM,RW),[[], [X,Y]]). move(jealousy(_,LM,LW,RM,RW),[[], [X]]). • 夫婦が移動 move(jealousy(_,LM,LW,RM,RW),[[X], [X]]).
状態の更新 • 乗る人を選ぶために、select/3, select2/3を用いる select(A,[a,b,c],X) は、[a,b,c]の中の要素の一つと Aが単一化し、残りのリストの要素からなるリストとXが単一化する: 要するに、第2引数のリストから要素を一つ選び出す。残った要素のリストが第3引数 select2([A,B],[a,b,c],X) は、[a,b,c]の中の要素2つがそれぞれ AとBに単一化し、残りの要素からなるリストがXとなる:要するに、第2引数のリストの中から二つ選び出し、残った要素のリストが第3引数 • update/3の確認:第1引数は元の状態、第2引数は指し手、第3引数は交信された状態 select2という組み込み述語はないので、このような述語を作る!
状態の更新(続) 左岸からの移動。右岸からの移動も同様 update(jealousy(left,LH,LW,RH,RW), [[X,Y], [ ]], jealousy(right,NewLH,LW,NewRH,RW)) :- select2([X,Y],LH,NewLH), sort([X,Y|RH],NewRH). update(jealousy(left,LH,LW,RH,RW), [[X], [ ]], jealousy(right,NewLH,LW,NewRH,RW)) :- select(X,LH,NewLH), sort([X|RH],NewRH). update(jealousy(left,LH,LW,RH,RW), [[ ], [X,Y]], jealousy(right,LH,NewLW,RH,NewRW)) :- select2([X,Y],LW,NewLW) , sort([X,Y|RW],NewRW). update(jealousy(left,LH,LW,RH,RW), [[ ], [X]], jealousy(right, LH, NewLW, RH, NewRW)) :- select(X,LW,NewLW), sort([X|RW],NewRW). update(jealousy(left,LH,LW,RH,RW), [[X], [X]], jealousy(right,NewLH,NewLW,NewRH,NewRW)) :- select(X,LW,NewLW), select(X,LH,NewLH), sort([X|RH],NewRH), sort([X|RW],NewRW).