FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

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'

contractgr.zip[download all files]

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
contract_graph.mos[download]

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
   svgaddgroup(DistrGraph(d), "District "+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)))
    svgaddrectangle(DistrGraph(d), c-0.1, ct, 0.2, getsol(quant(d,c))/2)
    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

Back to examples browserPrevious exampleNext example