Initializing help system before first use

Transport - Insight GUI, user graph


Type: Transportation problem
Rating: 3 (intermediate)
Description:
  • transport_insight.zip: Xpress Insight application (includes transport_insight.mos, transportdata.vdl, transportcustsel.vdl, transportres.vdl, transportressum.vdl, transprt.dat, transport_insight.xml)
  • transport_graph.mos: Graphical solution output with mmsvg (requires transprt.dat)
File(s): transport_insight.mos, transportdata.vdl, transportcustsel.vdl, transportres.vdl, transportressum.vdl, transport_insight.xml, transport_graph.mos
Data file(s): transport_insight.zip, transprt.dat

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 procedure readdata
 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
  INSIGHT_MODE_LOAD: do
     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
 procedure readdata
  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
  svgaddgroup("PGr", "Plants", svgcolor(0,63,95))
  svgsetstyle(SVG_FONTSIZE, 20)
  forall(p in PLANT) svgaddtext(0.2, YP(p)-0.05, p)

  ! Draw the sales regions
  svgaddgroup("RGr", "Regions", svgcolor(0,157,169))
  svgsetstyle(SVG_FONTSIZE, 20)
  forall(r in REGION) svgaddtext(3.1, YR(r)-0.05, r)

  ! Draw all transport routes
  svgaddgroup("TGr", "Routes", SVG_GREY)
  forall(p in PLANT, r in REGION | exists(TRANSCAP(p,r)) )
   svgaddline(1, YP(p), 3, YR(r))

  ! Draw the routes used by the solution
  svgaddgroup("SGr", "Solution", SVG_ORANGE)
  forall(p in PLANT, r in REGION | exists(flow(p,r)) and getsol(flow(p,r)) > 0)
   svgaddarrow(1, YP(p), 3, YR(r))

  ! 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

transportdata.vdl
<vdl version="4.7">
  <vdl-page>    <!-- 'vdl' and 'vdl-page' tags must always be present -->

    <!-- 'header' element: container for any vdl elements that are not part 
         of the page layout -->
    <vdl-header>
      <vdl-action-group name="runModel">
        <vdl-action-execute mode="RUN"></vdl-action-execute>
      </vdl-action-group>
    </vdl-header>

    <!-- Structural element 'section': print header text for a section -->
    <vdl-section heading="Transportation data input">

      <!-- Structural element 'row': arrange contents in rows -->
      <vdl-row>
        <!-- A form contains one or several input elements -->
        <vdl-column size="4">
          <vdl-form>
            <!-- 'Run' button to launch optimization -->
            <vdl-button vdl-event="click:actions.runModel" 
                        label="Run optimization"></vdl-button>
          </vdl-form>
        </vdl-column> 
        <vdl-column size="4">
          <vdl-form>
            <!-- Input field for the fuel cost -->
            <vdl-field entity="FUELCOST" label-size="8" size="4"/>
          </vdl-form>
        </vdl-column> 
      </vdl-row>

      <vdl-row>
        <!-- Several columns within a 'row' for display side-by-side,
	     dividing up the total row width of 12 via 'size' setting
             on each column. -->
        <vdl-column size="4" heading="Plant data">
	  <!-- Display the plant data input values, default table format -->
          <vdl-table>
             <vdl-table-column entity="PLANTCAP" editable="true"/>
             <vdl-table-column entity="PLANTCOST" editable="true"/>
          </vdl-table>
        </vdl-column> 
        <vdl-column size="4" heading="Customer demands">
          <!-- Display the demand input values, default table format -->
          <vdl-table>
            <vdl-table-column entity="DEMAND" editable="true"/>  
          </vdl-table>
        </vdl-column> 
        <vdl-column size="4" heading="Transportation routes">
          <!-- Display the route input values, default table format,
               enabling pagewise display with 8 entries per page -->
          <vdl-table page-mode="paged" page-size="8"> 
            <vdl-table-column entity="DISTANCE" editable="true"/>
            <vdl-table-column entity="TRANSCAP" editable="true"/>
          </vdl-table>
        </vdl-column>
      </vdl-row>
    </vdl-section>
  </vdl-page>
