 FICO Xpress Optimization Examples Repository
 FICO Optimization Community FICO Xpress Optimization Home   Contract allocation

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 then 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 explanation of this example: 'Xpress teaching material', Section 2.2 'Semi-continuous variables: contract allocation'; 'Applications of optimization with Xpress-MP'', Section 3.4.3 'Semi-continuous variables'

Source Files

Data Files

contract_graph.mos

```(!******************************************************
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) 2008 Fair Isaac Corporation
author: S. Heipcke, Jan. 2001, rev. Sep. 2017
*******************************************************!)

model "Contract allocation"
uses "mmxprs", "mmsvg"

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
DistrGraph: array(DISTRICT) of string
end-declarations

forall(d in DISTRICT) do
DistrGraph(d):= "D"+d
svgsetstyle(SVG_STROKEWIDTH, "0.3")
end-do
forall(c in CONTRACT) do
ct:=0.0
forall(d in DISTRICT)
if getsol(quant(d,c))>0 then
!    svgaddrectangle(DistrGraph(d), 2*c-0.2, ct, 0.4, getsol(quant(d,c)))
ct+=getsol(quant(d,c))/2
end-if
end-do

svgsetgraphlabels("Contracts", "Contract volume")
svgsetgraphviewbox(0, 0, CONTRACT.size+1, 0.5*max(c in CONTRACT) VOLUME(c))

svgsave("contract.svg")
svgrefresh
svgwaitclose("Close browser window to terminate model execution.", 1)
end-model

```   