(!********************************************************************* Mosel Example Problems ====================== file facilityloc.mos ```````````````````` TYPE: Facility location problem DIFFICULTY: 3 FEATURES: MIP problem, graphical solution representation, re-solving with modified bounds, data input from file, dynamic arrays for data and decision variables, use of 'exists', model cuts DESCRIPTION: There are a set of depot locations and a set of clients. The cost of opening each depot, the depot capacities, and the demand of each client is given. For all possible delivery routes the unit shipping cost is given. We wish to supply all the clients at the least cost. The model is re-solved several times to study the effects of forcing some depots open. FURTHER INFO: Similar problem: `Applications of optimization with Xpress-MP', Section 10.3 `Depot location' (c) 2004 Dash Associates author: S. Heipcke **********************************************************************!) model "Facility location" uses "mmxprs" uses "mmive" forward procedure print_sol declarations Depots: set of string ! Set of Depots Clients: set of string ! Set of Clients COPEN: array(Depots) of real ! Cost of opening depot CSHIP: array(Depots, Clients) of real ! Cost of shipping DEM: array(Clients) of real ! Demand of Clients CAP: array(Depots) of real ! Capacity of depots X,Y: array(set of string) of integer ! x-y-coordinates for graph drawing end-declarations initializations from 'facilityloc.dat' [X,Y] as 'POS' COPEN CAP CSHIP DEM end-initializations ! Finalize index sets (= their contents cannot be modified any more) finalize(Depots); finalize(Clients) declarations ship: dynamic array(Depots, Clients) of mpvar ! Amount to be shipped from ! depot d to client c open: array(Depots) of mpvar ! 1, if depot d is open, 0 otherwise end-declarations ! Create variables for possible routes forall(d in Depots, c in Clients | exists(CSHIP(d,c)) ) create(ship(d,c)) ! Objective: minimize total cost MinCost:= sum(d in Depots, c in Clients | exists(CSHIP(d,c))) CSHIP(d,c) * ship(d,c) + ! Shipping cost sum(d in Depots) COPEN(d) * open(d) ! Depot open cost ! Capacity constraint at each depot forall(d in Depots) Capacity(d):= sum(c in Clients) ship(d,c) <= CAP(d) * open(d) ! Demand requirements at each client forall (c in Clients) Demand(c):= sum(d in Depots) ship(d,c) >= DEM(c) ! Additional constraints: ! Force 'open(d)' to 1 if there is any shipping from d ! (disaggregated form of 'Capacity' constraints) (! declarations Force: array(Depots, Clients) of linctr end-declarations forall (d in Depots, c in Clients | exists(CSHIP(d,c))) do Force(d,c):= CAP(d) * open(d) >= ship(d,c) setmodcut(Force(d,c)) end-do !) ! 'open' variables are binary forall(d in Depots) open(d) is_binary ! Setting parameters for Xpress-Optimizer setparam("xprs_verbose",true) ! Display Optimizer log setparam("xprs_presolve",0) ! Switch presolve off ! Solve the problem minimize(MinCost) writeln("CASE 1: Optimal Solution") print_sol ! What if Depot 1 has to be open? writeln("\nCASE 2: Depot 1 is forced open ") Open1:= open("DEP1")=1 minimize(MinCost) print_sol ! What if Depot 2 has to be open? writeln("\nCASE 3: Depot 2 is forced open ") Open1:= open("DEP2")=1 minimize(MinCost) print_sol ! What if both 1 & 2 have to be open? writeln("\nCASE 4: Depots 1 & 2 are forced open ") Open2:= open("DEP1")=1 minimize(MinCost) print_sol !----------------------------------------------------------------- ! Print the current solution procedure print_sol writeln("Total cost: $", getobjval) write("Open depots:") forall(d in Depots) write(if(getsol(open(d))=1, " "+d, "") ) writeln writeln("Shipping details: ") forall(d in Depots, c in Clients) do if (getsol(ship(d,c))<>0) then writeln(getsol(ship(d,c))," units shipped from depot ",d," to client ",c,".") end-if end-do end-procedure !----------------------------------------------------------------- end-model