</vdl>

transportcustsel.vdl
<vdl version="4.7">
    <!-- Implementation of a table row filter  -->
    <script>
        function filterRow(rowData, idx, current, Select) {
            // Plant === CURRENTPLANT && SELCUST for selecting the customers
            return (rowData[0] === current.value) && Select(rowData[1]).value;
        }
    </script>
    <vdl-page>
        <!-- 'vdl' and 'vdl-page' tags must always be present -->

        <!-- Structural element 'section': print header text for a section -->
        <vdl-section heading="Customer selection">
            <vdl-row>
                <vdl-column size="12">
                    <vdl-row>
                        <vdl-column><span vdl-text="Example of interaction between VDL elements: selecting customers and plant locations for display of input and result data in a filtered table."></span></vdl-column>
                    </vdl-row>
                    <vdl-row>
                        <!-- Display the input values as a table for indices 
                             selected upfront. -->
                        <!-- Several columns within a 'row' for display 
                             side-by-side, dividing up the total row width 
                             of 12 via 'size' setting on each column. -->
                        <vdl-column size="4" heading="Customer selection">
                            <vdl-table>
                                <vdl-table-column entity="SELCUST" editable="true"></vdl-table-column>
                            </vdl-table>
                        </vdl-column>
                        <vdl-column size="8" heading="Data and results for selected customers">
                            <vdl-form>
                                <vdl-field label="Plants" entity="CURRENTPLANT" options-set="PLANT"></vdl-field>
                            </vdl-form>
                            <vdl-table row-filter="=function(rowData, idx) {return filterRow(rowData, idx, scenario.entities.CURRENTPLANT, scenario.entities.SELCUST)}">
                                <vdl-table-column entity="TRANSCAP"></vdl-table-column>
                                <vdl-table-column entity="DISTANCE"></vdl-table-column>
                                <vdl-table-column entity="flow"></vdl-table-column>
                            </vdl-table>
                        </vdl-column>
                    </vdl-row>
                </vdl-column>
            </vdl-row>
        </vdl-section>
    </vdl-page>
</vdl>

