Initializing help system before first use

Binary fixing heuristic for the Coco problem


Type: Production planning
Rating: 3 (intermediate)
Description:
  • changing bounds on variables
  • basis in- and output
  • setting Optimizer parameters
  • saving and loading MIP solutions (file fixbvls.mos)
File(s): fixbv.mos, fixbvls.mos


fixbv.mos
(!*******************************************************
  * Mosel Example Problems                              *
  * ======================                              *
  *                                                     *
  * file fixbv.mos                                      *
  * ``````````````                                      *
  * Example for the use of the Mosel language           *
  * (Using the complete Coco Problem, as in coco.mos,   *
  *  this program implements a binary fixing heuristic) *
  *                                                     *
  * (c) 2008 Fair Isaac Corporation                     *
  *     author: S. Heipcke, 2001, rev. Feb. 2010        *
  *******************************************************!)

model Coco                             ! Start a new model

uses "mmxprs"                          ! Load the optimizer library

parameters
 PHASE=5
(!* Phase = 4: Mines may open/closed freely; when closed save 20000 per month
  * Phase = 5: Once closed always closed; larger saving 
!)
end-parameters

declarations
 NT=4                                  ! Number of time periods
 RP=1..2                               ! Range of products (p)
 RF=1..2                               !          factories (f)
 RR=1..2                               !          raw materials (r)
 RT=1..NT                              !          time periods (t)

 REV: array(RP,RT) of real             ! Unit selling price of product p
 CMAKE: array(RP,RF) of real           ! Unit cost to make product p 
                                       ! at factory f
 CBUY: array(RR,RT) of real            ! Unit cost to buy raw material r
 COPEN: array(RF) of real              ! Fixed cost of factory f being 
                                       ! open for one period
 REQ: array(RP,RR) of real             ! Requirement by unit of product p 
                                       ! for raw material r
 MXSELL: array(RP,RT) of real          ! Max. amount of p that can be sold
 MXMAKE: array(RF) of real             ! Max. amount factory f can make 
                                       ! over all products
 PSTOCK0: array(RP,RF) of real         ! Initial product p stock level 
                                       ! at factory f
 RSTOCK0: array(RR,RF) of real         ! Initial raw material r stock 
                                       ! level at factory f
 CPSTOCK = 2.0                         ! Unit cost to store any product p
 CRSTOCK = 1.0                         ! Unit cost to store any raw mat. r
 MXRSTOCK = 300                        ! Max. amount of r that can be 
                                       ! stored each f and t
                                   
 make: array(RP,RF,RT) of mpvar        ! Amount of product p made at 
                                       ! factory f
 sell: array(RP,RF,RT) of mpvar        ! Amount of product p sold from 
                                       ! factory f in period t
 buy: array(RR,RF,RT) of mpvar         ! Amount of raw material r bought 
                                       ! for factory f in period t
 pstock: array(RP,RF,1..NT+1) of mpvar ! Stock level of product p at 
                                       ! factory f at start of period t
 rstock: array(RR,RF,1..NT+1) of mpvar ! Stock level of raw material r at
                                       ! factory f at start of period t 
 openm: array(RF,RT) of mpvar          ! 1 if factory f is open in
                                       ! period t, else 0
end-declarations

 REV ::  [400, 380, 405, 350,
          410, 397, 412, 397]
 CMAKE :: [150, 153,
           75,  68] 
 CBUY :: [100,  98,  97, 100,
          200, 195, 198, 200]
 COPEN :: [50000, 63000]
 REQ ::  [1.0, 0.5,
          1.3, 0.4]
 MXSELL ::   [650, 600, 500, 400,
              600, 500, 300, 250]
 MXMAKE ::  [400, 500]
 PSTOCK0 :: [50, 100,
             50,  50]
 RSTOCK0 :: [100, 150,
              50, 100]

                                 ! Objective: maximize total profit
 MaxProfit:= 
  sum(p in RP,f in RF,t in RT) REV(p,t) * sell(p,f,t) -        ! revenue
  sum(p in RP,f in RF,t in RT) CMAKE(p,f) * make(p,f,t) -      ! prod. cost
  sum(r in RR,f in RF,t in RT) CBUY(r,t) * buy(r,f,t) -        ! raw mat. cost
  sum(p in RP,f in RF,t in 2..NT+1) CPSTOCK * pstock(p,f,t) -  ! p stor. cost
  sum(r in RR,f in RF,t in 2..NT+1) CRSTOCK * rstock(r,f,t)    ! r stor. cost

 if PHASE=4 then                 ! Factory fixed cost
  MaxProfit -= sum(f in RF,t in RT) (COPEN(f)-20000)*openm(f,t)
 elif PHASE=5 then
  MaxProfit -= sum(f in RF,t in RT) COPEN(f)* openm(f,t)
 end-if
                                 ! Product stock balance
 forall(p in RP,f in RF,t in RT) PBal(p,f,t):=
  (pstock(p,f,t+1) = pstock(p,f,t) + make(p,f,t) - sell(p,f,t))

                                 ! Raw material stock balance
 forall(r in RR,f in RF,t in RT) 
  RBal(r,f,t):=  rstock(r,f,t+1) = 
   rstock(r,f,t) + buy(r,f,t) - sum(p in RP) REQ(p,r)*make(p,f,t)

                                 ! Capacity limit at factory f
 forall(f in RF,t in RT)
  MxMake(f,t):= sum(p in RP) make(p,f,t) <= MXMAKE(f)*openm(f,t)

                                 ! Limit on the amount of prod. p to be sold
 forall(p in RP,t in RT)
  MxSell(p,t):= sum(f in RF) sell(p,f,t) <= MXSELL(p,t)

                                 !  Raw material stock limit
 forall(f in RF,t in 2..NT+1)
  MxRStock(f,t):= sum(r in RR) rstock(r,f,t) <= MXRSTOCK

 if PHASE=5 then                 ! Once closed, always closed
  forall(f in RF,t in 1..NT-1) Closed(f,t):= openm(f,t+1) <= openm(f,t)
 end-if
                                 ! Initial product levels
 forall(p in RP,f in RF) pstock(p,f,1) = PSTOCK0(p,f)
                                 ! Initial raw material levels
 forall(r in RR,f in RF) rstock(r,f,1) = RSTOCK0(r,f)

 forall(f in RF,t in RT) openm(f,t) is_binary
   

