FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious example

Local authorities and public services

Description
Problem name and type, featuresDifficultyRelated examples
J‑1 Water conveyance / water supply management: Maximum flow problem ** j1water_graph.mos, g1rely.mos
encoding of arcs, selection with `|', record data structure
J‑2 CCTV surveillance: Maximum vertex cover problem ** j2bigbro_graph.mos, g6transmit.mos, d5cutsh.mos
encoding of network, exists
J‑3 Rigging elections: Partitioning problem **** j3elect_graph.mos, partitioning_graph.mos
algorithm for data preprocessing; file inclusion, 3 nested/recursive procedures, working with sets, if-then, forall-do, exists, finalize
J‑4 Gritting roads: Directed Chinese postman problem **** j4grit_graph.mos
algorithm for finding Eulerian path/graph for printing; encoding of arcs, dynamic array, exists, 2 functions implementing Eulerian circuit algorithm, round, getsize, break, while-do, if-then-else, list handling
J‑5 Location of income tax offices: p-median problem ****
modeling an implication, all-pairs shortest path algorithm (Floyd-Warshall); dynamic array, exists, procedure for shortest path algorithm, forall-do, if-then, selection with `|'
J‑6 Efficiency of hospitals: Data Envelopment Analysis (DEA) ***
description of DEA method; loop over problem solving with complete re-definition of problem every time, naming and declaring constraints


Further explanation of this example: 'Applications of optimization with Xpress-MP', Chapter 15: Local authorities and public services

mosel_app_10.zip[download all files]

Source Files

Data Files





j5tax.mos

(!******************************************************
   Mosel Example Problems
   ======================

   file j5tax.mos
   ``````````````
   Choice of locations for income tax offices
 
   A graph representing the cities and major roads connecting
   them is provided. The population of each city and the 
   distance between two cities directly connected are also 
   known from the graph. Where should tax offices be located 
   to minimize the average distance per inhabitant to the 
   closest tax office?

   Given the graph, the distance matrix is calculated using a
   specialized algorithm (Floyd-Warshall), implemented by the
   procedure 'calculatedist'. These distances are used 
   in the MIP model where two families of decision variables 
   are defined.

   (c) 2008-2022 Fair Isaac Corporation
       author: S. Heipcke, Mar. 2002, rev. Mar. 2022
*******************************************************!)

model "J-5 Tax office location"
 uses "mmxprs"

 forward procedure calculatedist

 declarations
  CITIES = 1..12                        ! Set of cities

  DIST: array(CITIES,CITIES) of integer ! Distance matrix
  POP: array(CITIES) of integer         ! Population of cities
  LEN: dynamic array(CITIES,CITIES) of integer ! Road lengths
  NUMLOC: integer                       ! Desired number of tax offices
  
  build: array(CITIES) of mpvar         ! 1 if office in city, 0 otherwise
  depend: array(CITIES,CITIES) of mpvar ! (c,d) 1 if city c depends on office
                                        ! in city d, 0 otherwise
 end-declarations

 initializations from 'j5tax.dat'
  LEN POP NUMLOC
 end-initializations

! Calculate the distance matrix
 calculatedist    

! Objective: weighted total distance
 TotDist:= sum(c,d in CITIES) POP(c)*DIST(c,d)*depend(c,d)

! Assign cities to offices
 forall(c in CITIES) sum(d in CITIES) depend(c,d) = 1
 
! Limit total number of offices
 sum(c in CITIES) build(c) <= NUMLOC
 
! Relations between dependencies and offices built
 forall(c,d in CITIES) depend(c,d) <= build(d)  
 
 forall(c in CITIES) build(c) is_binary

! Solve the problem
 minimize(TotDist)
 
! Solution printing
 writeln("Total weighted distance: ", getobjval, 
        " (average per inhabitant: ", getobjval/sum(c in CITIES) POP(c), ")")
 forall(c in CITIES | getsol(build(c))>0) do
  write("Office in ", c, ": ")
  forall(d in CITIES | getsol(depend(d,c))>0) write(" ", d)
  writeln
 end-do

!-----------------------------------------------------------------

! Calculate the distance matrix using Floyd-Warshall algorithm
 procedure calculatedist
 ! Initialize all distance labels with a sufficiently large value
  BIGM:=sum(c,d in CITIES | exists(LEN(c,d))) LEN(c,d)
  forall(c,d in CITIES) DIST(c,d):=BIGM

  forall(c in CITIES) DIST(c,c):=0    ! Set values on the diagonal to 0
 
! Length of existing road connections
  forall(c,d in CITIES | exists(LEN(c,d))) do
   DIST(c,d):=LEN(c,d)
   DIST(d,c):=LEN(c,d)
  end-do
 
! Update shortest distance for every node triple
  forall(b,c,d in CITIES | c<d )
   if DIST(c,d) > DIST(c,b)+DIST(b,d) then
    DIST(c,d):= DIST(c,b)+DIST(b,d)
    DIST(d,c):= DIST(c,b)+DIST(b,d)
   end-if 
 end-procedure 
 
end-model

Back to examples browserPrevious example