FICO Xpress Optimization Examples Repository
 FICO Optimization Community FICO Xpress Optimization Home

Output formatting for a transportation model

Description
• small LP problem
• generate a nice printed output
• using dynamic arrays for representing sparse data structures
• reading several data arrays from a single data file
Further explanation of this example: 'Mosel User Guide', Section 3.2 A transport example and Section 10.1 Producing formatted output.

The section 'Traditional embedding: solving multiple scenarios' of the Xpress Whitepaper 'Embedding Optimization Algorithms' describes how to embed a similar transportation model into an application.

Source Files

Data Files

transport_insight.mos

(!******************************************************
Mosel User Guide Example Problems
=================================

file transport_insight.mos

Solution display in Insight application.

(c) 2012 Fair Isaac Corporation
author: S.Heipcke, Sep. 2012, rev. Dec. 2020
*******************************************************!)

model "Transport"
uses "mmxprs", "mmsystem", "mmsvg"
uses "mminsight"

version 1.0.2

forward function solveproblem: boolean
forward procedure drawsolution(ifdisplay: boolean)

!@insight.manage=input
public declarations
!@insight.alias Customer regions
REGION: set of string                 ! Set of customer regions
!@insight.alias Plants
PLANT: set of string                  ! Set of plants
!@insight.alias Demand
DEMAND: array(REGION) of real         ! Demand at regions
!@insight.alias Production capacity
PLANTCAP: array(PLANT) of real        ! Production capacity at plants
!@insight.alias Unit production cost
PLANTCOST: array(PLANT) of real       ! Unit production cost at plants
!@insight.alias Capacity on each route
TRANSCAP: dynamic array(PLANT,REGION) of real
! Capacity on each route plant->region
!@insight.alias Distance per route
DISTANCE: dynamic array(PLANT,REGION) of real
! Distance of each route plant->region
!@insight.alias Fuel cost per unit distance
FUELCOST: real                        ! Fuel cost per unit distance
!@insight.update.afterexecution=true
! @insight.hidden=true
SELCUST: array(REGION) of boolean     ! Customer selection for display
! @insight.hidden=true
!@insight.update.afterexecution=true
CURRENTPLANT: string                  ! Plant selection for display
end-declarations

!@insight.manage=result
public declarations
!@insight.alias Production capacity limits
MaxCap: array(PLANT) of linctr        ! Capacity constraints
!@insight.alias Amount shipped
flow: dynamic array(PLANT,REGION) of mpvar    ! Flow on each route
RunDate: string                       ! Date for display
!@insight.hidden=true
MincostSol: real
!@insight.hidden=true
pltotal: array(PLANT) of real         !@insight.alias Total
!@insight.hidden=true
rgtotal: array(REGION) of real
end-declarations

!@insight.resultdata.delete=on-execute

! Handling of Insight execution modes
! (whether to read data from file or use scenario data)
case insightgetmode of
readdata             ! Initialize data from file
exit(0)              ! Stop model run after data input
end-do
INSIGHT_MODE_RUN: do
insightpopulate      ! Inject scenario data
if solveproblem then   ! State and solve the optimization problem
drawsolution(false)
end-if
end-do
INSIGHT_MODE_NONE: do
readdata             ! Non-Insight runs: initialize data from file
if solveproblem then   ! State and solve the optimization problem
drawsolution(true)
end-if
end-do
else
writeln_("Unknown run mode")
exit(1)
end-case

!***********************************************************************
! **** State and solve the optimization problem
function solveproblem: boolean
! Create the flow variables that exist
forall(p in PLANT, r in REGION | exists(TRANSCAP(p,r)) ) create(flow(p,r))

! Objective: minimize total cost
MinCost:= sum(p in PLANT, r in REGION | exists(flow(p,r)))
(FUELCOST * DISTANCE(p,r) + PLANTCOST(p)) * flow(p,r)

! Limits on plant capacity
forall(p in PLANT) MaxCap(p):= sum(r in REGION) flow(p,r) <= PLANTCAP(p)

! Satisfy all demands
forall(r in REGION) sum(p in PLANT) flow(p,r) = DEMAND(r)

! Bounds on flows
forall(p in PLANT, r in REGION | exists(flow(p,r)))
flow(p,r) <= TRANSCAP(p,r)

insightminimize(MinCost)      ! Solve problem through Xpress Insight

setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
RunDate:= string(datetime(SYS_NOW))

if getprobstat=XPRS_OPT then
writeln("Solution: ", getobjval)

! Result objects accessed by Xpress Insight
MincostSol:= getobjval
pltotal:= array(p in PLANT) sum(r in REGION) flow(p,r).sol
rgtotal:= array(r in REGION) sum(p in PLANT) flow(p,r).sol

returned:=true
else
writeln("No solution found")
returned:=false
end-if
end-function

! **** Data input from file
initializations from 'transprt.dat'
DEMAND
[PLANTCAP,PLANTCOST] as 'PLANTDATA'
[DISTANCE,TRANSCAP] as 'ROUTES'
FUELCOST
end-initializations
end-procedure

! **** Create an SVG graphic representing the solution
procedure drawsolution(ifdisplay: boolean)
declarations
YP: array(PLANT) of real           ! y-coordinates of plants
YR: array(REGION) of real          ! y-coordinates of sales regions
end-declarations

! Scale the size of the displayed graph
svgsetgraphviewbox(0.2,0.4,4,getsize(REGION)-0.55)
svgsetgraphsize(490,490)
svgsetgraphscale(100)

! Determine y-coordinates for plants and regions
ct:= floor((getsize(REGION)-getsize(PLANT))/2)
forall(p in PLANT, ct as counter) YP(p):= ct
writeln(YP)
ct:=0
forall(r in REGION, ct as counter) YR(r):= ct-0.5

! Draw the plants
svgsetstyle(SVG_FONTSIZE, 20)
forall(p in PLANT) svgaddtext(0.2, YP(p)-0.05, p)

! Draw the sales regions
svgsetstyle(SVG_FONTSIZE, 20)
forall(r in REGION) svgaddtext(3.1, YR(r)-0.05, r)

! Draw all transport routes
forall(p in PLANT, r in REGION | exists(TRANSCAP(p,r)) )

! Draw the routes used by the solution
forall(p in PLANT, r in REGION | exists(flow(p,r)) and getsol(flow(p,r)) > 0)

! Generate the SVG graphic file
svgsave("transport.svg")

! Don't try to display the graphic if this model is run within Insight
if ifdisplay then
svgrefresh
svgwaitclose("Close browser window to terminate model execution.", 1)
else
! Upload the graphic as attachment
insightputscenattach("transport.svg",true)
insightsetscenattachtags("transport.svg", ["resultgraph"])
end-if
end-procedure
end-model