Initializing help system before first use

Data handling basics

Topics covered in this section:

model "Chess 3"
 uses "mmxprs"

 declarations
  R = 1..2                             ! Index range
  DUR, WOOD, PROFIT: array(R) of real  ! Coefficients
  x: array(R) of mpvar                 ! Array of variables
 end-declarations

 DUR   :: [3, 2]                       ! Initialize data arrays
 WOOD  :: [1, 3]
 PROFIT:: [5, 20]

 sum(i in R) DUR(i)*x(i) <= 160        ! Constraint definition
 sum(i in R) WOOD(i)*x(i) <= 200
 forall(i in R) x(i) is_integer

 maximize(sum(i in R) PROFIT(i)*x(i))
 writeln("Solution: ", getobjval)
end-model

Data types

Constant data
declarations
  NWEEKS = 20
  NDAYS = 7*NWEEKS
  CONV_RATE = 1.425
  DATA_DIR = 'c:\data'
end-declarations
Variable data
  Declaration
declarations
  NPROD: integer
  SCOST: real
  MAXREFVEG: real
  DIR: string
  IF_DEBUG: boolean
  HARD: array(1..5) of real
  COST: array(1..3,1..4) of real
end-declarations
  Initialization
NPROD := 20
SCOST := 5
MAXREFVEG := 200.0
DIR := 'c:\data'
IF_DEBUG := true
HARD :: [8.8, 6.1, 2.0, 4.2, 5.0]
COST :: [11, 12, 13, 14,
         21, 22, 23, 24,
         31, 32, 33, 34]

Sums and loops

Summations
Sum up an array of variables in a constraint:
MaxCap := sum(p in 1..10) buy(p) <= 100

MaxCap := sum(p in 1..10) (buy(p) + sum(r in 1..5) make(p,r)) <= 100

MaxCap := sum(p in 1..NP, t in 1..NT)
          CAP(p)*buy(p,t) <= MAXCAP

MaxCap := sum(p in 1..NP) (2*CAP(p)*buy(p)/10 +
          SCAP(p)*sell(p)) <= MAXCAP
Loops
Use a loop to assign an array of constraints:
forall(t in 2..NT)
  Inven(t) := bal(t) = bal(t-1) + buy(t) - sell(t)
Use do/ end-do to group several statements into one loop
forall(t in 1..NT) do
  MaxRef(t) := sum(i in 1..NI) use(i,t) <= MAXREF(t)

  Inven(t) := store(t) = store(t-1) + buy(t) - use(t)
end-do
Can nest forall statements:
forall(t in 1..NT) do
  MaxRef(t) := sum(i in 1..NI) use(i,t) <= MAXREF(t)

  forall(i in 1..NI)
    Inven(i,t) := store(i,t) = store(i,t-1) + buy(i,t) - use(i,t)
end-do
Similarly for specification of bounds (a bound is just a simple unnamed constraint):
forall(i in 1..NI) do
  forall(t in 1..NT) store(i,t) <= MAXSTORE(t)
  store(i,0) = STORE0
end-do
May include conditions in sums or loops:
forall(c in 1..10 | CAP(c)>=100.0)
  MaxCap(c) :=
    sum(i in 1..10, j in 1..10 | i<>j)
      TECH(i,j,c)*x(i,j,c) <= MAXTECH(c)

Index sets

Explicit statement:
declarations
  MaxCap: array(1..10) of linctr
end-declarations

forall(d in 1..10)
  MaxCap(d) :=
    sum(p in 1..10, m in 1..10)
      TECH(p,m,d)*x(p,m,d) <= MAXTECH(d)
Defining named sets:
declarations
  PRODUCTS = 1..5
  MATERIALS = {12,487,163}
  DEPOTS = {"Boston","New York","Atlanta"}

  MaxCap: array(DEPOTS) of linctr
end-declarations

