pyclustering  0.10.1
pyclustring is a Python, C++ data mining library.
dsatur.py
1 """!
2 
3 @brief Graph coloring algorithm: DSATUR
4 @details Implementation based on paper @cite article::gcolor::dsatur::1.
5 
6 @authors Andrei Novikov (pyclustering@yandex.ru)
7 @date 2014-2020
8 @copyright BSD-3-Clause
9 
10 """
11 
12 class dsatur:
13  """!
14  @brief Represents DSATUR algorithm for graph coloring problem that uses greedy strategy.
15 
16  """
17 
18  def __init__(self, data):
19  """!
20  @brief Constructor of DSATUR algorithm.
21 
22  @param[in] data (list): Matrix graph representation.
23 
24  """
25  if (len(data[0]) != len(data)):
26  raise NameError('Only matrix graph representation is available.');
27 
28  self.__data_pointer = data;
29  self.__colors = [];
30  self.__coloring = None;
31 
32  def process(self):
33  """!
34  @brief Perform graph coloring using DSATUR algorithm.
35 
36  @see get_colors()
37 
38  """
39  color_counter = 1;
40 
41  degrees = list();
42  saturation_degrees = [0] * len(self.__data_pointer);
43 
44  self.__coloring = [0] * len(self.__data_pointer);
45  uncolored_vertices = set(range(len(self.__data_pointer)));
46 
47  index_maximum_degree = 0;
48  maximum_degree = 0;
49  for index_node in range(len(self.__data_pointer)):
50  # Fill degree of nodes in the input graph
51  degrees.append( ( sum(self.__data_pointer[index_node]), index_node ) );
52 
53  # And find node with maximal degree at the same time.
54  if (degrees[index_node][0] > maximum_degree):
55  (maximum_degree, node_index) = degrees[index_node];
56  index_maximum_degree = index_node;
57 
58  # Update saturation
59  neighbors = self.__get_neighbors(index_maximum_degree);
60  for index_neighbor in neighbors:
61  saturation_degrees[index_neighbor] += 1;
62 
63  # Coloring the first node
64  self.__coloring[index_maximum_degree] = color_counter;
65  uncolored_vertices.remove(index_maximum_degree);
66 
67  while(len(uncolored_vertices) > 0):
68  # Get maximum saturation degree
69  maximum_satur_degree = -1;
70  for index in uncolored_vertices:
71  if (saturation_degrees[index] > maximum_satur_degree):
72  maximum_satur_degree = saturation_degrees[index];
73 
74  # Get list of indexes with maximum saturation degree
75  indexes_maximum_satur_degree = [index for index in uncolored_vertices if saturation_degrees[index] == maximum_satur_degree];
76 
77  coloring_index = indexes_maximum_satur_degree[0];
78  if (len(indexes_maximum_satur_degree) > 1): # There are more then one node with maximum saturation
79  # Find node with maximum degree
80  maximum_degree = -1;
81  for index in indexes_maximum_satur_degree:
82  (degree, node_index) = degrees[index];
83  if (degree > maximum_degree):
84  coloring_index = node_index;
85  maximum_degree = degree;
86 
87  # Coloring
88  node_index_neighbors = self.__get_neighbors(coloring_index);
89  for number_color in range(1, color_counter + 1, 1):
90  if (self.__get_amount_color(node_index_neighbors, number_color) == 0):
91  self.__coloring[coloring_index] = number_color;
92  break;
93 
94  # If it has not been colored then
95  if (self.__coloring[coloring_index] == 0):
96  color_counter += 1; # Add new color
97  self.__coloring[coloring_index] = color_counter;
98 
99  # Remove node from uncolored set
100  uncolored_vertices.remove(coloring_index);
101 
102 
103  # Update degree of saturation
104  for index_neighbor in node_index_neighbors:
105  subneighbors = self.__get_neighbors(index_neighbor);
106 
107  if (self.__get_amount_color(subneighbors, self.__coloring[coloring_index]) == 1):
108  saturation_degrees[index_neighbor] += 1;
109 
110  def get_colors(self):
111  """!
112  @brief Returns results of graph coloring.
113 
114  @return (list) list with assigned colors where each element corresponds
115  to node in the graph, for example [1, 2, 2, 1, 3, 4, 1].
116 
117  @see process()
118 
119  """
120 
121  return self.__coloring;
122 
123  def __get_amount_color(self, node_indexes, color_number):
124  """!
125  @brief Countes how many nodes has color 'color_number'.
126 
127  @param[in] node_indexes (list): Indexes of graph nodes for checking.
128  @param[in] color_number (uint): Number of color that is searched in nodes.
129 
130  @return (uint) Number found nodes with the specified color 'color_number'.
131 
132  """
133 
134  color_counter = 0;
135  for index in node_indexes:
136  if (self.__coloring[index] == color_number):
137  color_counter += 1;
138 
139  return color_counter;
140 
141 
142  def __get_neighbors(self, node_index):
143  """!
144  @brief Returns indexes of neighbors of the specified node.
145 
146  @param[in] node_index (uint):
147 
148  @return (list) Neighbors of the specified node.
149 
150  """
151 
152  return [ index for index in range(len(self.__data_pointer[node_index])) if self.__data_pointer[node_index][index] != 0 ];
153 
pyclustering.gcolor.dsatur.dsatur.process
def process(self)
Perform graph coloring using DSATUR algorithm.
Definition: dsatur.py:32
pyclustering.gcolor.dsatur.dsatur.get_colors
def get_colors(self)
Returns results of graph coloring.
Definition: dsatur.py:110
pyclustering.gcolor.dsatur.dsatur.__coloring
__coloring
Definition: dsatur.py:30
pyclustering.gcolor.dsatur.dsatur
Represents DSATUR algorithm for graph coloring problem that uses greedy strategy.
Definition: dsatur.py:12
pyclustering.gcolor.dsatur.dsatur.__get_neighbors
def __get_neighbors(self, node_index)
Returns indexes of neighbors of the specified node.
Definition: dsatur.py:142
pyclustering.gcolor.dsatur.dsatur.__init__
def __init__(self, data)
Constructor of DSATUR algorithm.
Definition: dsatur.py:18
pyclustering.gcolor.dsatur.dsatur.__get_amount_color
def __get_amount_color(self, node_indexes, color_number)
Countes how many nodes has color 'color_number'.
Definition: dsatur.py:123
pyclustering.gcolor.dsatur.dsatur.__colors
__colors
Definition: dsatur.py:29
pyclustering.gcolor.dsatur.dsatur.__data_pointer
__data_pointer
Definition: dsatur.py:28