transportres.vdl
<vdl version="4.7">
    <!-- 'vdl' and 'vdl-page' must always be present -->
    <vdl-page>
        <!-- 'header' element: container for any vdl elements that are not part 
             of the page layout -->
        <vdl-header>
         <!-- Optional style definition -->
             <style>
                 .Strong {
                     font-weight: bold;
                     font-style: italic;
                 }
             </style>
        </vdl-header>
 
        <!-- Placeholder message -->
	<vdl-container vdl-if="=!scenario.summaryData.hasResultData">
            <span vdl-text="No results available. Run the scenario to see the results." 
            style="font-style:italic"></span></vdl-container>

        <!-- Structural element 'section': 
             if hasResultData: display data once result values become available 
                              (after scenario execution) -->
        <vdl-section heading="Transportation Plan" vdl-if="=scenario.summaryData.hasResultData">

            <!-- Structural element 'row': arrange contents in rows -->
            <vdl-row>
                <!-- Several columns within a 'row' for display side-by-side,
                     dividing up the total row width of 12 via 'size' setting
                     on each column. -->
                <!-- Display inline text element with objective value -->
                <vdl-column size="4">
                    <vdl-container><span vdl-text="Total cost: &#163;"></span><span vdl-text="=insight.Formatter.formatNumber(scenario.entities.MincostSol.value, 
  '#,###.00')"></span></vdl-container>
                </vdl-column>
                <vdl-column size="8">
                    <vdl-container><span vdl-text="Date: "></span><span inline="true" vdl-text="=scenario.entities.RunDate.value" vd-selection="510.3619866979374"></span></vdl-container>
                </vdl-column>
            </vdl-row>
            <vdl-row>
                <vdl-column size="6">
                    <vdl-row>
                        <!-- Display the 'flow' solution values, showing the 
                             table in rectangular format (last index across the 
                             columns) with an additional colum for the 
                             single-index array 'pltotal' printed in bold font. -->
                        <vdl-column size="12" heading="Customized Autotable">
                            <vdl-table>
                                <vdl-table-column entity="flow" heading="=r.label" vdl-repeat="=r in scenario.entities.REGION">
                                    <vdl-index-filter set="REGION" value="=r.value"></vdl-index-filter>
                                </vdl-table-column>
                                <vdl-table-column entity="pltotal" label="Total" class="Strong"></vdl-table-column>
                            </vdl-table>
                        </vdl-column>
                    </vdl-row>
                    <vdl-row>
                        <!-- Display 'flow' solution values using the default 
                             table format, enabling pagewise display with 
                             10 entries per per -->
                        <vdl-column size="12" heading="Default Autotable format">
                            <vdl-table page-mode="paged" page-size="10">
                                <vdl-table-column entity="flow"></vdl-table-column>
                            </vdl-table>
                        </vdl-column>
                    </vdl-row>
                </vdl-column>
                <!-- Display 'flow' solution values as a stacked bar chart -->
                <vdl-column size="6" heading="Chart of result data">
                    <vdl-chart bar-mode="stack">
                        <vdl-chart-series entity="flow" series-set="PLANT"></vdl-chart-series>
                    </vdl-chart>
                </vdl-column>
            </vdl-row>
            <vdl-row>
                <vdl-column size="12">
                    <vdl-container><span vdl-text="Example of an SVG graphic generated by the Mosel model during a scenario run and added into scenario attachments:"></span></vdl-container>
                    <vdl-container><img vdl-attr="={src: scenario.attachments('transport.svg').dataUrl + '?lastModified='+scenario.attachments('transport.svg').lastModifiedDate}" width="400" height="400"  /></vdl-container>
                </vdl-column>
            </vdl-row>
        </vdl-section>
    </vdl-page>
</vdl>

transportressum.vdl
<vdl version="4.7">
    <!-- 'vdl' and 'vdl-page' must always be present -->
    <vdl-page>
        <!-- Structural element 'section': print header text for a section -->
        <vdl-section heading="Comparison of scenario results">
            <vdl-row>
                <vdl-column>
                    <p><span vdl-text="Viewing "></span><span vdl-text="=scenarios.length"></span><span vdl-text=" scenario(s)."></span></p>
                </vdl-column>
            </vdl-row>
            <vdl-row>
                <!-- Display the objective value -->
                <vdl-column heading="Total Cost">
                    <table class="insight-table table-main table-condensed">
                        <thead>
                            <tr>
                                <th vdl-repeat="=s in scenarios" vdl-text="=s.props.name"></th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td vdl-repeat="=s in scenarios" vdl-text="=insight.Formatter.formatNumber(s.entities.MincostSol.value, 
  '#,###.00')"></td>
                            </tr>
                        </tbody>
                    </table>
                </vdl-column>
            </vdl-row>
            <vdl-row>
                <!-- Display 'flow' solution values using the default table format,
                     enabling pagewise display with 10 entries per page -->
                <vdl-column size="12" heading="Quantities transported">
                    <vdl-table page-mode="paged" page-size="10">
                        <vdl-table-column entity="flow" heading="=s.props.name" vdl-repeat="=s,i in scenarios" scenario="=i"></vdl-table-column>
                    </vdl-table>
                </vdl-column>
            </vdl-row>
        </vdl-section>
    </vdl-page>
</vdl>

