Usage Examples
Simple Model
This is a version of the 'chess2' example, modified to be an Xpress Insight project. It demonstrates how to write a model so that Xpress Insight can capture or inject the model's input data, depending upon the run mode, while still allowing the model developer to run the model from outside of Xpress Insight, e.g. in IVE.
model Chess2 uses "mmxprs" ! Load the Xpress-Optimizer uses "mminsight" ! Load the Insight interface public declarations ! Model inputs UnitTypes: set of string ResourceTypes: set of string ResourceLimits: array(ResourceTypes) of real ProfitPerUnit: array(UnitTypes) of real UnitResourceRequirements: array(UnitTypes,ResourceTypes) of real ! Mathematical model objects (providing model results) unitstobuild: array(UnitTypes) of mpvar ResourceLimitConstraints: array(ResourceTypes) of linctr MaxProfit: linctr end-declarations ! Procedure to populate model with initial input data procedure loaddata ProfitPerUnit:: (["small","large"])[5,20] UnitResourceRequirements:: (["small"],["wood","mc_time"]) [1,3] UnitResourceRequirements:: (["large"],["wood","mc_time"]) [3,2] ResourceLimits:: (["wood","mc_time"])[200,400] finalize( UnitTypes ) finalize( ResourceTypes ) end-procedure ! Procedure to build and solve optimization problem procedure runproblem ! Build whole units only forall(u in UnitTypes) unitstobuild(u) is_integer ! Define profit MaxProfit:= sum(u in UnitTypes) ProfitPerUnit(u)*unitstobuild(u) ! Don't use more than available resources forall(r in ResourceTypes) ResourceLimitConstraints(r) := ( sum(u in UnitTypes) UnitResourceRequirements(u,r)*unitstobuild(u) ) <= ResourceLimits(r) ! Solve the mixed integer problem insightmaximize(MaxProfit) ! Print the solution to the run log writeln("Solution:\n Objective: ", getobjval) forall(u in UnitTypes) writeln(u, ":", unitstobuild(u).sol) end-procedure ! Perform actions based on how model is being executed case insightgetmode of INSIGHT_MODE_LOAD: do ! Scenario is being 'loaded' through Xpress Insight ! Initialize input arrays and then terminate loaddata end-do INSIGHT_MODE_RUN: do ! Scenario is being 'run' through Xpress Insight ! Populate with Insight scenario data and then solve optimization insightpopulate runproblem end-do INSIGHT_MODE_NONE: do ! Model is being run outside of Xpress Insight, e.g. in IVE ! Initialize input arrays then solve optimization loaddata runproblem end-do else writeln("Unknown execution mode") end-case end-model
Accessing Attachments
As described in the Developer Guide, Xpress Insight allows files to be attached to a project or scenario. While the model is running within Xpress Insight, the Mosel interface will allow you to query, read and edit attachments of the scenario being run, as well as query and read (but not edit) attachments of the project to which that scenario belongs.
To demonstrate the use of project and scenario attachments, in this example we have a Distances array that we want to populate with distances between cities. As this will not change, it would be very wasteful to store a copy of these in every scenario of the project, so we store them in a file distances.dat which is attached to the project. In the example, we call insightgetprojattach to copy this file to the working directory and then populate the Distances array from this. (It is assumed that the project has a companion-file that configures the Distances array as unmanaged by Xpress Insight.)
To demonstrate the use of scenario attachments, we then save the model's results to a file decorated with today's date, and attach this file to the current scenario.
model RoutePlanner uses "mmxprs" ! Load the Xpress-Optimizer uses "mminsight" ! Load the Insight interface public declarations EvaluationDate: string Cities: set of string Distances: array(Cities,Cities) of real TrafficLevels: array(Cities,Cities) of real routetaken: array(Cities,Cities) of mpvar end-declarations ! Procedure to build and solve optimization problem procedure runproblem ! Download project attachment if insightgetmode <> INSIGHT_MODE_NONE then ! Model is running within Insight, so download distances.dat from Insight server insightgetprojattach("distances.dat") if insightattachstatus<>INSIGHT_ATTACH_OK then writeln("Failed to download project attachmentt") exit(1) end-if else ! Model is running outside of Insight, attachments are not accessible so copy from some other location fcopy( '/Users/me/myfiles/distances.dat', 'distances.dat' ) end-if ! Load into model initializations from "distances.dat" Distances end-initializations ! Perform optimization buildproblem optimizeproblem ! Capture results to file ROUTES_FNAME := "result-"+EvaluationDate+".dat" fopen(ROUTES_FNAME,F_OUTPUT) forall (s in Cities, d in Cities | routetaken(s,d).sol=1) writeln(s,"->",d) fclose(F_OUTPUT) ! Store as scenario attachment if insightgetmode <> INSIGHT_MODE_NONE then ! Model is running within Insight, so upload distances.dat to Insight server insightputscenattach(ROUTES_FNAME) if insightattachstatus<>INSIGHT_ATTACH_OK then writeln("Failed to upload scenario attachment") exit(1) end-if end-if end-procedure case insightgetmode of INSIGHT_MODE_LOAD: do loaddata end-do INSIGHT_MODE_RUN: do insightpopulate runproblem end-do INSIGHT_MODE_NONE: do loaddata runproblem end-do else writeln("Unknown execution mode") end-case end-model
For clarity, the implementation of the loaddata, buildproblem and optimizeproblem procedures have been omitted from the example.
Inter-Scenario Data Access
You can also initialize your data structures with values from external scenarios using the mminsight.scenariodata I/O driver with a standard Mosel initializations-from block. For example, the following model initializes the array "Distances" from an array called "CityDrivingDistances" in a scenario "USDrivingDistances" in a project named "DrivingDistancesModel"
model RoutePlanner uses "mmxprs" ! Load the Xpress-Optimizer uses "mminsight" ! Load the Insight interface public declarations Cities: set of string Distances: array(Cities,Cities) of real TrafficLevels: array(Cities,Cities) of real routetaken: array(Cities,Cities) of mpvar end-declarations ! Procedure to build and solve optimization problem procedure runproblem ! Populate 'Distances' array if insightgetmode <> INSIGHT_MODE_NONE then ! Populate 'Distances' array from the remote scenario initializations from "mminsight.scenariodata:/DrivingDistancesModel/USDrivingDistances" Distances as "CityDrivingDistances" end-initializations else ! Model is running outside of Insight, so populate driving distances from local file initializations from "/Users/me/myfiles/distances.dat" Distances end-initializations end-if ! Perform optimization buildproblem optimizeproblem end-procedure case insightgetmode of INSIGHT_MODE_LOAD: do loaddata end-do INSIGHT_MODE_RUN: do insightpopulate runproblem end-do INSIGHT_MODE_NONE: do loaddata runproblem end-do else writeln("Unknown execution mode") end-case end-model
For clarity, the implementation of the loaddata, buildproblem and optimizeproblem procedures have been omitted from the example.
Annotations
The handling of model (schema) entities by Insight and certain global settings such as execution modes or unit conversions are configured via annotations to the Mosel model. The following Mosel model extract shows some examples of annotation definitions.
!@insight.manage=input public declarations ! All entities declared here are managed as input !@insight.alias Suppliers !@insight.descr Set of all suppliers SUPP: set of string DEP: set of string !@insight.alias Depots DIST: array(SUPP,DEP) of real !@insight.unit mile end-declarations ! The 'insight.units' or 'insight.execmodes' annotations must be stated as global ! annotations, so not immediately preceding 'declarations' ! Define a unit 'mile' with conversion rules for 'meter' and 'kilometer' (!@insight.units.mile. @name mile @abbreviation mi @conversion.meter.factor=1609.34 @conversion.kilometer.scale=0.621373 !) ! Define an execution mode 'analyzedata' (!@insight.execmodes.analyzedata. @descr Analyzing input data @clearinput false @threads 1 !) case insightgetmode of "analyzedata": do loaddata analyzedata end-do INSIGHT_MODE_LOAD: do loaddata end-do !... ! Handling of other execution modes end-case