Loading and cutting problems
Description
Problem name and type, features | Difficulty | Related examples |
D‑1 | Wagon load balancing: Nonpreemptive scheduling on parallel machines | **** | |
| heuristic solution requiring sorting algorithm, formulation of maximin objective; nested subroutines: function returning heuristic solution value and sorting procedure, ceil, getsize, if-then, break, exit, all loop types (forall-do, repeat-until, while-do), setparam, qsort, cutoff value, loading a MIP start solution |
D‑2 | Barge loading: Knapsack problem | ** | burglar1.mos, knapsack_graph.mos |
| incremental problem definition with 3 different objectives, procedure for solution printing |
D‑3 | Tank loading: Loading problem | *** | |
| 2 objectives; data preprocessing, as, dynamic creation of variables, procedure for solution printing, if-then-else |
D‑4 | Backing up files: Bin-packing problem | ** | binpacking_graph.mos |
| 2 versions of mathematical model, symmetry breaking; data preprocessing, ceil, range |
D‑5 | Cutting sheet metal: Covering problem | * | g6transmit.mos, j2bigbro.mos |
| |
D‑6 | Cutting steel bars for desk legs: Cutting-stock problem | ** | cutstock_graph.mos |
| set operation(s) on range sets, set of integer (data as set contents) |
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
|