transport_insight.xml
<?xml version="1.0" encoding="UTF-8"?>
<model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0">

  <attachment-config>
    <attachment-tags>
      <attachment-tag name="resultgraph" usage="single-file">
        <description>Graph output by running the model.</description>
      </attachment-tag>
    </attachment-tags>
  </attachment-config>

  <client>
    <view-group title="Main">
      <vdl-view title="Input data" default="true" path="transportdata.vdl"/>
      <vdl-view title="Customer selection" default="false" path="transportcustsel.vdl"/>
      <vdl-view title="Transportation plan" default="false" path="transportres.vdl"/>
      <vdl-view title="Result comparison" default="false" path="transportressum.vdl"/>
    </view-group>
  </client>
</model-companion>

transport_graph.mos
(!******************************************************
   Mosel User Guide Example Problems
   ================================= 

   file transport_graph.mos
   ````````````````````````
   Graphical solution output with mmsvg.
   
   (c) 2008 Fair Isaac Corporation
       author: S.Heipcke, 2006, rev. Sep. 2017
*******************************************************!)

model "Transport (Graph)"
 uses "mmxprs", "mmsvg"

 forward procedure draw_solution

 declarations
  REGION: set of string                 ! Set of customer regions
  PLANT: set of string                  ! Set of plants

  DEMAND: array(REGION) of real         ! Demand at regions
  PLANTCAP: array(PLANT) of real        ! Production capacity at plants
  PLANTCOST: array(PLANT) of real       ! Unit production cost at plants
  TRANSCAP: dynamic array(PLANT,REGION) of real
                                        ! Capacity on each route plant->region
  DISTANCE: dynamic array(PLANT,REGION) of real
                                        ! Distance of each route plant->region
  FUELCOST: real                        ! Fuel cost per unit distance

  flow: dynamic array(PLANT,REGION) of mpvar    ! Flow on each route
 end-declarations
 
 initializations from 'transprt.dat'
  DEMAND
  [PLANTCAP,PLANTCOST] as 'PLANTDATA'
  [DISTANCE,TRANSCAP] as 'ROUTES'
  FUELCOST
 end-initializations
 
! 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) 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)
 
 minimize(MinCost)                       ! Solve the problem

 draw_solution                           ! Solution drawing (SVG)

!***********************************************************************
 procedure draw_solution
  declarations
   YP: array(PLANT) of integer           ! y-coordinates of plants
   YR: array(REGION) of integer          ! y-coordinates of sales regions
  end-declarations
  
  ! Scale the size of the displayed graph
  svgsetgraphviewbox(0.25,0.75,3.75,getsize(REGION)+1)
  svgsetgraphscale(100)

  ! Determine y-coordinates for plants and regions  
  ct:= 1+floor((getsize(REGION)-getsize(PLANT))/2)
  forall(p in PLANT, ct as counter) YP(p):= ct

  ct:=1
  forall(r in REGION, ct as counter) YR(r):= ct
  
  ! Draw the plants
  svgaddgroup("PGr", "Plants", svgcolor(0,63,95))
  forall(p in PLANT) svgaddtext(0.55, YP(p)-0.1, p)
  
  ! Draw the sales regions
  svgaddgroup("RGr", "Regions", svgcolor(0,157,169))
  forall(r in REGION) svgaddtext(3.1, YR(r)-0.1, r)
  
  ! Draw all transport routes
  svgaddgroup("TGr", "Routes", SVG_GREY)
  forall(p in PLANT, r in REGION | exists(TRANSCAP(p,r)) ) 
   svgaddline(1, YP(p), 3, YR(r))
   
  ! Draw the routes used by the solution
  svgaddgroup("SGr", "Solution", SVG_ORANGE)
  forall(p in PLANT, r in REGION | exists(flow(p,r)) and getsol(flow(p,r)) > 0)
   svgaddarrow(1, YP(p), 3, YR(r))

  ! Save graphic in SVG format
  svgsave("transport.svg")

  ! Display the graphic
  svgrefresh
  svgwaitclose("Close browser window to terminate model execution.", 1)
 end-procedure

end-model

© 2001-2023 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.