c1bike.mos |
(!******************************************************
Mosel Example Problems
======================
file c1bike.mos
```````````````
Planning the production of bicycles
A sales forecast shows the predicted bicycle demand for the
upcoming year. There is a set production capacity per month
but it can be increased with overtime (with additional costs).
The company can store excess bikes at a small cost with no
limit to quantity. How many bikes need to be produced and
stored in the next year to meet the forecasted demand while
minimizing total (production, overtime, storage) cost?
This implementation using the inline 'if' function to condense
the balance constraints since this varies for t=1 and t>1.
Note that there is no slack built into the demand forecast so
bike storage will be as low as possible to reduce total cost.
This may not be practical if there is an unpredicted spike in
demand.
(c) 2008-2022 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)
model "C-1 Bicycle production"
uses "mmxprs"
declarations
TIMES = 1..12 ! Range of time periods
DEM: array(TIMES) of integer ! Demand per months
CNORM,COVER: integer ! Prod. cost in normal / overtime hours
CSTOCK: integer ! Storage cost per bicycle
CAP: integer ! Monthly capacity in normal working hours
ISTOCK: integer ! Initial stock
pnorm:array(TIMES) of mpvar ! No. of bicycles produced in normal hours
pover:array(TIMES) of mpvar ! No. of bicycles produced in overtime hours
store:array(TIMES) of mpvar ! No. of bicycles stored per month
end-declarations
initializations from 'c1bike.dat'
DEM CNORM COVER CSTOCK CAP ISTOCK
end-initializations
! Objective: minimize production cost
Cost:= sum(t in TIMES) (CNORM*pnorm(t) + COVER*pover(t) + CSTOCK*store(t))
! Satisfy the demand for every period
forall(t in TIMES)
pnorm(t) + pover(t) + if(t>1, store(t-1), ISTOCK) = DEM(t) + store(t)
! Capacity limits on normal and overtime working hours per month
forall(t in TIMES) do
pnorm(t) <= CAP
pover(t) <= 0.5*CAP
end-do
! Solve the problem
minimize(Cost)
! Solution printing
declarations
MONTHS: array(TIMES) of string ! Names of months
end-declarations
initializations from 'c1bike.dat'
MONTHS
end-initializations
writeln("Total cost: ", getobjval)
write(" ")
forall(t in TIMES) write(strfmt(MONTHS(t),4))
setparam("realfmt", "%4g") ! Reserve 4 char.s for display of real numbers
write("\nDemand ")
forall(t in TIMES) write(DEM(t)/1000)
write("\nNormal ")
forall(t in TIMES) write(getsol(pnorm(t))/1000)
write("\nAdd. ")
forall(t in TIMES) write(getsol(pover(t))/1000)
write("\nStore ")
forall(t in TIMES) write(getsol(store(t))/1000)
writeln
end-model
|
|
c2glass.mos |
(!******************************************************
Mosel Example Problems
======================
file c2glass.mos
````````````````
Planning the production of glasses
A French company produces 6 types of drinking glasses.
Each product has varying production cost, storage cost,
initial stock, and storage space requirements. The time it
take a work and machine to create each batch of glasses
also varies. How much of each type of glasses should be
produced in each period so that the total (production and
storage) cost be minimized?
A balance constraint is necessary to define the glasses
stored from one period to the next. Note that the production
variable cannot be named 'prod' and the set of products
cannot be named 'PROD' as 'prod' is a reserved word since
it is a keyword of Mosel.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002
*******************************************************!)
model "C-2 Glass production"
uses "mmxprs", "mmsystem"
declarations
NT = 12 ! Number of weeks in planning period
WEEKS = 1..NT
PRODS = 1.. 6 ! Set of products
CAPW,CAPM: integer ! Capacity of workers and machines
CAPS: integer ! Storage capacity
DEM: array(PRODS,WEEKS) of integer ! Demand per product and per week
CPROD: array(PRODS) of integer ! Production cost per product
CSTOCK: array(PRODS) of integer ! Storage cost per product
ISTOCK: array(PRODS) of integer ! Initial stock levels
FSTOCK: array(PRODS) of integer ! Min. final stock levels
TIMEW,TIMEM: array(PRODS) of integer ! Worker and machine time per unit
SPACE: array(PRODS) of integer ! Storage space required by products
produce: array(PRODS,WEEKS) of mpvar ! Production of products per week
store: array(PRODS,WEEKS) of mpvar ! Amount stored at end of week
end-declarations
initializations from 'c2glass.dat'
CAPW CAPM CAPS DEM CSTOCK CPROD ISTOCK FSTOCK TIMEW TIMEM SPACE
end-initializations
! Objective: sum of production and storage costs
Cost:=
sum(p in PRODS, t in WEEKS) (CPROD(p)*produce(p,t) + CSTOCK(p)*store(p,t))
! Stock balances
forall(p in PRODS, t in WEEKS)
store(p,t) = if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - DEM(p,t)
! Final stock levels
forall(p in PRODS) store(p,NT) >= FSTOCK(p)
! Capacity constraints
forall(t in WEEKS) do
sum(p in PRODS) TIMEW(p)*produce(p,t) <= CAPW ! Workers
sum(p in PRODS) TIMEM(p)*produce(p,t) <= CAPM ! Machines
sum(p in PRODS) SPACE(p)*store(p,t) <= CAPS ! Storage
end-do
! Solve the problem
minimize(Cost)
! Solution printing
writeln("Total cost: ",getobjval)
writeln("Production plan:")
write(" Week")
forall(t in WEEKS) write(textfmt(t,7))
writeln
forall(p in PRODS) do
write(p,": Prod. ")
forall(t in WEEKS) write(textfmt(getsol(produce(p,t)),7))
writeln
write(" Store ")
forall(t in WEEKS) write(textfmt("("+getsol(store(p,t))+")",7))
writeln
end-do
writeln("\nCapacities used:")
writeln(formattext("Week%8s%9s%7s","Workers","Machines","Space"))
forall(t in WEEKS)
writeln(formattext("%2d%8g%10.2f%9.2f", t,
getsol(sum(p in PRODS) TIMEW(p)*produce(p,t)),
getsol(sum(p in PRODS) TIMEM(p)*produce(p,t)),
getsol(sum(p in PRODS) SPACE(p)*store(p,t))) )
end-model
|
|
c3toy.mos |
(!******************************************************
Mosel Example Problems
======================
file c3toy.mos
``````````````
Planning the production of toy lorrys
A company produces two types of large toy lorry (trucks).
Each toy has 13 components. A subset of items can be assembled
by the company or subcontracted. Given the demand is the
same for both toys, how much should the company buy or
subcontract to meet demand and minimize cost?
Index sets are not fixed and are instead initialized from
the data file when reading the array data. The index sets of dense
arrays are automatically finalized by Mosel. As a consequence,
the arrays of decision variables 'produce' and 'buy' that are
declared in the same declarations block and are first accessed after
data has been initialized (when their index sets are known and
have been finalized) will be created automatically without any
need for an explicit call of the function 'create'.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002, re. Mar. 2022
*******************************************************!)
model "C-3 Toy production"
uses "mmxprs", "mmsystem"
declarations
ITEMS: set of string ! Set of all products
FINAL: set of string ! Set of final products
ASMBL: set of string ! Set of assembled products
PREPROD: set of string ! Set of preproducts
CAP: array(ASMBL) of integer ! Capacity of assembly lines
DEM: array(FINAL) of integer ! Demand of lorrys
CPROD: array(ASMBL) of real ! Assembly costs
CBUY: array(ITEMS) of real ! Purchase costs
REQ: array(ASMBL,PREPROD) of integer ! Items req. for assembling a product
produce: array(ASMBL) of mpvar ! Quantity of items produced
buy: array(PREPROD) of mpvar ! Quantity of items bought
end-declarations
initializations from 'c3toy.dat'
DEM CBUY REQ
[CPROD, CAP] as 'ASSEMBLY'
end-initializations
! Objective: total costs
Cost:= sum(p in PREPROD) CBUY(p)*buy(p) +
sum(p in ASMBL) CPROD(p)*produce(p)
! Satisfy demands
forall(p in FINAL) produce(p) >= DEM(p)
! Assembly balance
forall(p in PREPROD) buy(p) + if(p in ASMBL, produce(p), 0) >=
sum(q in ASMBL) REQ(q,p)*produce(q)
! Limits on assembly capacity
forall(p in ASMBL) produce(p) <= CAP(p)
forall(p in PREPROD) buy(p) is_integer
forall(p in ASMBL) produce(p) is_integer
! Solve the problem
minimize(Cost)
! Solution printing
writeln("Total cost: ",getobjval)
writeln("Buy:")
forall(p in PREPROD)
writeln(formattext(" %-18s: %5g", p, getsol(buy(p))))
writeln("Produce:")
forall(p in ASMBL)
writeln(formattext(" %-18s: %5g", p, getsol(produce(p))))
end-model
|
|
c4compo.mos |
(!******************************************************
Mosel Example Problems
======================
file c4compo.mos
````````````````
Planning the production of electronic components
A company produces cards with microchips and electronic
badges. They also produce the components for these. The
company would like to meet the forecasted demand while
minimizing the cost associated to production, storage,
and product changes.
This is a simple planning problem with an addition of
one new cost type (product changes). A balance constraint
is necessary to define the products stored from one period
to the next.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002
*******************************************************!)
model "C-4 Electronic components"
uses "mmxprs"
declarations
NT = 6 ! Number of time periods (months)
MONTHS = 1..NT
PRODS = 1..4 ! Set of components
DEM: array(PRODS,MONTHS) of integer ! Demand of components per month
CPROD: array(PRODS) of integer ! Production costs
CSTOCK: array(PRODS) of real ! Storage costs
CADD,CRED: real ! Cost of additional/reduced prod.
ISTOCK,FSTOCK: array(PRODS) of integer ! Initial and final stock levels
produce: array(PRODS,MONTHS) of mpvar ! Quantities produced per month
store: array(PRODS,MONTHS) of mpvar ! Stock levels at end of every month
reduce: array(MONTHS) of mpvar ! Reduction of production per month
add: array(MONTHS) of mpvar ! Increase of production per month
end-declarations
initializations from 'c4compo.dat'
DEM CPROD CSTOCK CADD CRED ISTOCK FSTOCK
end-initializations
! Objective: total cost of production, storage, and change of prod. level
Cost:= sum(p in PRODS, t in MONTHS) (CPROD(p)*produce(p,t) +
CSTOCK(p)*store(p,t)) +
sum(t in 2..NT) (CRED*reduce(t) + CADD*add(t))
! Stock balance constraints (satisfy demands)
forall(p in PRODS, t in MONTHS)
store(p,t) = if(t>1, store(p,t-1), ISTOCK(p)) + produce(p,t) - DEM(p,t)
! Changes to the level of production
forall(t in 2..NT)
sum(p in PRODS) (produce(p,t) - produce(p,t-1)) = add(t) - reduce(t)
! Guarantee final stock levels
forall(p in PRODS) store(p,NT) >= FSTOCK(p)
! Solve the problem
minimize(Cost)
! Solution printing
declarations
PNAME: array(PRODS) of string ! Product names
end-declarations
initializations from 'c4compo.dat'
PNAME
end-initializations
writeln("Total cost: ",getobjval)
write(strfmt("Month",13))
forall(t in MONTHS) write(strfmt(t,5))
forall(p in PRODS) do
write("\n", PNAME(p), ": Prod. ")
forall(t in MONTHS) write(strfmt(getsol(produce(p,t)),5))
write("\n", strfmt("Store ",14))
forall(t in MONTHS) write(strfmt("("+store(p,t).sol+")",5))
end-do
write("\nTotal ")
forall(t in MONTHS) write(strfmt(sum(p in PRODS) produce(p,t).sol,5))
writeln
end-model
|
|
c5fiber.mos |
(!******************************************************
Mosel Example Problems
======================
file c5fiber.mos
````````````````
Planning the production of fiberglass
The next 6 weeks of fiberglass production needs to be
planned. Capacity is limited and varies by week. Production
and storage costs also change over time. Determine
the plan that minimizes total cost of production and
storage while meeting demand for the time period.
This problem introduces a transshipment flow formulation.
The demand and capacity data are represented as node weights
and are combined into a single array 'WEIGHT'. 'ARC' defines
the cost of flow between nodes. Note that since the array of
variables 'flow' is dynamic, it must be created after the data is
read and only for node combinations where 'ARC' exists. Two new
functions are introduced here: 'isodd' determines if an integer
value is odd or even and 'getlast' returns the last entry of a
range or a list.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002, rev. Nov. 2017
*******************************************************!)
model "C-5 Fiberglass"
uses "mmxprs"
declarations
NODES: range ! Production and demand nodes
! odd numbers: production capacities
! even numbers: demands
ARC: dynamic array(NODES,NODES) of real ! Cost of flow on arcs
WEIGHT: array(NODES) of integer ! Node weights (capacities/demand)
flow: dynamic array(NODES,NODES) of mpvar ! Flow on arcs
end-declarations
initializations from 'c5fiber.dat'
ARC WEIGHT
end-initializations
forall(m,n in NODES | exists(ARC(m,n))) create(flow(m,n))
! Objective: total cost of production and storage
Cost:= sum(m,n in NODES | exists(ARC(m,n))) ARC(m,n)*flow(m,n)
! Satisfy demands (flow balance constraints)
forall(n in NODES | isodd(n)=FALSE)
if(n>2, flow(n-2,n), 0) + flow(n-1,n) =
if(n<getlast(NODES), flow(n,n+2), 0) + WEIGHT(n)
! Production capacities
forall(n in NODES | isodd(n)) flow(n,n+1) <= WEIGHT(n)
! Solve the problem
minimize(Cost)
! Solution printing
writeln("Total cost: ",getobjval)
write("Week")
forall(t in 1..integer(getlast(NODES)/2)) write(strfmt(t,5))
write("\nProd.")
forall(n in NODES | isodd(n))
write(strfmt(getsol(sum(m in NODES) flow(n,m)),5))
write("\nStock")
forall(n in NODES | not(isodd(n)))
write(strfmt(getsol(sum(m in NODES) flow(n,m)),5))
writeln
end-model
|
|
c6assign.mos |
(!******************************************************
Mosel Example Problems
======================
file c6assign.mos
`````````````````
Machine assignment for production batches
10 batches must be produced in the upcoming period. There
are 5 machines that can produce any given batch. However,
processing time and cost depends on machine assignment.
Each machine has a max production capacity. Determine the
batch to machine assignment that minimizes the total cost
of production.
This is a generalized assignment problem and is a very
compact mathematical model. Each batch must be assigned
to only one machine and each machine must produce no more
than its specified capacity.
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002
*******************************************************!)
model "C-6 Machine assignment"
uses "mmxprs"
declarations
MACH = 1..5 ! Set of machines
PRODS = 1..10 ! Set of production batches
CAP: array(MACH) of integer ! Machine capacities
DUR: array(MACH,PRODS) of integer ! Production durations
COST: array(MACH,PRODS) of integer ! Production costs
use: array(MACH,PRODS) of mpvar ! 1 if machine assigned to batch,
! 0 otherwise
end-declarations
initializations from 'c6assign.dat'
DUR CAP COST
end-initializations
! Objective: total production cost
Cost:= sum(m in MACH, p in PRODS) COST(m,p)*use(m,p)
! Assign a single machine to every batch
forall(p in PRODS) sum(m in MACH) use(m,p) = 1
! Limits on machine capacities
forall(m in MACH) sum(p in PRODS) DUR(m,p)*use(m,p) <= CAP(m)
forall(m in MACH, p in PRODS) use(m,p) is_binary
! Solve the problem
minimize(Cost)
! Solution printing
writeln("Total cost: ",getobjval)
forall(m in MACH) do
write("Machine ", m, ": ")
forall(p in PRODS)
if (getsol(use(m,p))=1) then
write(p, " ")
end-if
writeln(" (total duration: ", getsol(sum(p in PRODS) DUR(m,p)*use(m,p)), ")")
end-do
end-model
|
|