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





j3elect_calc.mos

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

   file j3elect_calc.mos
   ````````````````''''`
   Include file for data pre-processing

   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, Apr. 2002
*******************************************************!)

 declarations
  NUMD: integer                         ! Number of possible districts
  RN: range                             ! Neighboring quarters
  
  NEIGHB: dynamic array(QUARTERS,RN) of integer ! Set of neighboring quarters
  POP: array(QUARTERS) of integer       ! Number of electors (in 1000)
  VOTES: array(QUARTERS) of real        ! Number of favorable votes (in 1000)
  MINPOP,MAXPOP,MINSINGLE: integer      ! Limits on electors per district
 end-declarations

 initializations from 'j3elect.dat'
  NEIGHB POP VOTES MINPOP MAXPOP MINSINGLE
 end-initializations

!**** Save a new entry in the list of districts ****
 procedure savedistr(sQ: set of integer)
  NUMD+=1
  forall(q in sQ) DISTR(NUMD,q):=1 
 end-procedure  

!**** Add a neighboring quarter to the current set of quarters ****
 procedure addneighb(toadd:integer, sQ:set of integer)
  declarations
   nQ: set of integer
  end-declarations
   
  nQ:=sQ+{toadd}
  if(sum(q in nQ) POP(q) >= MINPOP) then      ! Large enough to form distr.
   savedistr(nQ) 
  end-if 
  forall(p in RN | exists(NEIGHB(toadd,p)))   ! Try adding every neighbor
   if(sum(q in nQ) POP(q)+POP(NEIGHB(toadd,p))<=MAXPOP) then
    addneighb(NEIGHB(toadd,p), nQ)
   end-if   
 end-procedure

!**** Calculate the list of possible districts ****
 procedure calculatedistr
  NUMD:=0
  forall(q in QUARTERS) do
   if (POP(q) >= MINSINGLE and q<>10) then    ! Single quarter districts
    savedistr({q})
   end-if
   forall(p in RN | exists(NEIGHB(q,p)))      ! Try adding every neighbor
    if(POP(q)+POP(NEIGHB(q,p))<=MAXPOP) then
     addneighb(NEIGHB(q,p),{q})
    end-if 
  end-do
  
  forall(d in 1..NUMD) do                     ! Print the resulting list
   write(d,":")
   forall(q in QUARTERS| DISTR(d,q)>0) write(" ", q)
   writeln(" ", (sum(q in QUARTERS | DISTR(d,q)>0) VOTES(q)) *100 / 
                (sum(q in QUARTERS | DISTR(d,q)>0) POP(q)), "%")
  end-do 
  writeln("Number of possible districts: ",NUMD)

  forall(d in 1..NUMD)                        ! Calculate majorities
   MAJ(d):= if(((sum(q in QUARTERS | DISTR(d,q)>0) VOTES(q)) / 
                (sum(q in QUARTERS | DISTR(d,q)>0) POP(q))    >= 0.5), 1, 0)
  finalize(RDIST)
 end-procedure


!**** Start the calculation of the list of possible districts ****
 calculatedistr


Back to examples browserPrevious example