我想安排商店的工作人员,并最大化一周中每天的生产率变量。该生产率var计算为一天的目标预算除以该天的工作小时数。
我的MiniZinc模型如下。
使用“解决满意”方法是可行的,但并不能根据目标预算优化工时或人事(工作人员)数。例如,当目标Bugget较小时,我希望有更少的时间。
“解决最大生产率”问题不起作用,因为它是一个数组。
有什么主意吗?
include "globals.mzn";
% Week in year
int: Week = 41;
% Days in week
enum Days = {Mo, Tu, We, Th, Fr, Sa, Su};
% Employees
enum Employees = {E01, E02, E03, E04, E05, E06, E07, E08, E20, E21, E22, E23};
% Week contracts in hour
array[Employees] of int: Contracts = [35, 35, 35, 35, 35, 35, 24, 24, 37, 40, 40, 40];
% Budget
array[Days] of int: Budget = [3500, 2500, 5000, 3500, 6000, 20000, 10000];
% Work hours
array[Employees, Days] of var 0..10: Work;
% Personnel effort
array[Days] of var int: Personnel_effort;
% Hour effort
array[Days] of var int: Hour_effort;
% Productivity
array[Days] of var int: Productivity;
% ===============================
% Constraints for the employees
% E01 can't work on We
% E01 work either on Sa or Su depending on Week odd or even
constraint forall (d in Days) (
if d in {We} then Work[E01, d] = 0 endif
/\
if Week mod 2 = 0 then Work[E01, Su] = 0
else Work[E01, Sa] = 0 endif
);
% E02 can't work on Sa
constraint forall (d in Days) (
if d in {Sa} then Work[E02, d] = 0 endif
);
% E07 can't work on Tu, Wed, Th and Fr
constraint forall (d in Days) (
if d in {Tu, We, Th, Fr} then Work[E07, d] = 0 endif
);
% E08 can't work on Mo, Tu, Wed and Th
constraint forall (d in Days) (
if d in {Tu, We, Th, Fr} then Work[E08, d] = 0 endif
);
% For all employees minimum amount of hours by day is 7
% If employees are not off
constraint forall (e in Employees, d in Days) (
if Work[e, d] != 0 then Work[e, d] >= 7 endif
);
% Employees with a Contract >= 35 must have exactly 2 days off
constraint forall (e in Employees) (
if Contracts[e] >= 35 then exactly(2, Work[e, Days], 0) endif
);
% Employees must only work the amount of hours in their contract
constraint forall (e in Employees) (
sum (d in Days) (Work[e,d]) = Contracts[e]
);
% Let's control the amount of employee's day off on We and Fr
% and Sa and Su
constraint forall (d in Days) (
if d = Sa \/ d = Su then
at_most(2, Work[Employees, d], 0)
elseif d = We \/ d = Fr then
at_most(3, Work[Employees, d], 0)
else
at_least(3, Work[Employees, d], 0)
endif
);
% Personnel effort
constraint forall (d in Days) (
Personnel_effort[d] = card(Employees) - among(Work[Employees, d], {0})
);
% Hour effort
constraint forall (d in Days) (
Hour_effort[d] = (sum (e in Employees) (Work[e,d]))
/\
Hour_effort[d] >= 37 % (1m + 1e) and (1m + 2e)
);
% Productivity
constraint forall(d in Days) (
Productivity[d] = (Budget[d] div Hour_effort[d])
/\
Productivity[d] > 40
);
% Solve
solve satisfy;
% solve maximize Productivity;
% Output
output [if d == Mo then show(Employees[e]) ++ "\t\t" else "" endif ++
show(Days[d]) ++ ":" ++ show(Work[e,d]) ++
if d == Su then "\n" else "\t" endif
| e in Employees, d in Days ] ++
[if d == Mo then "\nBudget\t\t" else "" endif ++
show(Days[d]) ++ ":" ++ show(Budget[d]) ++ "\t"
| d in Days ] ++
[if d == Mo then "\nProd\t\t" else "" endif ++
show(Days[d]) ++ ":" ++ show(Productivity[d]) ++ "\t"
| d in Days ] ++
[if d == Mo then "\nEffort (P)\t" else "" endif ++
show(Days[d]) ++ ":" ++ show(Personnel_effort[d]) ++ "\t"
| d in Days ] ++
[if d == Mo then "\nEffort (h)\t" else "" endif ++
show(Days[d]) ++ ":" ++ show(Hour_effort[d]) ++ "\t"
| d in Days ];
答案 0 :(得分:0)
正如hakank建议的那样,您需要一个函数来进行优化。最简单的方法就是优化生产力的总和:
solve maximize sum(d in Days) (Productivity[d]);
如果愿意,可以添加更复杂的功能。