help-glpk
[Top][All Lists]

## Re: [Help-glpk] mathprog

 From: glpk xypron Subject: Re: [Help-glpk] mathprog Date: Tue, 27 Jan 2009 19:22:33 +0100

```Hello Abdelahd,

> How to model that an employee must work at least 5 successive
> periods and at most 8 successive periods with mathprog.

please, find an example below. In the appendix you can find a model using csv
files as data input.

Best regards

Xypron

# Personnel assignment problem
#
# Given:
#   available workers with
#   - minimum working days in a row
#   - maximum working days in a row
#   - minimum leave days in a row
#   - daily wage
#
# determine cheapest shift schedule.
#
# Author: Xypron, 2009
#
# This example is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY. Feel free to copy or modify.

set L, dimen 2;

# workers (name, min workdays, max workdays, minimum leave, wage)
set W, dimen 5;

# names of workers
set V := setof{(v, b, c, d, e) in W} v;

# periods
set B := ( (min{(b,c) in L} b) .. (max{(b,c) in L} b) );

# minimum number of workdays in row
param ri{v in V} := min{(v, b, c, d, e) in W} b;

# maximum number of workdays in row
param ra{v in V} := min{(v, b, c, d, e) in W} c;

# minimum leave days in row
param ml{v in V} := min{(v, b, c, d, e) in W} d;

# wage
param wa{v in V} := min{(v, b, c, d, e) in W} e;

# work offer [worker, start, duration]
# (for large problems consider column generation to create work offers)
set O := setof{ v in V, s in B, d in {ri[v]..ra[v]}}( v, s, d);

# workday
param wd{b in B, (v, s, d) in O} :=
if b < s then 0 else if b - s > d - 1 then 0 else 1;

# leaveday
param ld{b in B, (v, s, d) in O} :=
if b < s + d then 0 else if b - s > d + ml[v] - 1 then 0 else 1;

# work offer used
var x{(v,s,d) in O}, binary;

# minimze total wage
minimize wage :
sum{b in B, (v,s,d) in O} x[v,s,d] * wd[b,v,s,d] * wa[v];

# worker can do one job only
s.t. j1{b in B, v in V} :
sum{(v,s,d) in O} x[v,s,d] * ( wd[b,v,s,d] + ld[b,v,s,d] ) <= 1;

# do all jobs
s.t. ja{b in B} :
sum{(v,s,d) in O} x[v,s,d] * wd[b,v,s,d] >= sum{(b, w) in L} w;

solve;

# output solution
printf "\n%-10s", "Day";
for {v in V}
printf "| %-10s", v;
printf "\n";
printf "%-10s", '----------';
for {v in V}
printf "+-%-10s", '----------';
printf "\n";
for {b in B}
{
printf "%9i ", b;
for {v in V}
printf "| %-9s ",
if sum{(v,s,d) in O} x[v,s,d] * wd[b,v,s,d] then "working"
else "on leave";
printf "\n";
}
printf "\n";

data;

set L := # day, workload
( 1, 3)
( 2, 1)
( 3, 1)
( 4, 1)
( 5, 1)
( 6, 2)
( 7, 2)
( 8, 2)
( 9, 3)
(10, 2)
(11, 2)
(12, 2)
(14, 1)
(15, 2)
(17, 3)
(18, 3)
(19, 2)
(21, 3)
(23, 1)
(24, 3)
(25, 3)
(26, 3)
(27, 2)
(28, 1)
(29, 1)
(30, 2)
(31, 1)
(32, 3)
(33, 2)
(35, 3)
(36, 3)
(37, 1)
(38, 3)
(39, 2)
(40, 3)
(43, 1)
(44, 1)
(45, 2)
(46, 2)
(47, 3)
(48, 2)
(49, 1)
(50, 2);

# workers
set W := # name, min workdays, max workdays, minimum leave, wage
( 'Anna',   5, 8, 2,  470 )
( 'Isabel', 5, 8, 2,  500 )
( 'Jack',   1, 8, 2, 1000 )
( 'John',   5, 8, 2,  600 )
( 'Lisa',   3, 5, 3,  640 );
end;

--
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen:
http://www.gmx.net/de/go/multimessenger
``` manpower.tar.gz
Description: PostScript document