| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Loading and cutting problems Description
Further explanation of this example: 'Applications of optimization with Xpress-MP', Chapter 9: Loading and cutting stock problems
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Data Files
d3tanks.mos
(!******************************************************
Mosel Example Problems
======================
file d3tanks.mos
````````````````
Loading of liquid chemicals into tanks
Five tanker ships filled with liquids must be unloaded
into storage tanks. The 5 liquids must not be mixed.
(1) How should the ships be unloaded to maximize the capacity
of unused tanks? (2) How should they be unloaded to maximize
the number of unused tanks?
The storage tanks are defined as a range of consecutive
integers whereas the liquids are identified by their names.
Entries of the decision variable array 'load' are created
dynamically depending on the initial configuration data.
This problem calls the custom 'printsol' procedure after
minimizing each objective.
(c) 2008-2022 Fair Isaac Corporation
author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)
model "D-3 Tank loading"
uses "mmxprs"
forward procedure printsol
declarations
TANKS: range ! Set of tanks
LIQ: set of string ! Set of liquids
CAP: array(TANKS) of integer ! Tank capacities
TINIT: array(TANKS) of string ! Initial tank contents type
QINIT: array(TANKS) of integer ! Quantity of initial contents
ARR: array(LIQ) of integer ! Arriving quantities of chemicals
REST: array(LIQ) of integer ! Rest after filling part. filled tanks
ifload: dynamic array(LIQ,TANKS) of mpvar ! 1 if liquid loaded into tank,
! 0 otherwise
end-declarations
initializations from 'd3tanks.dat'
CAP ARR
[TINIT, QINIT] as 'FILLED'
end-initializations
finalize(LIQ)
forall(t in TANKS | QINIT(t)=0, l in LIQ) do
create(ifload(l,t))
ifload(l,t) is_binary
end-do
! Complete the initially partially filled tanks and calculate the remaining
! quantities of liquids
forall(l in LIQ)
REST(l):= ARR(l) - sum(t in TANKS | TINIT(t)=l) (CAP(t)-QINIT(t))
! Objective 1: total tank capacity used
TankUse:= sum(l in LIQ, t in TANKS) CAP(t)*ifload(l,t)
! Objective 2: number of tanks used
TankNum:= sum(l in LIQ, t in TANKS) ifload(l,t)
! Do not mix different liquids
forall(t in TANKS) sum(l in LIQ) ifload(l,t) <= 1
! Load the empty tanks within their capacity limits
forall(l in LIQ) sum(t in TANKS) CAP(t)*ifload(l,t) >= REST(l)
! Solve the problem with objective 1
minimize(TankUse)
! Solution printing
printsol
! Solve the problem with objective 2
minimize(TankNum)
! Solution printing
printsol
!-----------------------------------------------------------------
! Solution printing
procedure printsol
writeln("Used capacity: ", getsol(TankUse) +
sum(t in TANKS | QINIT(t)>0) CAP(t),
" Capacity of empty tanks: ", sum(t in TANKS) CAP(t) -
getsol(TankUse) -
sum(t in TANKS | QINIT(t)>0) CAP(t))
writeln("Number of tanks used: ", getsol(TankNum) +
sum(t in TANKS | QINIT(t)>0) 1)
forall(t in TANKS)
if(QINIT(t)=0) then
write(t, ": ")
forall(l in LIQ) write( if(getsol(ifload(l,t))>0 , l, ""))
writeln
else
writeln(t, ": ", TINIT(t))
end-if
end-procedure
end-model
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| © Copyright 2025 Fair Isaac Corporation. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||