Statistics
| Branch: | Tag: | Revision:

root / htools / Ganeti / HTools / Graph.hs @ 8e6623c8

History | View | Annotate | Download (3.8 kB)

1
{-| Algorithms on Graphs.
2

    
3
This module contains a few graph algorithms and the transoformations
4
needed for them to be used on nodes.
5

    
6
For more information about Graph Coloring see:
7
<http://en.wikipedia.org/wiki/Graph_coloring>
8
<http://en.wikipedia.org/wiki/Greedy_coloring>
9

    
10
LF-coloring is described in:
11
Welsh, D. J. A.; Powell, M. B. (1967), "An upper bound for the chromatic number
12
of a graph and its application to timetabling problems", The Computer Journal
13
10 (1): 85-86, doi:10.1093/comjnl/10.1.85
14
<http://comjnl.oxfordjournals.org/content/10/1/85>
15

    
16
-}
17

    
18
{-
19

    
20
Copyright (C) 2012, Google Inc.
21

    
22
This program is free software; you can redistribute it and/or modify
23
it under the terms of the GNU General Public License as published by
24
the Free Software Foundation; either version 2 of the License, or
25
(at your option) any later version.
26

    
27
This program is distributed in the hope that it will be useful, but
28
WITHOUT ANY WARRANTY; without even the implied warranty of
29
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30
General Public License for more details.
31

    
32
You should have received a copy of the GNU General Public License
33
along with this program; if not, write to the Free Software
34
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35
02110-1301, USA.
36

    
37
-}
38

    
39
module Ganeti.HTools.Graph
40
  ( -- * Types
41
    Color
42
  , VertColorMap
43
  , ColorVertMap
44
    -- * Creation
45
  , emptyVertColorMap
46
    -- * Coloring
47
  , colorInOrder
48
  , colorLF
49
    -- * Color map transformations
50
  , colorVertMap
51
    -- * Vertex sorting
52
  , verticesByDegreeDesc
53
  , verticesByDegreeAsc
54
  ) where
55

    
56
import Data.Maybe
57
import Data.Ord
58
import Data.List
59

    
60
import qualified Data.IntMap as IntMap
61
import qualified Data.Graph as Graph
62
import qualified Data.Array as Array
63

    
64
-- * Type declarations
65

    
66
-- | Node colors.
67
type Color = Int
68

    
69
-- | Vertex to Color association.
70
type VertColorMap = IntMap.IntMap Color
71

    
72
-- | Color to Vertex association.
73
type ColorVertMap = IntMap.IntMap [Int]
74

    
75
-- * Sorting of vertices
76

    
77
-- | (vertex, degree) tuples on a graph.
78
verticesDegree :: Graph.Graph -> [(Graph.Vertex, Int)]
79
verticesDegree g = Array.assocs $ Graph.outdegree g
80

    
81
-- | vertices of a graph, sorted by ascending degree.
82
verticesByDegreeDesc :: Graph.Graph -> [Graph.Vertex]
83
verticesByDegreeDesc g =
84
  map fst . sortBy (flip (comparing snd)) $ verticesDegree g
85

    
86
-- | vertices of a graph, sorted by descending degree.
87
verticesByDegreeAsc :: Graph.Graph -> [Graph.Vertex]
88
verticesByDegreeAsc g = map fst . sortBy (comparing snd) $ verticesDegree g
89

    
90
-- * Coloring
91

    
92
-- | Empty color map.
93
emptyVertColorMap :: VertColorMap
94
emptyVertColorMap = IntMap.empty
95

    
96
-- | Get the colors of the neighbors of a vertex.
97
neighColors :: Graph.Graph -> VertColorMap -> Graph.Vertex -> [Color]
98
neighColors g cMap v = mapMaybe (`IntMap.lookup` cMap) neighbors
99
    where neighbors = g Array.! v
100

    
101
-- | Color one node.
102
colorNode :: Graph.Graph -> VertColorMap -> Graph.Vertex -> Color
103
-- use of "head" is A-ok as the source is an infinite list
104
colorNode g cMap v = head $ filter notNeighColor [0..]
105
    where notNeighColor = (`notElem` neighColors g cMap v)
106

    
107
-- | Color a node returning the updated color map.
108
colorNodeInMap :: Graph.Graph -> Graph.Vertex -> VertColorMap -> VertColorMap
109
colorNodeInMap g v cMap = IntMap.insert v newcolor cMap
110
    where newcolor = colorNode g cMap v
111

    
112
-- | Color greedily all nodes in the given order.
113
colorInOrder :: Graph.Graph -> [Graph.Vertex] -> VertColorMap
114
colorInOrder g = foldr (colorNodeInMap g) emptyVertColorMap
115

    
116
-- | Color greedily all nodes, larger first.
117
colorLF :: Graph.Graph -> ColorVertMap
118
colorLF g = colorVertMap . colorInOrder g $ verticesByDegreeAsc g
119

    
120
-- | ColorVertMap from VertColorMap.
121
colorVertMap :: VertColorMap -> ColorVertMap
122
colorVertMap = IntMap.foldWithKey
123
                 (flip (IntMap.insertWith ((:) . head)) . replicate 1)
124
                 IntMap.empty