Minizinc:这种约束可能吗?

时间:2014-11-20 09:36:31

标签: constraints constraint-programming check-constraints minizinc

我想弄清楚如何写这个约束:我有一个考试列表,每个考试都有一个持续时间;最后的输出是显示一个真正的时间表,列中有可用的小时数,早上四点和下午四点,午餐时间两小时不可用。所以,让我做这非常清楚,如果我有两门考试并且每门考试都有指定的持续时间,我想在时间表中显示与考试时间相关的考试编号,因为我的变量是考试。

例如:我有两个考试,第一个考试需要一个小时,第二个考试需要三个小时

int: Exams;
array[1..Exams] of int: Exams_duration;


int: Slotstime;         % number of slots
int: Rooms;             % number of rooms
array[1..Slotstime,1..Rooms] of var 0..Exams: Timetable_exams;

%Data

Exams=2;
Exam_duration=[1,3];
Slotstime=4;            

我想要输出:[1,2,2,2]而不是[0,0,0,4](垂直模式下) Minizinc有可能做到吗? 第二个输出的代码是:

constraint forall (p in 1..Rooms)                 
( 
  sum (s in 1..Slotstime) (Timetable_exams[s,p]) 
  = sum (f in 1..Exams)(Exams_duration[f])
);

提前致谢

1 个答案:

答案 0 :(得分:2)

(嗨,这个问题比原来的问题更容易回答,因为它更加重要。)

这是一个使用两个额外的决策变量数组的版本:" ExamsRoom"处理考试房间的分配,以及" ExamsStart"考试的开始时间。也许这些并不是必需的,但它们更容易说明考试持续时间的限制;房间和时间的分配也更清楚地显示出来。它们可能对添加进一步的约束也很有用。

我还添加了参数" Rooms = 2"因为你的例子中缺少它。

int: Exams;
array[1..Exams] of int: Exams_duration;

int: Slotstime;         % number of slots
int: Rooms;             % number of rooms
array[1..Slotstime,1..Rooms] of var 0..Exams: Timetable_exams;

array[1..Exams] of var 1..Rooms: ExamsRoom; % new
array[1..Exams] of var 1..Slotstime: ExamsStart; % new

solve satisfy;
% solve :: int_search(x, first_fail, indomain_min, complete) satisfy;

constraint

  % hakank's version

  % for each exam
  forall(e in 1..Exams) (
    % find a room
    exists(r in 1..Rooms) (
       % assign the room to the exam
       ExamsRoom[e] = r /\
       % assign the exam to the slot times and room in the timetable
       forall(t in 0..Exams_duration[e]-1) (
          Timetable_exams[t+ExamsStart[e],r] = e
       )
    ) 
  ) 

  /\ % ensure that we have the correct number of exam slots
  sum(Exams_duration) = sum([bool2int(Timetable_exams[t,r]>0) | t in 1..Slotstime, r in 1..Rooms])
 ;

output [
  if r = 1 then "\n" else " " endif ++ 
     show(Timetable_exams[t,r])
  | t in 1..Slotstime, r in 1..Rooms
 ]
 ++
 [
   "\nExamsRoom: ", show(ExamsRoom), "\n",
   "ExamsStart: ", show(ExamsStart), "\n",
 ]
 ;

 %
 % Data
 %
 Exams=2;
 Exams_duration=[1,3];
 Slotstime=4;            

 % was not defined
 Rooms = 2;

该模型有20种不同的解决方案,前两种(使用Gecode作为求解器)是

2 0
2 0
2 0
1 0
ExamsRoom: [1, 1]
ExamsStart: [4, 1]
----------

2 1
2 0
2 0
0 0
ExamsRoom: [2, 1]
ExamsStart: [1, 1]
----------

第一个解决方案意味着考试1从1号房间的时间4开始,考试2从时间1开始,也在1号房间开始。第2个解决方案对考试2具有相同的作业,但将考试1设置为2号房间(在时间1)。

希望这有助于您进一步了解该模型。

/ hakank