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="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: £"></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 |