首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >花费无限时间来满足约束并产生输出的问题

花费无限时间来满足约束并产生输出的问题
EN

Stack Overflow用户
提问于 2019-12-23 00:26:58
回答 1查看 94关注 0票数 0

我正在写一个迷你程序,为一家餐馆的员工安排日常工作。限制条件是每个工人每周只连续工作五天,并且每一天都有一个最低要求,该要求出现在下面代码的数组“minempl_perday”中。

任务是在满足上述所有限制的同时最小化受雇人员的数量。它存储在变量'nb_personnes‘中。

代码运行时没有错误,但是它无限地运行,没有任何输出。有人能帮我解决这个问题吗?

代码语言:javascript
运行
复制
include "globals.mzn";

int: n_jour = 7; 
int: maxpersonnes = 40;
var 1..maxpersonnes : nb_personnes ;

set of int: jours = 1..n_jour;
array[1..n_jour] of int: minempl_perday = [14,13,15,16,19,18,11] ;
%set of int var: personnes = 1..n_personnes;

array[1..maxpersonnes, jours] of var 0..1: planning;

% Now pad all remaining rows to 0
constraint forall(i in nb_personnes+1..maxpersonnes,j in jours)(planning[i,j]=0);

% Constraints

% Each value of every point in array can only be 1 or 0
%constraint forall(p in 1..nb_personnes, d in jours)(planning[p,d] = 1 \/ planning[p,d] = 0);

% Each employee only works 5 days a week.
%constraint forall(p in 1..nb_personnes)(forall(d in jours))(sum(planning[p][d]) = 5); 
constraint forall(p in 1..nb_personnes)(sum(d in jours)(planning[p,d]) = 5);

% Minimum number of employees respected each day
constraint forall(i in 1..n_jour )(sum(p in 1..nb_personnes)(planning[p,i]) >= minempl_perday[i]);


% Five days consecutive worked by every employee
% First day - monday
constraint forall(p in 1..nb_personnes)(if planning[p,1] = 1 /\ planning[p,7] = 0 then planning[p,2] = 1 /\ planning[p,3]= 1 /\ planning[p,4] = 1/\ planning[p,5] = 1 endif);

% First day - tuesday
constraint forall(p in 1..nb_personnes)(if planning[p,2] = 1 /\ planning[p,1] = 0 then planning[p,3] = 1 /\ planning[p,4]= 1 /\ planning[p,5] = 1/\ planning[p,6] = 1 endif);

% First day - wednesday
constraint forall(p in 1..nb_personnes)(if planning[p,3] = 1 /\ planning[p,2] = 0 then planning[p,4] = 1 /\ planning[p,5]= 1 /\ planning[p,6] = 1/\ planning[p,7] = 1 endif);

% First day - tnursday
constraint forall(p in 1..nb_personnes)(if planning[p,4] = 1 /\ planning[p,3] = 0 then planning[p,5] = 1 /\ planning[p,6]= 1 /\ planning[p,7] = 1/\ planning[p,1] = 1 endif);

% First day - friday
constraint forall(p in 1..nb_personnes)(if planning[p,5] = 1 /\ planning[p,4] = 0 then planning[p,6] = 1 /\ planning[p,7]= 1 /\ planning[p,1] = 1/\ planning[p,2] = 1 endif);

% First day - saturday
constraint forall(p in 1..nb_personnes)(if planning[p,6] = 1 /\ planning[p,5] = 0 then planning[p,7] = 1 /\ planning[p,1]= 1 /\ planning[p,2] = 1/\ planning[p,3] = 1 endif);

% First day - sunday
constraint forall(p in 1..nb_personnes)(if planning[p,7] = 1 /\ planning[p,6] = 0 then planning[p,1] = 1 /\ planning[p,2]= 1 /\ planning[p,3] = 1/\ planning[p,4] = 1 endif);


% Minimize the nb_personnes such that all the constraints of above are satisfied
solve minimize(nb_personnes);

output [show(planning[p,j])++" "++
     if j==n_jour 
       then "\n" 
       else "" 
     endif 
     |p in 1..maxpersonnes, j in jours];
EN

回答 1

Stack Overflow用户

发布于 2019-12-23 00:49:17

当使用优化(最小化或最大化)时,建议使用-a选项来查看所有中间解决方案。如果没有此选项,则仅显示最后一个最优解决方案。

如果解决方案花费的时间太长,你可以尝试不同的搜索选项,例如

代码语言:javascript
运行
复制
solve ::int_search(array1d(planning), anti_first_fail, indomain_split, complete)  minimize nb_personnes;

此外,您还可以测试使用Chuffed求解器,它可能会更快。请注意,对于此模型,您必须添加以下include行来处理集合变量:

代码语言:javascript
运行
复制
include "nosets.mzn";

然而,对于这个问题,使用MIP解算器可能更好,例如CBC。请注意,您仍然需要添加include "nosets.mzn;行。

稍后(有点离题):您的七天限制可以替换为以下内容:

代码语言:javascript
运行
复制
function int: modadd(int: n, int: s, int: m) =
  let {
     int: r = (n + s) mod m;
     int: t = if r == 0 then m else r  endif
  }
  in t;

constraint
  forall(t in 1..7) (
    forall(p in 1..nb_personnes)(
       if planning[p,t] = 1 /\ planning[p,modadd(t,-1,7)] = 0 then
         forall(a in 1..4) (
            planning[p,modadd(t,a,7)] = 1
         )
      endif
    )
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59446018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档