(!****************************************************** Mosel Example Problems ====================== file contract.mos ````````````````` TYPE: Contract allocation problem DIFFICULTY: 2 FEATURES: simple MIP problem, semi-continuous variables, graphical representation of results DESCRIPTION: A public utility, which is divided into six regional districts, wishes to allocate ten power generation contracts to its regions as cheaply as possible. The cost per unit of power generated by each region for each contract is known.  If part of a contract is allocated to a region than it must be at least as big as a certain minimum size (5 units). For reliability reasons, no contract may be placed exclusively with only one district. Each district has a limited power generation capacity. FURTHER INFO: `Applications of optimization with Xpress-MP teaching material', Section 2.2 `Semi-continuous variables: contract allocation'; `Applications of optimization with Xpress-MP', Section 3.4.3 `Semi-continuous variables' (c) 2001 Dash Associates author: S. Heipcke *******************************************************!) model "Contract allocation" uses "mmxprs", "mmive" declarations DISTRICT = 1..6 ! Districts CONTRACT = 1..10 ! Contracts OUTPUT: array(DISTRICT) of integer ! Maximum output per district COST : array(DISTRICT) of integer ! Cost per district VOLUME: array(CONTRACT) of integer ! Volume of contracts alloc: array(DISTRICT,CONTRACT) of mpvar ! 1 if a bid is chosen, 0 otherwise quant: array(DISTRICT,CONTRACT) of mpvar ! Quantities allocated to contractors end-declarations initializations from 'contract.dat' OUTPUT COST VOLUME end-initializations ! Objective function: total cost Cost:= sum(d in DISTRICT, c in CONTRACT) COST(d)*quant(d,c) forall(c in CONTRACT) do sum(d in DISTRICT) quant(d,c) >= VOLUME(c) ! Cover the req. contract volume sum(d in DISTRICT) alloc(d,c) >= 2 ! At least 2 districts per contract end-do ! Do not exceed maximum output of any district forall(d in DISTRICT) Output(d):= sum(c in CONTRACT) quant(d,c) <= OUTPUT(d) ! If a contract is allocated to a district, then at least 1 unit is ! allocated to it forall(d in DISTRICT, c in CONTRACT) MinAlloc(d,c):= alloc(d,c) <= quant(d,c) forall(d in DISTRICT, c in CONTRACT) do alloc(d,c) is_binary quant(d,c) is_semcont 5 quant(d,c) <= OUTPUT(d) end-do ! Solve the problem minimize(Cost) ! Solution printing writeln("Total cost: ", getobjval) writeln("Contract Districts") forall(c in CONTRACT) do write(strfmt(c,3), " (", VOLUME(c), "):") forall(d in DISTRICT) write(if(getsol(quant(d,c))>0, " "+d+"("+getsol(quant(d,c))+")", "")) writeln end-do ! Solution drawing declarations COLOR: array(DISTRICT) of integer DistrGraph: array(DISTRICT) of integer end-declarations COLOR:=[IVE_BLUE, IVE_YELLOW, IVE_RED, IVE_GREEN, IVE_CYAN, IVE_MAGENTA] IVEzoom(0, 0, max(c in CONTRACT) c+1, max(c in CONTRACT) VOLUME(c)+1) forall(d in DISTRICT) DistrGraph(d):= IVEaddplot("District "+d, COLOR(d)) !forall(c in CONTRACT) do ! ct:=0.0 ! forall(d in DISTRICT) !if getsol(quant(d,c))>0 then ! IVEdrawrectangle(DistrGraph(d), c-0.2, ct, c+0.2, ct+getsol(quant(d,c))) ! ct+=getsol(quant(d,c)) ! end-if !end-do end-model