Transport - Insight GUI, user graph
|
|
Type: | Transportation problem |
Rating: | 3 (intermediate) |
Description: |
|
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="5"> <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="5"> <!-- 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="5"> <!-- '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: £"></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="5"> <!-- '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.