(!*********************************************************************
Mosel NL examples
=================
file quadfacloc.mos
```````````````````
Quadratic Facility Location model
Model of quadratic facility location problem.
The goal is to assign facilities to customers to minimize cost.
Basic version (formulation as MIQP)
(c) 2018 Fair Isaac Corporation
author: Z.Csizmadia, Sven Leyffer, Aug. 2018
*********************************************************************!)
model QuadFacLoc
uses "mmxprs", "mmnl", "mmsystem"
declarations
Iter: integer
end-declarations
declarations
I = 1..5 ! Set of facilities
J = 1..10 ! Set of customers
FacX,FacY: array(I) of real ! X/Y coordinates of facility location
CustX,CustY: array(J) of real ! X/Y coordinates of customer location
C: array(I) of real ! Fixed cost of opening facility at location
Q: array(I,J) of real ! Quadr. cost of meeting demand j from facility i
end-declarations
! **** Generate random data:
! **** Cost coefficients and coordinates of all facility + customer locations
setrandseed(42)
SCALE:=100
forall(i in I) do
C(i) := SCALE*100*random
FacX(i) := SCALE*random
FacY(i) := SCALE*random
end-do
forall(j in J) do
CustX(j) := SCALE*random
CustY(j) := SCALE*random
end-do
forall(i in I, j in J) ! Formula used by Lee to create instances
Q(i,j) := 50 * sqrt( (FacX(i) - CustX(j))*(FacX(i) - CustX(j)) +
(FacY(i) - CustY(j))*(FacY(i) - CustY(j)))
! **** Optimization model formulation (MIQP) ****
declarations
x: array(I,J) of mpvar ! Percentage of customer j served by facility i
z: array(I) of mpvar ! =1, iff facility i built
QuadCost: nlctr
BasicNodes: integer
end-declarations
! Quadratic objective function
QuadCost:= sum(i in I) C(i)*z(i) + sum(i in I, j in J) Q(i,j)*x(i,j)^2;
! Variable upper bound (only serve customers from open facilities)
forall(i in I, j in J) x(i,j) <= z(i)
! Meet all customers' demands
forall(j in J) sum(i in I) x(i,j) = 1
forall(i in I) z(i) is_binary
setparam("xprs_verbose",true)
starttime:=gettime
minimize(QuadCost)
BasicNodes:= getparam("XPRS_NODES")
writeln(gettime-starttime, "sec Solution: ", getobjval, ". Basic formulation - nodes: ", BasicNodes)
! Display the solution
write("Open Customer locations\nfacility")
forall(j in J) write(formattext("%6d",j))
forall(i in I | z(i).sol>0) do
write("\n ", textfmt(i,-8))
forall(j in J) write(formattext("%5.1f%%",x(i,j).sol*100))
end-do
writeln
end-model
|
(!*********************************************************************
Mosel NL examples
=================
file quadfaclocoa.mos
`````````````````````
Quadratic Facility Location model
Model of a quadratic facility location problem solved
by outer approximation (master modeL: MIP, submodel: QP).
The goal is to assign facilities to customers to minimize cost.
Original AMPL model by Sven Leyffer, see
https://www.researchgate.net/publication/2827082_Solving_Mixed_Integer_Nonlinear_Programs_by_Outer_Approximation
(c) 2018 Fair Isaac Corporation
author: Z.Csizmadia, Sven Leyffer, Aug. 2018
*********************************************************************!)
model QuadFacLocOA
uses "mmxprs", "mmnl", "mmsystem"
parameters
ILIM = 100
end-parameters
forward procedure printsol
declarations
Iter: integer
end-declarations
declarations
I = 1..5 ! Set of facilities
J = 1..10 ! Set of customers
FacX,FacY: array(I) of real ! X/Y coordinates of facility location
CustX,CustY: array(J) of real ! X/Y coordinates of customer location
C: array(I) of real ! Fixed cost of opening facility at location
Q: array(I,J) of real ! Quadr. cost of meeting demand j from facility i
UBD,LBD: real ! Upper/lower bound on solution
end-declarations
! **** Generate random data:
! **** Cost coefficients and coordinates of all facility + customer locations
setrandseed(42)
SCALE:=100
forall(i in I) do
C(i) := SCALE*100*random
FacX(i) := SCALE*random
FacY(i) := SCALE*random
end-do
forall(j in J) do
CustX(j) := SCALE*random
CustY(j) := SCALE*random
end-do
forall(i in I, j in J) ! Formula used by Lee to create instances
Q(i,j) := 50 * sqrt( (FacX(i) - CustX(j))*(FacX(i) - CustX(j)) +
(FacY(i) - CustY(j))*(FacY(i) - CustY(j)))
! **** Optimization model formulation ****
declarations
eta: mpvar ! Linearization of quad. objective terms
x: array(I,J) of mpvar ! Percentage of customer j served by facility j
z: array(I) of mpvar ! =1, iff facility i built
LastPoint: array(I) of real ! Latest discrete solution values from master
LastMast: real ! Latest obj solution value for master problem
LastX: array(I,J) of real ! Latest 'x' solution values from subproblem
LastSub: real ! Latest obj solution value for subproblem
end-declarations
! **** Master model (MIP)
declarations
Master: mpproblem
end-declarations
with Master do
declarations
LinCost: linctr
end-declarations
eta is_free
! Linearized objective function
LinCost:= sum(i in I) C(i)*z(i)
! After the initial iteration, the objective is changed to this form:
! LinCost:= sum(i in I) C(i)*z(i) + eta
! Variable upper bound (only serve customers from open facilities)
forall(i in I, j in J) x(i,j) <= z(i)
! Meet all customers' demands
forall(j in J) sum(i in I) x(i,j) = 1
forall(i in I) z(i) is_binary
! setparam("xprs_verbose",true)
end-do
! **** Submodel (continuous QP)
declarations
SubNLP: mpproblem
end-declarations
with SubNLP do
declarations
QuadCost: nlctr
Fixings: array(I) of linctr
end-declarations
! Quadratic objective function
QuadCost:= sum(i in I) C(i)*z(i) + sum(i in I, j in J) Q(i,j)*x(i,j)^2;
! Variable upper bound (only serve customers from open facilities)
forall(i in I, j in J) x(i,j) <= z(i)
! Meet all customers' demands
forall(j in J) sum(i in I) x(i,j) = 1
! setparam("xprs_verbose",true)
end-do
! **** Outer approximation algorithm
UBD := 1E20; LBD := -1E20
Iter:= 0; starttime:=gettime
while (LBD < UBD-(SCALE*1E-2) and Iter <= ILIM) do
Iter += 1
with Master do
minimize(LinCost)
! writeprob('Master_'+Iter,'l')
if getprobstat<>XPRS_OPT then break; end-if
forall(i in I) LastPoint(i) := getsol(z(i))
LastMast := getobjval
end-do
with SubNLP do
forall(i in I) Fixings(i):= z(i) = LastPoint(i) ! Fix discrete variables
minimize(QuadCost)
! writeprob('SubNLP_'+Iter,'l')
forall(i in I, j in J) LastX(i,j) := getsol(x(i,j))
LastSub := getobjval
end-do
with Master do
! After the first iteration add the linearization term to the objective
if Iter=1 then LinCost+= eta; end-if
! Linearization of quadratic part
eta >=
sum(i in I, j in J) Q(i,j)*LastX(i,j)^2 + ! Objective value
sum(i in I, j in J) 2*Q(i,j)*LastX(i,j)*(x(i,j) - LastX(i,j)) ! Gradient
end-do
UBD := minlist( UBD, LastSub )
LBD := LastMast
writeln(gettime-starttime, "sec Iter = ", Iter, ": LBD = ", LBD, " UBD = ", UBD)
! Uncomment this line to display intermediate solutions in detail:
! printsol
end-do
if Iter > ILIM then writeln("Iteration limit reached"); end-if
printsol
! **** Display the solution ****
procedure printsol
write("Open Customer locations\nfacility")
forall(j in J) write(formattext("%6d",j))
forall(i in I | LastPoint(i)>0) do
write("\n ", textfmt(i,-8))
forall(j in J) write(formattext("%5.1f%%",LastX(i,j).sol*100))
end-do
writeln
end-procedure
end-model
|