Initializing help system before first use

Minimum weight spanning tree


Type: Minimum weight spanning tree
Rating: 3 (intermediate)
Description: Six terminals located in different buildings need to be connected. The cost of connecting two terminals is proportional to the distance between them. Determine the connections to install to minimize the total cost.
File(s): spanningtree_graph.mos
Data file(s): spanningtree.dat


spanningtree_graph.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file spanningtree.mos
   `````````````````````
   TYPE:         Minimum weight spanning tree problem
   DIFFICULTY:   3
   FEATURES:     MIP problem, formulation of constraints to exclude subcycles,
                 graphical representation of results
   DESCRIPTION:  Six terminals located in different buildings need to be 
                 connected. The cost of connecting two terminals is 
                 proportional to the distance between them. Determine the 
                 connections to install to minimize the total cost.     
   FURTHER INFO: `Applications of optimization with Xpress-MP', 
                 Section 12.4 `Construction of a cabled network'
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, 2002, rev. Sep. 2017
*******************************************************!)

model "Cabled network"
 uses "mmxprs", "mmsvg","mmsystem"

 declarations
  NTERM = 6
  TERMINALS = 1..NTERM                  ! Set of terminals to cnct

  DIST: array(TERMINALS,TERMINALS) of integer  ! Distance between terminals

  cnct: array(TERMINALS,TERMINALS) of mpvar ! 1 if direct connection
                                        ! between terminals, 0 otherwise
  level: array(TERMINALS) of mpvar      ! level value of nodes
 end-declarations

 initializations from 'spanningtree.dat'
  DIST
 end-initializations

! Objective: length of cable used
 Length:= sum(s,t in TERMINALS | s<>t) DIST(s,t)*cnct(s,t)

! Number of cnctions
 NumConnect:= sum(s,t in TERMINALS | s<>t) cnct(s,t) = NTERM - 1 

! Avoid subcycle
 forall(s,t in TERMINALS | s<>t) 
  Cycle(s,t):= level(t) >= level(s) + 1 - NTERM + NTERM*cnct(s,t)

! Direct all cnctions towards the root (node 1)
 forall(s in 2..NTERM) Direct(s):= sum(t in TERMINALS | s<>t) cnct(s,t) = 1

 forall(s,t in TERMINALS | s<>t) cnct(s,t) is_binary

! Solve the problem
 minimize(Length)
 
! Solution printing
 writeln("Cable length: ", getobjval)

 write("Connections:")
 forall(s,t in TERMINALS | s<>t)
  write(if(getsol(cnct(s,t))>0, " " + s + "-" + t, "")) 
 writeln

! Solution drawing
 declarations
  X,Y: array(TERMINALS) of integer       ! x-y-coordinates of terminals
 end-declarations
 
 initializations from 'spanningtree.dat'
  [X,Y] as 'POS'
 end-initializations

 minx:=min(t in TERMINALS)X(t)-5; miny:=min(t in TERMINALS)Y(t)-5
 svgsetgraphviewbox(minx, miny,
         max(t in TERMINALS)X(t)+5-minx,max(t in TERMINALS)Y(t)+5-miny)
 
 svgaddgroup("T", "Terminals", SVG_BLACK)
 forall(t in TERMINALS) do
  svgaddpoint(X(t), Y(t))
  svgaddtext(X(t), Y(t)+1, "T"+t)
 end-do
 
 svgaddgroup("C", "Connections", SVG_GREEN)
 forall(s,t in TERMINALS | s<>t)
  if(getsol(cnct(s,t))>0) then
   svgaddtext(round((X(s)+X(t))/2), round((Y(s)+Y(t))/2), 
                string(DIST(s,t)))
   svgaddline(X(t), Y(t), X(s), Y(s))
  end-if

 svgsetgraphscale(5)
 svgsetgraphpointsize(3)

 svgsave("spantree.svg")
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)
end-model

© 2001-2026 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.