(!******************************************************
Mosel User Guide Example Problems
=================================
file euler.mos
``````````````
Constructing a Eulerian circuit (a closed circuit
that uses every given arc exactly once).
- Working with lists -
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Oct. 2006
*******************************************************!)
model "Eulerian circuit"
declarations
NODES = 1..12 ! Set of nodes
UNUSED: array(NODES) of list of integer
TOUR: list of integer
NEWT, TAIL: list of integer
end-declarations
initializations from 'euler.dat'
UNUSED
end-initializations
ct:=sum(i in NODES) getsize(UNUSED(i))
TOUR:=[1] ! Choose node 1 as start point
while(ct>0) do ! While there are unused arcs:
! Find first node in TOUR with unused outgoing arc(s)
node:=0
forall(i in TOUR)
if UNUSED(i) <> [] then
node:=i
break
end-if
! Insertion position (first occurrence of 'node' in TOUR)
pos:= findfirst(TOUR, node)
! Construct a new subtour starting from 'node'
cur:=node ! Start with current node
NEWT:=[]
while(UNUSED(cur) <> []) do
NEWT+=splithead(UNUSED(cur),1) ! Take first unused arc
cur:=getlast(NEWT) ! End point of arc is new current node
end-do
! Stop if the subtour is not a closed loop (=> no Eulerian circuit)
if cur<>node then ! Compare start and end of subtour
writeln("Tour cannot be closed")
exit(1)
end-if
! Add the new subtour to the main journey
TAIL:=splittail(TOUR, -pos) ! Split off the tail from main tour
TOUR += NEWT + TAIL ! Attach subtour and tail to main tour
ct -= getsize(NEWT)
end-do
writeln("Tour: ", TOUR) ! Print the result
end-model
|
(!******************************************************
Mosel User Guide Example Problems
=================================
file eulerfct.mos
`````````````````
Constructing a Eulerian circuit (a closed circuit
that uses every given arc exactly once).
- Working with lists -
- Model version using subroutines -
(c) 2008 Fair Isaac Corporation
author: S. Heipcke, Oct. 2006
*******************************************************!)
model "Eulerian circuit"
forward function find_unused(J: list of integer):integer
forward function add_loop(node:integer, J: list of integer):integer
declarations
NODES = 1..12 ! Set of nodes
UNUSED: array(NODES) of list of integer
TOUR: list of integer
end-declarations
initializations from 'euler.dat'
UNUSED
end-initializations
ct:=sum(i in NODES) getsize(UNUSED(i))
! Main loop of the Eulerian circuit algorithm
TOUR:=[1] ! Choose node 1 as start point
ct-=add_loop(1,TOUR) ! Construct a closed tour from node 1
while(ct>0) ! While there are unused arcs:
ct-=add_loop(find_unused(TOUR),TOUR) ! Add new closed subtours to main tour
writeln("Tour: ", TOUR) ! Print the result
!-----------------------------------------------------------------
! Find first node in list (tour) with unused outgoing arc(s)
function find_unused(J: list of integer):integer
returned:=0
forall(i in J)
if UNUSED(i) <> [] then
returned:=i
break
end-if
end-function
!-----------------------------------------------------------------
! Add a subtour to the main tour
function add_loop(node:integer, J: list of integer):integer
declarations
NEWJ, TAIL: list of integer
end-declarations
! Insertion position (first occurrence of 'node' in list J)
pos:= findfirst(J,node)
! Construct a new subtour
cur:=node ! Start with current node
while(UNUSED(cur) <> []) do
NEWJ+=splithead(UNUSED(cur),1) ! Take first unused arc
cur:=getlast(NEWJ) ! End point of arc is new current node
end-do
! Stop if the subtour is not a closed loop (=> no Eulerian circuit)
if cur<>node then ! Compare start and end of subtour
writeln("Tour cannot be closed")
exit(1)
end-if
! Add the new subtour to the main journey
TAIL:=splittail(J, -pos) ! Split off the tail from main tour
J += NEWJ + TAIL ! Attach subtour and tail to main tour
returned:=getsize(NEWJ)
end-function
end-model
|