approx.mos |
(!******************************************************
Mosel Example Problems
======================
file approx.mos
```````````````
Function approximation with SOS2
SOS2s are generally used for modeling piecewise approximations
of functions of a single variable. In this example, we aim
to represent f as a function of x and we consider four line
segments between five points. The five points are (R1, F1),
(R2, F2), (R3, F3), (R4, F4) and (R5, F5) and associated with
each point i is a weight variable y(i). Binary variable b(i) is
associated with each of the intervals (R1, R2), (R2, R3), (R3,
R4) and (R4, R5), so 'b(i)' takes value 1 if the value of x
lies between 'R(i)' and 'R(i+1)'.
The SOS2 property of having at most two non-zero 'y(i)', and
if there are two non-zero then they must be adjacent, implies
that we are always on the piece-wise linear function.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Sep. 2006
*******************************************************!)
model "Approximation"
uses "mmxprs"
declarations
NB = 5
BREAKS = 1..NB
R,F: array(BREAKS) of real ! Coordinates of break points
x,f: mpvar ! Decision variables
y: array(BREAKS) of mpvar ! Weight variables
end-declarations
R:: [1, 2.2, 3.4, 4.8, 6.5]
F:: [2, 3.2, 1.4, 2.5, 0.8]
RefRow:= sum(i in BREAKS) R(i)*y(i)
x = RefRow
f = sum(i in BREAKS) F(i)*y(i)
! Convexity constraint
sum(i in BREAKS) y(i) = 1
! SOS2 definition
RefRow is_sos2
! Alternative SOS definition (to be used for 0-valued RefRow coefficients):
! makesos2(union(i in BREAKS) {y(i)}, RefRow)
(! Alternative formulation using binaries instead of SOS2:
declarations
b: array(1..NB-1) of mpvar
end-declarations
sum(i in 1..NB-1) b(i) = 1
forall(i in 1..NB-1) b(i) is_binary
forall(i in BREAKS) y(i) <= if(i>1, b(i-1), 0) + if(i<NB, b(i), 0)
!)
! Bounds
1<=x; x<=6.5
! Solve the problem
minimize(f)
writeln("Objective value: ", getobjval)
writeln("x: ", getsol(x))
end-model
|
|
approx2.mos |
(!******************************************************
Mosel Example Problems
======================
file approx2.mos
````````````````
Function approximation via piecewise linear expression
In this example, we aim to represent f as a function of x
that is specified via four line segments between the five
points (X(i),FX(i)).
We use the 'pwlin' construct to state f as a piecewise linear
constraint that will be handled directly by the MIP solver
although the constraint formulation requires the nonlinear
module 'mmxnlp'.
(c) 2021 Fair Isaac Corporation
author: S. Heipcke, July 2021
*******************************************************!)
model "Approximation (pwlin)"
uses "mmxnlp"
declarations
NB = 5
BREAKS = 1..NB
X,FX: array(BREAKS) of real ! Coordinates of break points
x,f: mpvar ! Decision variables
end-declarations
X:: [1, 2.2, 3.4, 4.8, 6.5]
FX:: [2, 3.2, 1.4, 2.5, 0.8]
f = pwlin(x, union(i in BREAKS) [X(i),FX(i)])
! Bounds
1<=x; x<=6.5
! Solve the problem
minimize(f)
writeln("Objective value: ", getobjval)
writeln("x: ", getsol(x))
end-model
|
|
burglar1.mos |
(!******************************************************
Mosel Example Problems
======================
file burglar1.mos
`````````````````
Knapsack problem
A burglar considers eight items that have different values
and weights. He wants to take a group of items that maximizes
the total value while the total weight is not more than the
maximum 'WTMAX' he can carry.
This IP model represents the so-called knapsack problem where
binary decision variable 'take(i)' takes value 1 if item 'i'
is taken; 0 otherwise.
(c) 2008 Fair Isaac Corporation
author: R.C. Daniel, Jul. 2002
*******************************************************!)
model "Burglar 1"
uses "mmxprs"
declarations
ITEMS = 1..8 ! Index range for items
WTMAX = 102 ! Maximum weight allowed
VALUE: array(ITEMS) of real ! Value of items
WEIGHT: array(ITEMS) of real ! Weight of items
take: array(ITEMS) of mpvar ! 1 if we take item i; 0 otherwise
end-declarations
! Item: 1 2 3 4 5 6 7 8
VALUE :: [15, 100, 90, 60, 40, 15, 10, 1]
WEIGHT:: [ 2, 20, 20, 30, 40, 30, 60, 10]
! Objective: maximize total value
MaxVal:= sum(i in ITEMS) VALUE(i)*take(i)
! Weight restriction
sum(i in ITEMS) WEIGHT(i)*take(i) <= WTMAX
! All variables are 0/1
forall(i in ITEMS) take(i) is_binary
maximize(MaxVal) ! Solve the MIP-problem
! Print out the solution
writeln("Solution:\n Objective: ", getobjval)
forall(i in ITEMS) writeln(" take(", i, "): ", getsol(take(i)))
end-model
|
|
burglar2.mos |
(!******************************************************
Mosel Example Problems
======================
file burglar2.mos
`````````````````
Knapsack problem
A burglar considers eight items that have different values
and weights. He wants to take a group of items that maximizes
the total value while the total weight is not more than the
maximum 'WTMAX' he can carry.
This IP model represents the so-called knapsack problem where
binary decision variable 'take(i)' takes value 1 if item 'i'
is taken; 0 otherwise. This implementation illustrates how
problem data could be read into tables from text files.
Instead of having the item data embedded in the Mosel model
file, we have the data in a file and use 'initializations from'.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Aug. 2002
*******************************************************!)
model "Burglar 2"
uses "mmxprs"
declarations
ITEMS: set of string ! Set of items
WTMAX = 102 ! Maximum weight allowed
VALUE: array(ITEMS) of real ! Value of items
WEIGHT: array(ITEMS) of real ! Weight of items
end-declarations
initializations from 'burglar.dat'
VALUE
WEIGHT
end-initializations
(! alternatively:
initializations from 'burglar2.dat'
[VALUE, WEIGHT] as 'KNAPSACK'
end-initializations
!)
declarations
take: array(ITEMS) of mpvar ! 1 if we take item i; 0 otherwise
end-declarations
! Objective: maximize total value
MaxVal:= sum(i in ITEMS) VALUE(i)*take(i)
! Weight restriction
sum(i in ITEMS) WEIGHT(i)*take(i) <= WTMAX
! All variables are 0/1
forall(i in ITEMS) take(i) is_binary
maximize(MaxVal) ! Solve the MIP-problem
! Print out the solution
writeln("Solution:\n Objective: ", getobjval)
forall(i in ITEMS) writeln(" take(", i, "): ", getsol(take(i)))
end-model
|
|
burglari.mos |
(!******************************************************
Mosel Example Problems
======================
file burglari.mos
`````````````````
Knapsack problem
-- Using string indices --
-- Using string indices --
A burglar considers eight items that have different values
and weights. He wants to take a group of items that maximizes
the total value while the total weight is not more than the
maximum 'WTMAX' he can carry.
This IP model represents the so-called knapsack problem where
binary decision variable 'take(i)' takes value 1 if item 'i'
is taken; 0 otherwise. This implementation illustrates the
use of string indices having the data embedded in the model file.
(c) 2008 Fair Isaac Corporation
author: R.C. Daniel, Jul. 2002
*******************************************************!)
model "Burglar 1 (index set)"
uses "mmxprs"
declarations
ITEMS = {"camera", "necklace", "vase", "picture", "tv", "video",
"chest", "brick"} ! Set for items
WTMAX = 102 ! Maximum weight allowed
VALUE: array(ITEMS) of real ! Value of items
WEIGHT: array(ITEMS) of real ! Weight of items
take: array(ITEMS) of mpvar ! 1 if we take item i; 0 otherwise
end-declarations
VALUE("camera") := 15; WEIGHT("camera") := 2
VALUE("necklace"):=100; WEIGHT("necklace"):= 20
VALUE("vase") := 90; WEIGHT("vase") := 20
VALUE("picture") := 60; WEIGHT("picture") := 30
VALUE("tv") := 40; WEIGHT("tv") := 40
VALUE("video") := 15; WEIGHT("video") := 30
VALUE("chest") := 10; WEIGHT("chest") := 60
VALUE("brick") := 1; WEIGHT("brick") := 10
(! Alternative data initialization:
VALUE :: (["camera", "necklace", "vase", "picture", "tv", "video",
"chest", "brick"])[15, 100, 90, 60, 40, 15, 10, 1]
WEIGHT:: (["camera", "necklace", "vase", "picture", "tv", "video",
"chest", "brick"])[ 2, 20, 20, 30, 40, 30, 60, 10]
!)
! Objective: maximize total value
MaxVal:= sum(i in ITEMS) VALUE(i)*take(i)
! Weight restriction
sum(i in ITEMS) WEIGHT(i)*take(i) <= WTMAX
! All variables are 0/1
forall(i in ITEMS) take(i) is_binary
maximize(MaxVal) ! Solve the MIP-problem
! Print out the solution
writeln("Solution:\n Objective: ", getobjval)
forall(i in ITEMS) writeln(" take(", i, "): ", getsol(take(i)))
end-model
|
|
burglar_rec.mos |
(!******************************************************
Mosel Example Problems
======================
file burglar_rec.mos
````````````````````
Use of records.
A burglar considers eight items that have different values
and weights. He wants to take a group of items that maximizes
the total value while the total weight is not more than the
maximum 'WTMAX' he can carry.
This IP model represents the so-called knapsack problem where
binary decision variable 'take(i)' takes value 1 if item 'i'
is taken; 0 otherwise. This implementation illustrates that
data may also be given in the form of a single record, in this
case the array 'I' which is populated with the data file
burglar_rec.dat.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, July 2006
*******************************************************!)
model "Burglar (records)"
uses "mmxprs"
declarations
WTMAX = 102 ! Maximum weight allowed
ITEMS = {"camera", "necklace", "vase", "picture", "tv", "video",
"chest", "brick"} ! Index set for items
I: array(ITEMS) of record
VALUE: real ! Value of items
WEIGHT: real ! Weight of items
end-record
take: array(ITEMS) of mpvar ! 1 if we take item i; 0 otherwise
end-declarations
initializations from 'burglar_rec.dat'
I
end-initializations
! Objective: maximize total value
MaxVal:= sum(i in ITEMS) I(i).VALUE*take(i)
! Weight restriction
sum(i in ITEMS) I(i).WEIGHT*take(i) <= WTMAX
! All variables are 0/1
forall(i in ITEMS) take(i) is_binary
maximize(MaxVal) ! Solve the MIP-problem
! Print out the solution
writeln("Solution:\n Objective: ", getobjval)
forall(i in ITEMS) writeln(" take(", i, "): ", getsol(take(i)))
end-model
|
|
chess.mos |
(!******************************************************
Mosel Example Problems
======================
file chess.mos
``````````````
Production of chess boards
A small company manufactures two different sizes of boxwood
chess sets. The small set requires 3 lathehours and 1 kg
of boxwood. The large set requires 2 lathehours and 3 kg
of boxwood. There are 160 lathe-hours and 200 kg available
per week. Each large (resp. small) chess set produced and
sold yields a profit of $20 (resp. $5). How many sets of
each kind should be made each week to maximize total profit?
A simple LP model is implemented. After optimization,
'getobjval' returns the optimal objective function value
while 'getsol' returns the decision variables optimal values.
(c) 2008 Fair Isaac Corporation
author: R.C. Daniel, Jul. 2002
*******************************************************!)
model Chess
uses "mmxprs"
declarations
xs, xl: mpvar ! Decision variables: produced quantities
end-declarations
Profit:= 5*xs + 20*xl ! Objective function
Boxwood:= 1*xs + 3*xl <= 200 ! kg of boxwood
Lathe:= 3*xs + 2*xl <= 160 ! Lathehours
maximize(Profit) ! Solve the problem
writeln("LP Solution:") ! Solution printing
writeln(" Objective: ", getobjval)
writeln("Make ", getsol(xs), " small sets")
writeln("Make ", getsol(xl), " large sets")
end-model
|
|
chess2.mos |
(!******************************************************
Mosel Example Problems
======================
file chess2.mos
```````````````
Production of chess boards
A small company manufactures two different sizes of boxwood
chess sets. The small set requires 3 lathehours and 1 kg
of boxwood. The large set requires 2 lathehours and 3 kg
of boxwood. There are 160 lathe-hours and 200 kg available
per week. Each large (resp. small) chess set produced and
sold yields a profit of $20 (resp. $5). How many sets of
each kind should be made each week to maximize total profit?
Analyzing the problem solution further, 'getact' returns
the constraint activities, 'getdual' their dual values
(shadow prices), and 'getrcost' returns the reduced costs
of the decision variables.
(c) 2008 Fair Isaac Corporation
author: R.C. Daniel, Jul. 2002
*******************************************************!)
model "Chess 2"
uses "mmxprs"
declarations
xs, xl: mpvar ! Decision variables: produced quantities
end-declarations
Profit:= 5*xs + 20*xl ! Objective function
Boxwood:= 1*xs + 3*xl <= 200 ! kg of boxwood
Lathe:= 3*xs + 2*xl <= 160 ! Lathehours
maximize(Profit) ! Solve the problem
writeln("LP Solution:") ! Solution printing
writeln(" Objective: ", getobjval)
writeln("Make ", getsol(xs), " small sets")
writeln("Make ", getsol(xl), " large sets")
writeln("Activities/Dual Values")
writeln(" Lathe: ", getact(Lathe)," / ", getdual(Lathe))
writeln(" Boxwood: ", getact(Boxwood)," / ", getdual(Boxwood))
writeln("Reduced Costs")
writeln(" xs: ", getrcost(xs))
writeln(" xl: ", getrcost(xl))
end-model
|
|
pricebrai.mos |
(!******************************************************
Mosel Example Problems
======================
file pricebrai.mos
``````````````````
Modeling price breaks:
All item discount pricing
This implementation represents the situation where we
buy a certain number of items and we get discounts on
all items that we buy if the quantity we buy lies in
certain price bands. We have three price bands. If we
buy a number of items in [0,B1) then for each item we
pay COST1, if the quantity we buy lies in [B1,B2) we
pay COST2 for each item. Finally if we buy an amount
in [B2,B3) then we pay an amount COST3 for each item.
This sort of pricing is called all item discount pricing.
To model these item price breaks we use binary variables
b(i) which takes value 1 if we pay a unit cost of COST(i).
We also define continuous decision variables x1, x2 and
x3 which represent the number of items bought at price
COST1, COST2, and COST3, respectively.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Sep. 2006
*******************************************************!)
model "All item discount"
uses "mmxprs"
declarations
NB = 3 ! Number of price bands
BREAKS = 1..NB
COST: array(BREAKS) of real ! Cost per unit
x: array(BREAKS) of mpvar ! Number of items bought at a price
b: array(BREAKS) of mpvar ! Indicators of price bands
B: array(0..NB) of real ! Break points of cost function
end-declarations
DEM:= 150 ! Demand
B:: [0, 50, 120, 200]
COST:: [ 1, 0.7, 0.5]
forall(i in BREAKS) b(i) is_binary
(! Alternatively
sum(i in BREAKS) B(i)*b(i) is_sos1
!)
! Objective: total price
TotalCost:= sum(i in BREAKS) COST(i)*x(i)
! Meet the demand
sum(i in BREAKS) x(i) = DEM
! Lower and upper bounds on quantities
forall(i in BREAKS) do
B(i-1)*b(i) <= x(i); x(i) <= B(i)*b(i)
end-do
! The quantity bought lies in exactly one interval
sum(i in BREAKS) b(i) = 1
! Solve the problem
minimize(TotalCost)
! Solution printing
writeln("Objective: ", getobjval,
" (price per unit: ", getobjval/DEM, ")")
forall(i in BREAKS)
writeln("Interval ", i, ": ", getsol(x(i)), " (price per unit: ", COST(i), ")")
end-model
|
|
pricebrai2.mos |
(!******************************************************
Mosel Example Problems
======================
file pricebrai2.mos
```````````````````
Modeling price breaks:
All item discount pricing
- formulation as piecewise linear expression -
This implementation represents the situation where we
buy a certain number of items and we get discounts on
all items that we buy if the quantity we buy lies in
certain price bands. We have three price bands. If we
buy a number of items in [0,B1) then for each item we
pay COST1, if the quantity we buy lies in [B1,B2) we
pay COST2 for each item. Finally if we buy an amount
in [B2,B3) then we pay an amount COST3 for each item.
This sort of pricing is called all item discount pricing.
To model these item price breaks we use a 'pwlin'
expression specified via a list of the linear segments.
This general constraint is handled directly by the MIP solver
although the constraint formulation requires the nonlinear
module 'mmxnlp'.
(c) 2021 Fair Isaac Corporation
author: S. Heipcke, July 2021, rev. Sep. 2024
*******************************************************!)
model "All item discount (pwlin)"
uses "mmxnlp"
declarations
NB = 3 ! Number of price bands
BREAKS = 1..NB
COST: array(BREAKS) of real ! Cost per unit
x: mpvar ! Number of items bought
B: array(0..NB) of real ! Break points of cost function
TotalCost: nlctr
end-declarations
DEM:= 150 ! Demand
B:: [0, 50, 120, 200]
COST:: [ 1, 0.7, 0.5]
! Objective: 1- Specification as list of piecewise linear segments
TotalCost:= pwlin(union(i in 1..3) [pws(B(i-1), COST(i)*x)])
! Objective: 2- Specification as list of points
! TotalCost:= pwlin(x, union(i in 1..3) [B(i-1), COST(i)*B(i-1), B(i), COST(i)*B(i)])
! Meet the demand
x = DEM
(! Uncomment to display the problem definition
loadprob(TotalCost)
writeprob("","l")
!)
! Solve the problem
minimize(TotalCost)
! Solution printing
writeln("Objective: ", getobjval,
" (price per unit: ", getobjval/DEM, ")")
forall(i in BREAKS)
writeln("Interval ", i, ": ", if(x.sol>=B(i-1) and x.sol<=B(i),x.sol,0),
" (price per unit: ", COST(i), ")")
end-model
|
|
pricebrinc.mos |
(!******************************************************
Mosel Example Problems
======================
file pricebrinc.mos
```````````````````
Incremental pricebreaks formulated with SOS2
This model represents the situation where we buy a certain
number of items and we get discounts incrementally. The
unit cost for items between 0 and B1 is C1, whereas items
between B1 and B2 cost C2 each, and items between B2 and
B3 cost C3 each.
This implementation uses Special Ordered Sets of type 2
(SOS2). At the points 0, B1, B2 and B3, we introduce continuous
decision variables 'w(i)' (i = 0, 1, 2, 3). We also define cost
break points 'CBP(i)' that correspond to the total cost of buying
quantities 0, B1, B2 and B3. Then, 'w(i)' defines a SOS2 with
reference row coefficients given by the coefficients in the
definition of x. In this example, we use 'makesos2' to define
the SOS2.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Sep. 2006
*******************************************************!)
model "Incremental pricebreaks (SOS2)"
uses "mmxprs"
declarations
NB = 3 ! Number of price bands
BREAKS = 0..NB
COST: array(1..NB) of real ! Cost per unit within price bands
w: array(BREAKS) of mpvar ! Weight variables
x: mpvar ! Total quantity bought
B,CBP: array(BREAKS) of real ! Break points, cost break points
end-declarations
DEM:= 150 ! Demand
B:: [0, 50, 120, 200]
COST:: [0.8, 0.5, 0.3]
CBP(0):= 0
forall(i in 1..NB) CBP(i):= CBP(i-1) + COST(i) * (B(i)-B(i-1))
! Objective: total price
TotalCost:= sum(i in BREAKS) CBP(i)*w(i)
! Meet the demand
x = DEM
! Definition of x
Defx:= x = sum(i in BREAKS) B(i)*w(i)
! Weights sum up to 1
sum(i in BREAKS) w(i) = 1
! Definition of SOS2
! (we cannot use 'is_sos2' since there is a 0-valued coefficient)
makesos2(union(i in BREAKS) {w(i)}, Defx)
! Solve the problem
minimize(TotalCost)
! Solution printing
writeln("Objective: ", getobjval,
" (avg price per unit: ", getobjval/DEM, ")")
forall(i in BREAKS)
writeln("w(", i, "): ", getsol(w(i)), " (price per unit: ",
if(i>0, CBP(i)/B(i), CBP(i)), ")")
end-model
|
|
pricebrinc2.mos |
(!******************************************************
Mosel Example Problems
======================
file pricebrinc2.mos
````````````````````
Incremental pricebreaks formulated with
binary variables
This model represents the situation where we buy a certain
number of items and we get discounts incrementally. The
unit cost for items between 0 and B1 is C1, whereas items
between B1 and B2 cost C2 each, and items between B2 and
B3 cost C3 each.
We model the incremental price breaks by using binary
decision variables. Binary variable 'b(i)' takes value 1
if we have bought any items at a unit cost of 'COST(i)'.
Decision variables 'x(i)' is the number of items bought at
price 'COST(i)'.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Sep. 2006
*******************************************************!)
model "Incremental pricebreaks (binaries)"
uses "mmxprs"
declarations
NB = 3 ! Number of price bands
BREAKS = 1..NB
COST: array(BREAKS) of real ! Cost per unit
x: array(BREAKS) of mpvar ! Number of items bought at a price
b: array(BREAKS) of mpvar ! Indicators of price bands
B: array(0..NB) of real ! Break points of cost function
end-declarations
DEM:= 150 ! Demand
B:: [0, 50, 120, 200]
COST:: [0.8, 0.5, 0.3]
forall(i in BREAKS) b(i) is_binary
! Objective: total price
TotalCost:= sum(i in BREAKS) COST(i)*x(i)
! Meet the demand
sum(i in BREAKS) x(i) = DEM
! Lower and upper bounds on quantities
forall(i in 1..NB-1) (B(i)-B(i-1)) * b(i+1) <= x(i)
forall(i in BREAKS) x(i) <= (B(i)-B(i-1)) * b(i)
! Sequence of price intervals
forall(i in 1..NB-1) b(i) >= b(i+1)
! Solve the problem
minimize(TotalCost)
! Solution printing
writeln("Objective: ", getobjval,
" (avg price per unit: ", getobjval/DEM, ")")
forall(i in BREAKS)
writeln("x(", i, "): ", getsol(x(i)), " (price per unit: ", COST(i), ")")
end-model
|
|
pricebrinc3.mos |
(!******************************************************
Mosel Example Problems
======================
file pricebrinc3.mos
````````````````````
Incremental pricebreaks formulated with
piecewise linear expressions
This model represents the situation where we buy a certain
number of items and we get discounts incrementally. The
unit cost for items between 0 and B1 is C1, whereas items
between B1 and B2 cost C2 each, and items between B2 and
B3 cost C3 each.
We model the incremental price breaks via 'pwlin' expressions.
Three different versions can be used for representing
this particular case of a continuous cost function.
This general constraint is handled directly by the MIP solver
although the constraint formulation requires the nonlinear
module 'mmxnlp'.
(c) 2021 Fair Isaac Corporation
author: S. Heipcke, July 2021
*******************************************************!)
model "Incremental pricebreaks (pwlin)"
uses "mmxnlp"
declarations
NB = 3 ! Number of price bands
BREAKS = 0..NB
COST: array(1..NB) of real ! Cost per unit within price bands
x: mpvar ! Total quantity bought
B,CBP: array(BREAKS) of real ! Break points, cost break points
end-declarations
DEM:= 150 ! Demand
B:: [0, 50, 120, 200]
COST:: [0.8, 0.5, 0.3]
CBP(0):= 0
forall(i in 1..NB) CBP(i):= CBP(i-1) + COST(i) * (B(i)-B(i-1))
! Objective: total price (uncomment one of the three following options)
! 1- Specification as a list of slopes with associated intervals:
! (only points of slope changes are specified, the start value is 0):
!TotalCost:= pwlin(x, union(i in 1..2) [B(i)], union(i in 1..3) [COST(i)])
! 2- Specification as a list of piecewise linear segments (pws) with associated intervals:
TotalCost:= pwlin(union(i in 1..3) [pws(B(i-1), CBP(i-1)+COST(i)*(x-B(i-1)))])
! 3- Specification as a list of points:
!TotalCost:= pwlin(x, union(i in 0..3) [B(i), CBP(i)])
! Meet the demand
x = DEM
! Solve the problem
minimize(TotalCost)
! Solution printing
writeln("Objective: ", getobjval,
" (avg price per unit: ", getobjval/DEM, ")")
forall(i in 1..NB)
writeln("Interval ", i, ": ", minlist(B(i)-B(i-1),x.sol-B(i-1)), " (price per unit: ", COST(i), ")")
end-model
|
|