!************************************************************************
!  Solution heuristic:                                                   
!    solve the LP and save the basis                                     
!    fix all open variables which are integer feasible at the relaxation 
!    solve the MIP and save the best solution value                      
!    reset all variables to their original bounds                        
!    load the saved basis                                                
!    solve the MIP using the solution value found previously as cutoff   
!************************************************************************

declarations
 TOL=5.0E-4                      ! Zero-tolerance
 osol: array(RF,1..2) of real    ! Solution values for openm variables          
 bas: basis
end-declarations

 setparam("zerotol", TOL)        ! Set Mosel comparison tolerance    
 setparam("XPRS_verbose",true)   ! Enable message printing in mmxprs
 setparam("XPRS_CUTSTRATEGY",0)  ! Disable automatic cuts - we use a heuristic 
 setparam("XPRS_PRESOLVE",0)
 maximize(XPRS_LPSTOP,MaxProfit) ! Solve the LP problem
 savebasis(bas);                 ! Save the current basis 

 writeln("\n>>>>LP relaxation objective: ", getobjval)
 
! Fix all variables in the first two time periods which are integer feasible 
 forall(f in RF, t in 1..2) do
  osol(f,t):= openm(f,t).sol
  if osol(f,t) = 0 then 
   openm(f,t).ub:= 0.0
  elif osol(f,t) = 1 then
   openm(f,t).lb:= 1.0
  end-if
 end-do 

 maximize(XPRS_CONT,MaxProfit)   ! Solve the MIP problem
 ifgsol:=false
 if getprobstat=XPRS_OPT then    ! If an integer feas. solution was found 
  writeln("\n>>>>Heuristic MIP solution: ", getobjval)
  ifgsol:=true
  solval:=getobjval              ! Get the value of the best solution 
 end-if

                                 ! Reset variables to their original bounds 
 forall(f in RF, t in 1..2)
  if ((osol(f,t) = 0) or (osol(f,t) = 1)) then
   openm(f,t).lb:= 0.0
   openm(f,t).ub:= 1.0
  end-if

 loadbasis(bas)                  ! Load the saved basis: bound changes are
                                 ! immediately passed on to the optimizer 
                                 ! if the problem has not been modified
                                 ! in any other way, so that there is no 
                                 ! need to reload the matrix 
 if ifgsol then                  ! Set the cutoff to the best known solution 
  setparam("XPRS_MIPABSCUTOFF", solval)
 end-if
 maximize(MaxProfit)             ! Solve the MIP problem

 if getprobstat=XPRS_OPT then
  writeln("\n>>>>Best integer solution: ", getobjval)
 else
  writeln("\n>>>>Best integer solution: ", solval)
 end-if

end-model


fixbvls.mos
(!*******************************************************
   Mosel Example Problems                              
   ======================                              
                                                       
   file fixbvls.mos                                    
   ````````````````                                    
   Example for the use of the Mosel language           
   (Using the complete Coco Problem, as in coco.mos,   
    this program implements a binary fixing heuristic) 
    - Model version using savemipsol/loadmipsol -
                                                       
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, June 2007, rev. Mar. 2019                            
  *******************************************************!)

model Coco                             ! Start a new model

uses "mmxprs"                          ! Load the optimizer library

