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

Mining and process industries

Description
Problem name and type, featuresDifficultyRelated examples
A‑1 Production of alloys: Blending problem

formulation of blending constraints; data with numerical indices, solution printout, if-then, getsol
* blending_graph.mos
A‑2 Animal food production: Blending problem

formulation of blending constraints; data with string indices, as, formatted solution printout, use of getsol with linear expressions, strfmt
* a1alloy.mos
A‑3 Refinery : Blending problem

formulation of blending constraints; sparse data with string indices, dynamic initialization, union of sets
** a2food.mos
A‑4 Cane sugar production : Minimum cost flow (in a bipartite graph)

mo ceil, is_binary, formattext
* e2minflow.mos, mincostflow_graph.mos
A‑5 Opencast mining: Minimum cost flow

encoding of arcs, solving LP-relaxation only, array of set
** a4sugar.mos
A‑6 Production of electricity: Dispatch problem

inline if, is_integer, looping over optimization problem solving
**


Further explanation of this example: 'Applications of optimization with Xpress-MP', Chapter 6: Mining and process industries (blending problems)

mosel_app_1.zip[download all files]

Source Files

Data Files





a6electrg.mos

(!******************************************************
   Mosel Example Problems
   ======================

   file a6electrg.mos
   ``````````````````
   Production of electricity.
   Plotting parametrics in the reserve capacity.

   Four types of power generators are available to meet daily
   electricity demands and up to 20% above. Each type of 
   generator has a set maximum capacity and minimum power output.
   A generator can only be started or stopped at the beginning 
   of a time period. The objective is to determine which 
   generators should be used in each period so that total daily 
   cost is minimized.   

   Similar model formulation as a6electr.mos however defines data
   directly in code and is set up to solve for varying reserve 
   demand (0-20%), redefining the reserve constraints for every loop 
   iteration and reloading the basis saved after the initial LP solve.
   Displays results with a graph.
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Oct. 2004, rev. June 2017
*******************************************************!)

model "A-6 Electricity production (with graph drawing)"
 uses "mmxprs", "mmsvg"
 
 declarations
  NT = 7
  TIME = 1..NT                       ! Time periods
  TYPES = 1..4                       ! Power generator types

  LEN, DEM: array(TIME) of integer   ! Length and demand of time periods
  PMIN,PMAX: array(TYPES) of integer ! Min. & max output of a generator type
  CSTART: array(TYPES) of integer    ! Start-up cost of a generator
  CMIN: array(TYPES) of integer      ! Hourly cost of gen. at min. output
  CADD: array(TYPES) of real         ! Cost/hour/MW of prod. above min. level
  AVAIL: array(TYPES) of integer     ! Number of generators per type
  Graph: integer                     ! Result graph
  bas: basis                         ! LP basis

  start: array(TYPES,TIME) of mpvar  ! No. of gen.s started in a period
  work: array(TYPES,TIME) of mpvar   ! No. of gen.s working during a period
  padd: array(TYPES,TIME) of mpvar   ! Production above min. output level
 end-declarations
 
! Time period data
 LEN:: [    6,     3,     3,     2,     4,     4,     2]
 DEM:: [12000, 32000, 25000, 36000, 25000, 30000, 18000]

! Power plant data
 PMIN::   [ 750, 1000, 1200, 1800]
 PMAX::   [1750, 1500, 2000, 3500]
 CSTART:: [5000, 1600, 2400, 1200]
 CMIN::   [2250, 1800, 3750, 4800]
 CADD::   [ 2.7,  2.2,  1.8,  3.8]
 AVAIL::  [  10,    4,    8,    3]
 
 
! Objective function: total daily cost
 Cost:= sum(p in TYPES, t in TIME) (CSTART(p)*start(p,t) +
          LEN(t)*(CMIN(p)*work(p,t) + CADD(p)*padd(p,t))) 
                                   
! Number of generators started per period and per type
 forall(p in TYPES, t in TIME) 
  NumStart(p,t):= start(p,t) >= work(p,t) - if(t>1, work(p,t-1), work(p,NT))

! Limit on power production above minimum level
 forall(p in TYPES, t in TIME) 
  Limit(p,t):= padd(p,t) <= (PMAX(p)-PMIN(p))*work(p,t)

! Satisfy demands
 forall(t in TIME) 
  Demand(t):= sum(p in TYPES) (PMIN(p)*work(p,t) + padd(p,t)) >= DEM(t)

! Security reserve (reserve initially at 0%)
 forall(t in TIME) 
  Reserve(t):= sum(p in TYPES) PMAX(p)*work(p,t) >= DEM(t)

! Limit number of available generators; numbers of generators are integer
 forall(p in TYPES, t in TIME) do
  work(p,t) <= AVAIL(p)
  work(p,t) is_integer
 end-do


! Uncomment the following line to see the Optimizer log
! setparam("XPRS_verbose", true)

! Solve as an LP problem and save the basis
 setparam("XPRS_PRESOLVE", 0)
 minimize(XPRS_LPSTOP, Cost)
 savebasis(bas)
 setparam("XPRS_PRESOLVE", 1)

! Define a user graph
 svgaddgroup("Graph", "Reserve %")

! Solve the problem with different values of reserve (from 0% to 20%)
 forall(r in 0..20) do
  forall(t in TIME)                   ! Redefine the reserve constraints
   Reserve(t):= sum(p in TYPES) PMAX(p)*work(p,t) >= (1+r/100)*DEM(t)

  loadprob(Cost)                      ! Load problem into the Optimizer
  loadbasis(bas)                      ! Load the saved basis
  minimize(Cost)                      ! Solve the modified problem

  writeln(r, "%: ", getobjval)        ! Print solution value
  svgaddpoint("Graph", r, getobjval/1000)  ! Display solution in user graph
 end-do

! Scale the size of the displayed graph
 svgsetgraphscale(10)
 svgsetgraphpointsize(3)

 svgsave("a6electr.svg")
 svgrefresh
 svgwaitclose
end-model

Back to examples browserPrevious exampleNext example