1

Prolog で制約のあるスケジュールを実行しようとしています。スケジューリングは、2 つの制約に基づいて行われます。同一学期の科目と同一講師の科目を同一時間帯に組むことはできません。

course(ceng123,1). もちろん、コースコードと学期。

slot(monday,1). 曜日と時間。

teaches(jack,ceng123). 教師とコースコード。

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).

私が期待する答えは次のとおりです。

 ?- schedule([cse111,cse112,cse113,cse114,cse115,cse116,cse117,cse118],X).
 X = [cse111, monday, 1, cse112, monday, 2, cse113, tuesday, 1, cse114, tuesday, 2, cse115, monday, 1, cse116, monday, 2, cse117, tuesday, 1, cse118, tuesday, 2]

制約のないコードを書きました:

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).


 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     slot(Day,Slot),schedule(CourseTail,ScheduleTail).

問題はありませんが、これを試してみると;

 course(cse111,1).
 course(cse112,1).
 course(cse113,1).
 course(cse114,1).
 course(cse115,2).
 course(cse116,2).
 course(cse117,2).
 course(cse118,2).
 slot(monday,1).
 slot(monday,2).
 slot(tuesday,1).
 slot(tuesday,2).
 teaches(erkan,cse111).
 teaches(erkan,cse112).
 teaches(erkan,cse113).
 teaches(erkan,cse114).
 teaches(merkan,cse115).
 teaches(merkan,cse116).
 teaches(kan,cse117).
 teaches(kan,cse118).     

 schedule([],[]).
 schedule([Course|CourseTail],[Course,Day,Slot|ScheduleTail]):-
     schedule(CourseTail,ScheduleTail), check(Course,Day,Slot,ScheduleTail).

 check(_, _, _,[]).
 check(Course,Day,Slot,[Course2,Day2,Slot2|Tail]):- check(Course,Day,Slot,Tail),
     course(Course,Semester1),course(Course2,Semester2),Semester1=\=Semester2, 
     slot(Day,Slot),slot(Day2,Slot2).

制約を記述しようとしましたが、エラーが発生しました。

 uncaught exception: error(syntax_error('user_input:1 (char:4) . or operator expected           after expression'),read_term/3) 

間違いがわかりますか?

4

2 に答える 2

3

シングルトン変数は、プログラム内で一度だけ言及される変数です: wiki を参照してください。27行目でそれが得られますが、これはこれだと思います: check(Course,Day,Slot,[]). で置き換えることができます check(_, _, _,[])。(「_」は任意の変数を意味します。これは、変数を普遍的に数量化できることを意味します。)

エラーは発生しません。プロローグがノーと言うのは、あなたの制約が満たされないことを意味するだけです。

于 2012-12-26T18:10:37.203 に答える
0

制約を明確に定義することから始める必要があります。あなたのコメントから、私は次のことを読みました: 1 時間に 2 つのコースを同じ学期番号にすることはできず、同じ教師のコースを同じ時間に設定することはできません。

したがって、これらの要件を満たしているコースにスケジュールを割り当てることができます。これは、どの割り当てが既に発行されているかを知る必要があることを示唆しています。そのため、現在のスケジュールを維持し、要件が満たされたときにのみ新しい割り当てを追加する手順を作成できます。

したがって、空のリストでschedule/2新しいプロシージャを呼び出すプロシージャを定義することから始めます。schedule/3

schedule(Courses,Schedule):-
   schedule(Courses, [], Schedule).

ここで、このプロシージャは最初の引数にスケジュールを割り当てるコースのリストを持ち、現在の割り当てを 2 番目の引数に保持し、3 番目の引数を最終的なスケジュール (必要なデータ、つまりコース、日、スロット) と統合します。 . schedule(Course, Day, Slot)これらのデータをリストに混在させるのは得策ではないため、各割り当てを表すために構造体を使用します。

schedule([], _, []).
schedule([Course|CourseTail], Courses, [schedule(Course,Day,Slot)|ScheduleTail]):-
% Two courses in an hour cannot have same semester number and same teacher's courses will not be in same hour.
     course(Course, Semester),
     teaches(Teacher, Course),
     slot(Day, Slot),
     \+ member(s(Day, Slot, Semester, _), Courses),
     \+ member(s(Day, Slot, _, Teacher), Courses),
     schedule(CourseTail, [s(Day, Slot, Semester, Teacher)|Courses], ScheduleTail).

最初の節はベースケースです。入力リストにコースがなくなると、スケジュールは空になります。

2 番目の句は、入力リストから最初の Course を取得し、そのコースの可能な学期、Theacher、および Day/Slot を計算してから、制約が満たされているかどうかを確認します。その日/時間枠/学期のスケジュールが既にあるかどうか、およびその日/時間枠に教師の割り当てが既にあるかどうかをテストします。要件が満たされている場合は、この割り当てを現在の割り当てのリストに追加し、再帰を続行します。

戻ったら、最終的なスケジュールのリストにコース/日/スロットを追加します。

于 2012-12-27T14:19:17.320 に答える