parameters
 PHASE=5
(!* Phase = 4: Mines may open/closed freely; when closed save 20000 per month
  * Phase = 5: Once closed always closed; larger saving 
!)
end-parameters

declarations
 NT=4                                  ! Number of time periods
 RP=1..2                               ! Range of products (p)
 RF=1..2                               !          factories (f)
 RR=1..2                               !          raw materials (r)
 RT=1..NT                              !          time periods (t)

 REV: array(RP,RT) of real             ! Unit selling price of product p
 CMAKE: array(RP,RF) of real           ! Unit cost to make product p 
                                       ! at factory f
 CBUY: array(RR,RT) of real            ! Unit cost to buy raw material r
 COPEN: array(RF) of real              ! Fixed cost of factory f being 
                                       ! open for one period
 REQ: array(RP,RR) of real             ! Requirement by unit of product p 
                                       ! for raw material r
 MXSELL: array(RP,RT) of real          ! Max. amount of p that can be sold
 MXMAKE: array(RF) of real             ! Max. amount factory f can make 
                                       ! over all products
 PSTOCK0: array(RP,RF) of real         ! Initial product p stock level 
                                       ! at factory f
 RSTOCK0: array(RR,RF) of real         ! Initial raw material r stock 
                                       ! level at factory f
 CPSTOCK = 2.0                         ! Unit cost to store any product p
 CRSTOCK = 1.0                         ! Unit cost to store any raw mat. r
 MXRSTOCK = 300                        ! Max. amount of r that can be 
                                       ! stored each f and t
                                   
 make: array(RP,RF,RT) of mpvar        ! Amount of product p made at 
                                       ! factory f
 sell: array(RP,RF,RT) of mpvar        ! Amount of product p sold from 
                                       ! factory f in period t
 buy: array(RR,RF,RT) of mpvar         ! Amount of raw material r bought 
                                       ! for factory f in period t
 pstock: array(RP,RF,1..NT+1) of mpvar ! Stock level of product p at 
                                       ! factory f at start of period t
 rstock: array(RR,RF,1..NT+1) of mpvar ! Stock level of raw material r at
                                       ! factory f at start of period t 
 openm: array(RF,RT) of mpvar          ! 1 if factory f is open in
                                       ! period t, else 0
end-declarations

 REV ::  [400, 380, 405, 350,
          410, 397, 412, 397]
 CMAKE :: [150, 153,
           75,  68] 
 CBUY :: [100,  98,  97, 100,
          200, 195, 198, 200]
 COPEN :: [50000, 63000]
 REQ ::  [1.0, 0.5,
          1.3, 0.4]
 MXSELL ::   [650, 600, 500, 400,
              600, 500, 300, 250]
 MXMAKE ::  [400, 500]
 PSTOCK0 :: [50, 100,
             50,  50]
 RSTOCK0 :: [100, 150,
              50, 100]

                                 ! Objective: maximize total profit
 MaxProfit:= 
  sum(p in RP,f in RF,t in RT) REV(p,t) * sell(p,f,t) -        ! revenue
  sum(p in RP,f in RF,t in RT) CMAKE(p,f) * make(p,f,t) -      ! prod. cost
  sum(r in RR,f in RF,t in RT) CBUY(r,t) * buy(r,f,t) -        ! raw mat. cost
  sum(p in RP,f in RF,t in 2..NT+1) CPSTOCK * pstock(p,f,t) -  ! p stor. cost
  sum(r in RR,f in RF,t in 2..NT+1) CRSTOCK * rstock(r,f,t)    ! r stor. cost

 if PHASE=4 then                 ! Factory fixed cost
  MaxProfit -= sum(f in RF,t in RT) (COPEN(f)-20000)*openm(f,t)
 elif PHASE=5 then
  MaxProfit -= sum(f in RF,t in RT) COPEN(f)* openm(f,t)
 end-if
                                 ! Product stock balance
 forall(p in RP,f in RF,t in RT) PBal(p,f,t):=
  (pstock(p,f,t+1) = pstock(p,f,t) + make(p,f,t) - sell(p,f,t))

                                 ! Raw material stock balance
 forall(r in RR,f in RF,t in RT) 
  RBal(r,f,t):=  rstock(r,f,t+1) = 
   rstock(r,f,t) + buy(r,f,t) - sum(p in RP) REQ(p,r)*make(p,f,t)

                                 ! Capacity limit at factory f
 forall(f in RF,t in RT)
  MxMake(f,t):= sum(p in RP) make(p,f,t) <= MXMAKE(f)*openm(f,t)

                                 ! Limit on the amount of prod. p to be sold
 forall(p in RP,t in RT)
  MxSell(p,t):= sum(f in RF) sell(p,f,t) <= MXSELL(p,t)

                                 !  Raw material stock limit
 forall(f in RF,t in 2..NT+1)
  MxRStock(f,t):= sum(r in RR) rstock(r,f,t) <= MXRSTOCK

 if PHASE=5 then                 ! Once closed, always closed
  forall(f in RF,t in 1..NT-1) Closed(f,t):= openm(f,t+1) <= openm(f,t)
 end-if
                                 ! Initial product levels
 forall(p in RP,f in RF) pstock(p,f,1) = PSTOCK0(p,f)
                                 ! Initial raw material levels
 forall(r in RR,f in RF) rstock(r,f,1) = RSTOCK0(r,f)

 forall(f in RF,t in RT) openm(f,t) is_binary
   