forall(d in DEPOTS)
  MaxCap(d) :=
    sum(p in PRODUCTS, m in MATERIALS)
      TECH(p,m,d)*x(p,m,d) <= MAXTECH(d)
Using named sets
  • improves the readability of a model
  • makes it easier to apply the model to different sized data sets
  • makes the model easier to maintain

Reading data in from text files

Read data into COST from cost.dat
initializations from 'cost.dat'
  COST
end-initializations
Data file cost.dat (dense data format)
COST : [3.9 0 4.8
        0 7.5 5.5]
Data file cost2.dat (sparse data format)
COST: [("Oil1" 1) 3.9  ("Oil1" 3) 4.8
       ("Oil2" 2) 7.5  ("Oil2" 3) 5.5]
Mosel data format:
  • file may include single line comments, marked with '!'
  • format: label, colon, data value(s)
  • for an array, use a single list enclosed in [ ]
  • list may be comma or space separated
  • dense format: the values fill the data table starting at the first position and varying the last index most rapidly
  • sparse format: each data item is preceded by the corresponding index tuple (in brackets)
Specifying the absolute path
initializations from 'c:/data/cost.dat'
  COST
end-initializations
Path relative to current working directory
initializations from '../cost.dat'
  COST
end-initializations
Read several data tables from a single file
initializations from 'cost.dat'
  SCOST
  PCOST
end-initializations
Different data label and model object names
initializations from 'cost.dat'
  COST as 'COST_DETAILS'
end-initializations
Read several data arrays with identical index sets from a single table
 
initializations from 'chess.dat'
  [DUR,WOOD,PROFIT] as 'ChessData'
end-initializations

Writing data out to text files

You can write out values in an analogous way to reading them in

initializations to 'cost.dat'
  COST
end-initializations

To write out the solution values of variables, or other solution values (slack, activity, dual, reduced cost) you must first put the values into a data table

declarations
  make_sol: array(ITEMS,TIME) of real
  obj_sol: real
end-declarations

forall(i in ITEMS, t in TIME)
  make_sol(i,t) := getsol(make(i,t))

obj_sol := getobjval

initializations to 'make.dat'
  make_sol
  obj_sol
end-initializations

Alternatively, you can use evaluation of directly in the initializations block

initializations to 'make.dat'
  evaluation of
    array(i in ITEMS, t in TIME) getsol(make(i,t)) as 'make_sol'
  evaluation of getobjval as 'obj_sol'
end-initializations

User defined data formats

Mosel also provides functions which allow you to read data in from and write data out to text files using any format (see list in Section Built in functions and procedures).

Reading in free format data
declarations
  ii, jj: integer    ! Don't use normal i,j
end-declarations

fopen('cost.dat', F_INPUT)
while(not iseof)
  readln(ii, ',', jj, ',', COST(ii,jj))
fclose(F_INPUT)
Writing out data in user format
fopen('xsol.dat', F_OUTPUT)
forall(s in SUP, d in DEP)
  writeln(s, ',', d, ',', getsol(x(s,d)))
fclose(F_OUTPUT)

Using other data sources

The initializations block can work with many different data sources and formats thanks to the notion of I/O drivers.

I/O drivers for physical data files:
  • mmodbc.odbc for databases with ODBC connector
  • mmsheet.excel for MS Excel spreadsheets
  • mmsheet.xls and mmsheet.xlsx for generic spreadsheet access, including on non-Windows platforms
  • mmsheet.csv for CSV format files
  • mmoci.oci for Oracle databases
  • mmetc.diskdata for mp-model style data files

Other drivers are available, e.g. for data exchange in memory between models or between a model and the host application.

Change of the data source = change of the I/O driver, no other modifications to your model

initializations from "mmsheet.xls:mydat.xls"
 COST as 'CostData'
end-initializations

initializations to "mmodbc.odbc:mydat.mdb"
 SOL as 'SolTable'
end-initializations

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