(!****************************************************** Mosel Example Problems ====================== file persplan.mos ````````````````` TYPE: Personnel planning DIFFICULTY: 2 FEATURES: simple MIP problem, formulation of balance constraints using inline 'if' DESCRIPTION: The requirements for construction workers at a construction site during a period of six months are known. Transfers from other sites to this one are possible on the first day of every month and at the end of every month workers may leave to other sites. Transfer, understaffing, and overstaffing incur known costs per month per post. Overtime work is limited to 25% of the hours worked normally. The monthly arrivals and departures are limited. Three workers are already present on site at the beginning of the planning period and that three workers need to remain on-site at the end. Which are the number of arrivals and departures every month to minimize the total cost? FURTHER INFO: `Applications of optimization with Xpress-MP', Section 14.6 `Planning the personnel at a construction site' (c) 2002 Dash Associates author: S. Heipcke *******************************************************!) model "Construction site personnel" uses "mmxprs", "mmive" declarations FIRST = 3; LAST = 8 MONTHS = FIRST..LAST ! Set of time periods (months) CARR, CLEAVE: integer ! Cost per arrival/departure COVER, CUNDER: integer ! Cost of over-/understaffing NSTART, NFINAL: integer ! No. of workers at begin/end of plan REQ: array(MONTHS) of integer ! Requirement of workers per month onsite: array(MONTHS) of mpvar ! Workers on site arrive,leave: array(MONTHS) of mpvar ! Workers arriving/leaving over,under: array(MONTHS) of mpvar ! Over-/understaffing end-declarations initializations from 'persplan.dat' CARR CLEAVE COVER CUNDER NSTART NFINAL REQ end-initializations ! Objective: total cost Cost:= sum(m in MONTHS) (CARR*arrive(m) + CLEAVE*leave(m) + COVER*over(m) + CUNDER*under(m)) ! Satisfy monthly need of workers forall(m in MONTHS) Demand(m):= onsite(m) - over(m) + under(m) = REQ(m) ! Balances forall(m in MONTHS) Balance(m):= onsite(m) = if(m>FIRST, onsite(m-1) - leave(m-1), NSTART) + arrive(m) BalanceFinal:= NFINAL = onsite(LAST) - leave(LAST) ! Limits on departures, understaffing, arrivals; integrality constraints forall(m in MONTHS) do LimitLeave(m):= leave(m) <= 1/3*onsite(m) LimitUnder(m):= under(m) <= 1/4*onsite(m) arrive(m) <= 3 arrive(m) is_integer; leave(m) is_integer; onsite(m) is_integer under(m) is_integer; over(m) is_integer end-do ! Solve the problem minimize(Cost) ! Solution printing declarations NAMES: array(MONTHS) of string ! Names of months end-declarations initializations from 'persplan.dat' NAMES end-initializations writeln("Total cost: ", getobjval) write("Month ") forall(m in MONTHS) write(NAMES(m)," ") write("\nOn site ") forall(m in MONTHS) write(strfmt(getsol(onsite(m)),4)) write("\nArrive ") forall(m in MONTHS) write(strfmt(getsol(arrive(m)),4)) write("\nLeave ") forall(m in MONTHS) write(strfmt(getsol(leave(m)),4)) write("\nOverst. ") forall(m in MONTHS) write(strfmt(getsol(over(m)),4)) write("\nUnderst.") forall(m in MONTHS) write(strfmt(getsol(under(m)),4)) writeln ! Solution drawing IVEzoom(FIRST, 0, LAST, max(m in MONTHS)REQ(m)+1) ReqGraph:= IVEaddplot("Staff requirement", IVE_RED) AvailGraph:= IVEaddplot("Actual staff level", IVE_YELLOW) forall(m in FIRST..LAST-1) do IVEdrawline(ReqGraph, m, REQ(m), m+1, REQ(m+1)) IVEdrawline(AvailGraph, m, round(getsol(onsite(m))), m+1, round(getsol(onsite(m+1)))) end-do end-model