约束规划调度

发布于 2025-01-11 21:47:36 字数 356 浏览 0 评论 0原文

我不知道如何在 cplex 中编写这些约束。

护理机构每天每小时都需要一名保安值班。一个 24 小时日历日分为三个 8 小时班次:D(上午)、E(晚上)和 N(晚上)。 为使用 6 名警卫的护理机构制定两周的时间表,并确保 满足以下就业要求:

  1. 如果警卫在日历日工作,那么他们将在上一个和/或下一个日历日工作 日

  2. 每个警卫的作息时间是正向轮换的。也就是说,给定任意一对 警卫工作的连续日历日,允许的任务是:D D、DE、DN、EE、EN 或 N N。

3) 时间表是循环的:时间表的第 15 天是该时间表的第一天 时间表等......,所有规则适用于第 14 日到第一天的边界。

I have no idea how to write these constraints in cplex.

A care facility requires exactly one security guard on duty every hour of every day. A
24-hour calendar day is broken up into three 8 hour shifts: D(ay), E(vening) and N(ight).
Find a two week schedule for the care facility that uses 6 guards and that ensures the
following employment requirements are met:

  1. If a guard works on a calendar day, then they work on the previous and/or next
    day

  2. The schedule of every guard is forward rotating. That is, given any pair of
    consecutive calendar days that a guard works, the allowable assignments are: D
    D, D E, D N, E E, E N, or N N.

3)The schedule is cyclical: the 15th day of the schedule is the first day of the
schedule, etc…, and all rules apply across the 14th to first day boundary.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坚持沉默 2025-01-18 21:47:36

作为起点,您可以使用决策管理社区挑战2020 年 4 月

挑战是 医生规划

range days=1..7;
range weekend=5..7;
int Friday=5;
int Saturday=6;
int Sunday=7;

{string} doctors={"Fleming","Freud","Heimlich","Eustachi","Golgi"};
{string} shifts={"early","late","night"};

assert card(doctors)==5;

tuple t
{
  string doctor;
  int day;
  string shift;
}

{t} availabilities with doctor in doctors =
{<"Fleming",d,s> | d in {Friday,Saturday,Sunday},s in shifts}
union
{<"Freud",d,s> | d in days, s in {"early","late"}}
union 
{<"Heimlich",d,s> | d in days,s in shifts : !((d in weekend) && (s=="night"))}
union
{<"Eustachi",d,s> | d in days,s in shifts}
union
{<"Golgi",d,s> | d in days,s in shifts}
;

// is that doctor working that day that shift ?
dvar boolean x[doctors][days][shifts]; 


// number of shifts per doctor
dvar int nbShifts[doctors];


// minimize max-min of nbShifts
minimize 
max(d in doctors) nbShifts[d]-min(d in doctors) nbShifts[d];

// constraints
subject to
{
  // nb of shifts
  forall(d in doctors) 
  nbShifts[d]==sum(i in days,s in shifts) x[d][i][s];
  
  // a doctor can only work one shift a day
  
  forall(d in doctors,i in days) sum(s in shifts) x[d][i][s]<=1;
  
  // specific constraints per doctor
  
  forall(d in doctors,i in days,s in shifts:<d,i,s> not in availabilities)
    x[d][i][s]==0;
    
   // max 2 night shifts for Golgi
   
   sum(d in days) x["Golgi"][d]["night"]<=2;
  
  // night shift ==> next day off or next night shift
  
  forall(d in doctors,i in days:(i+1) in days)
   { 
     (x[d][i]["night"]==1) => (x[d][i+1]["early"]==0);
     (x[d][i]["night"]==1) => (x[d][i+1]["late"]==0);
  }   
  
  // periodic timetable add on
  
  forall(d in doctors)
   { 
     (x[d][Sunday]["night"]==1) => (x[d][1]["early"]==0);
     (x[d][Sunday]["night"]==1) => (x[d][1]["late"]==0);
  }   
  
  // both days of the week end or none
  
  forall(d in doctors) 
     sum(s in shifts) x[d][Saturday][s]==sum(s in shifts) x[d][Sunday][s];
  
  //  1 and only 1 doctor per shift
  
  forall(i in days,s in shifts) sum(d in doctors)  x[d][i][s]==1;
  
}


string whichDoctor[d in days][s in shifts]=
   first({doc | doc in doctors:x[doc][d][s]==1});

execute display
{
for(var d in days)
{
  write("Day ",d," : ");
  for(var s in shifts) write(whichDoctor[d][s]," ");
  writeln();
}
}

as a starting point you could use the Decision Management Community challenge April 2020

The challenge was doctor planning

range days=1..7;
range weekend=5..7;
int Friday=5;
int Saturday=6;
int Sunday=7;

{string} doctors={"Fleming","Freud","Heimlich","Eustachi","Golgi"};
{string} shifts={"early","late","night"};

assert card(doctors)==5;

tuple t
{
  string doctor;
  int day;
  string shift;
}

{t} availabilities with doctor in doctors =
{<"Fleming",d,s> | d in {Friday,Saturday,Sunday},s in shifts}
union
{<"Freud",d,s> | d in days, s in {"early","late"}}
union 
{<"Heimlich",d,s> | d in days,s in shifts : !((d in weekend) && (s=="night"))}
union
{<"Eustachi",d,s> | d in days,s in shifts}
union
{<"Golgi",d,s> | d in days,s in shifts}
;

// is that doctor working that day that shift ?
dvar boolean x[doctors][days][shifts]; 


// number of shifts per doctor
dvar int nbShifts[doctors];


// minimize max-min of nbShifts
minimize 
max(d in doctors) nbShifts[d]-min(d in doctors) nbShifts[d];

// constraints
subject to
{
  // nb of shifts
  forall(d in doctors) 
  nbShifts[d]==sum(i in days,s in shifts) x[d][i][s];
  
  // a doctor can only work one shift a day
  
  forall(d in doctors,i in days) sum(s in shifts) x[d][i][s]<=1;
  
  // specific constraints per doctor
  
  forall(d in doctors,i in days,s in shifts:<d,i,s> not in availabilities)
    x[d][i][s]==0;
    
   // max 2 night shifts for Golgi
   
   sum(d in days) x["Golgi"][d]["night"]<=2;
  
  // night shift ==> next day off or next night shift
  
  forall(d in doctors,i in days:(i+1) in days)
   { 
     (x[d][i]["night"]==1) => (x[d][i+1]["early"]==0);
     (x[d][i]["night"]==1) => (x[d][i+1]["late"]==0);
  }   
  
  // periodic timetable add on
  
  forall(d in doctors)
   { 
     (x[d][Sunday]["night"]==1) => (x[d][1]["early"]==0);
     (x[d][Sunday]["night"]==1) => (x[d][1]["late"]==0);
  }   
  
  // both days of the week end or none
  
  forall(d in doctors) 
     sum(s in shifts) x[d][Saturday][s]==sum(s in shifts) x[d][Sunday][s];
  
  //  1 and only 1 doctor per shift
  
  forall(i in days,s in shifts) sum(d in doctors)  x[d][i][s]==1;
  
}


string whichDoctor[d in days][s in shifts]=
   first({doc | doc in doctors:x[doc][d][s]==1});

execute display
{
for(var d in days)
{
  write("Day ",d," : ");
  for(var s in shifts) write(whichDoctor[d][s]," ");
  writeln();
}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文