(!******************************************************
Mosel Example Problems
======================
file covering.mos
`````````````````
TYPE: Covering problem
DIFFICULTY: 2
FEATURES: MIP problem, modeling an equivalence; sparse data format,
graphical output representation, 'if-then-else'
DESCRIPTION: A mobile phone operator decides to equip a currently
uncovered geographical zone. A budget is allocated to equip
this region. 7 locations are possible for the construction
of the transmitters. Every transmitter only covers a certain
number of communities. For every community the number of
inhabitants is known. Where should the transmitters be built
to cover the largest population with the given budget?
FURTHER INFO: `Applications of optimization with Xpress-MP',
Section 12.6 `Location of GSM transmitters'.
Similar problems: Section 9.5 `Cutting of sheet metal',
Section 15.2 `CCTV surveillance'
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, 2002, rev. Sep. 2017
*******************************************************!)
model "Transmitter placement"
uses "mmxprs", "mmsvg"
declarations
COMMS = 1..15 ! Set of communities
PLACES = 1..7 ! Set of possible transm. locations
COST: array(PLACES) of real ! Cost of constructing transmitters
COVER: array(PLACES,COMMS) of integer ! Coverage by transmitter locations
POP: array(COMMS) of integer ! Number of inhabitants (in 1000)
BUDGET: integer ! Budget limit
build: array(PLACES) of mpvar ! 1 if transmitter built, 0 otherwise
covered: array(COMMS) of mpvar ! 1 if community covered, 0 otherwise
end-declarations
initializations from 'covering.dat'
COST COVER POP BUDGET
end-initializations
! Objective: total population covered
Coverage:= sum(c in COMMS) POP(c)*covered(c)
! Towns covered
forall(c in COMMS)
CoverTown(c):= sum(p in PLACES) COVER(p,c)*build(p) >= covered(c)
! Budget limit
BudgetLim:= sum(p in PLACES) COST(p)*build(p) <= BUDGET
forall(p in PLACES) build(p) is_binary
forall(c in COMMS) covered(c) is_binary
! Solve the problem
maximize(Coverage)
! Solution printing
writeln("Total coverage: ", getobjval, " total cost: ",
getsol(sum(p in PLACES) COST(p)*build(p)))
write("Build transmitters:")
forall(p in PLACES) write(if(getsol(build(p))>0, " "+p, ""))
write("\nCommunities covered:")
forall(c in COMMS) write(if(getsol(covered(c))>0, " "+c, ""))
writeln
! Solution drawing
declarations
XT,YT: array(PLACES) of integer ! x-y-coordinates for transmitters
XC,YC: array(COMMS) of integer ! x-y-coordinates of communities
end-declarations
initializations from 'covering.dat'
[XT,YT] as 'POST'
[XC,YC] as 'POSC'
end-initializations
svgsetgraphviewbox(10,10,110,75)
svgsetgraphscale(2)
svgaddgroup("CovGraph", "Communities covered", SVG_BLACK)
svgaddgroup("UncGraph", "Communities not covered", svgcolor(150,150,150))
forall(c in COMMS) do
if(getsol(covered(c))>0) then
svgaddpoint("CovGraph", XC(c), YC(c))
svgaddtext("CovGraph", XC(c)+1, YC(c)+1, text(c))
else
svgaddpoint("UncGraph", XC(c), YC(c))
svgaddtext("UncGraph", XC(c)+1, YC(c)+1, text(c))
end-if
end-do
svgaddgroup("LocGraph", "Possible locations", svgcolor(120,0,0))
svgsetstyle(SVG_FILL,SVG_CURRENT)
svgaddgroup("BuildGraph", "Chosen locations", SVG_RED)
svgsetstyle(SVG_FILL,SVG_CURRENT)
forall(p in PLACES)
if(getsol(build(p))>0) then
svgaddcircle("BuildGraph", XT(p), YT(p), 1)
svgaddtext("BuildGraph", XT(p)+1, YT(p)+1, text(p))
forall(c in COMMS)
if(COVER(p,c)>0) then
svgaddline("BuildGraph", XT(p), YT(p), XC(c), YC(c))
end-if
else
svgaddcircle("LocGraph", XT(p), YT(p), 1)
svgaddtext("LocGraph", XT(p)+1, YT(p)+1, text(p))
end-if
svgsave("covering.svg")
svgrefresh
svgwaitclose("Close browser window to terminate model execution.", 1)
end-model
|