!************************************************************************
!  Solution heuristic:                                                   
!    solve the LP and save the basis                                     
!    fix all open variables which are integer feasible at the relaxation 
!    solve the MIP and save the best solution value                      
!    reset all variables to their original bounds                        
!    load the saved basis                                                
!    solve the MIP using the solution value found previously as cutoff   
!************************************************************************

declarations
 TOL=5.0E-4                      ! Zero-tolerance
 osol: array(RF,1..2) of real    ! Solution values for openm variables          
 bas: basis
 allsol: array(mpvar) of real
end-declarations

 setparam("zerotol", TOL)        ! Set Mosel comparison tolerance    
 setparam("XPRS_verbose",true)   ! Enable message printing in mmxprs
 setparam("XPRS_CUTSTRATEGY",0)  ! Disable automatic cuts - we use a heuristic 
 setparam("XPRS_PRESOLVE",0)
 maximize(XPRS_LPSTOP,MaxProfit) ! Solve the LP problem
 savebasis(bas)                  ! Save the current basis 

 writeln("\n>>>>LP relaxation objective: ", getobjval)
 
! Fix all variables in the first two time periods which are integer feasible 
 forall(f in RF, t in 1..2) do
  osol(f,t):= getsol(openm(f,t))
  if osol(f,t) = 0 then 
   setub(openm(f,t), 0.0)
  elif osol(f,t) = 1 then
   setlb(openm(f,t), 1.0)
  end-if
 end-do 

 maximize(XPRS_CONT,MaxProfit)   ! Solve the MIP problem
 ifgsol:=false
 if getprobstat=XPRS_OPT then    ! If an integer feas. solution was found 
  writeln("\n>>>>Heuristic MIP solution: ", getobjval)
  ifgsol:=true
  solval:=getobjval              ! Get the value of the best solution 
  savemipsol(allsol)
 end-if

                                 ! Reset variables to their original bounds 
 forall(f in RF, t in 1..2)
  if ((osol(f,t) = 0) or (osol(f,t) = 1)) then
   setlb(openm(f,t), 0.0)
   setub(openm(f,t), 1.0)
  end-if

 loadprob(MaxProfit)             ! Reload the matrix if necessary:
                                 ! bound changes are immediately passed 
                                 ! on to the optimizer; since the problem 
                                 ! has not been modified in any other way 
                                 ! there is no need to reload the matrix. 
                                 ! 
				 ! If desired, reloading could be forced with:
				 !   loadprob(true, MaxProfit)

 loadbasis(bas)                  ! Load the saved basis to warm-start the LP 
 if ifgsol then                  
  res:=loadmipsol(allsol)        ! Load the best known MIP solution
  if(res<>0) then writeln("Loading MIP solution failed"); end-if
!  addmipsol("mysol", allsol)     ! Alternative form to load the MIP solution
 end-if
 maximize(MaxProfit)             ! Solve the MIP problem

                                 ! Print out the solution
 if getprobstat=XPRS_OPT then
  writeln("\n>>>>Best integer solution: ", getobjval)
 else
  writeln("\n>>>>Best integer solution: ", solval)
 end-if

! Uncomment to print out the solution values:
(!
 forall(p in RP, f in RF) do
  forall(t in RT)
   write(" make(",p,",",f,",",t,"):", getsol(make(p,f,t)), 
         " sell(",p,",",f,",",t,"):", getsol(sell(p,f,t)), " ")
  writeln
 end-do 
 forall(p in RP, f in RF) do
  forall(t in 1..NT+1) 
   write(" pstock(",p,",",f,",",t,"):", getsol(pstock(p,f,t)))
  writeln
 end-do 
 forall(r in RR, f in RF) do
  forall(t in RT)
   write(" buy(",r,",",f,",",t,"):", getsol(buy(r,f,t)))
  writeln
 end-do 
 forall(r in RR, f in RF) do
  forall(t in 1..NT+1) 
   write(" rstock(",r,",",f,",",t,"):", getsol(rstock(r,f,t)))
  writeln
 end-do 
 forall(f in RF, t in RT)
  write(" openm(",f,",",t,"):", getsol(openm(f,t)))
 writeln
!)

end-model


© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.