3 @brief Graph representation (uses format GRPR). 5 @authors Andrei Novikov (pyclustering@yandex.ru) 7 @copyright GNU Public License 9 @cond GNU_PUBLIC_LICENSE 10 PyClustering is free software: you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation, either version 3 of the License, or 13 (at your option) any later version. 15 PyClustering is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. 29 import matplotlib.pyplot
as plt
30 from matplotlib
import colors
31 except Exception
as error_instance:
32 warnings.warn(
"Impossible to import matplotlib (please, install 'matplotlib'), pyclustering's visualization " 33 "functionality is not available (details: '%s')." % str(error_instance))
35 from enum
import IntEnum
39 @brief Enumeration of graph description. 40 @details Matrix representation is list of lists where number of rows equals number of columns and each element 41 of square matrix determines whether there is connection between two vertices. For example: 42 [ [0, 1, 1], [1, 0, 1], [1, 1, 0] ]. 44 Vector representation is list of lists where index of row corresponds to index of vertex and elements 45 of row consists of indexes of connected vertices. For example: 46 [ [1, 2], [0, 2], [0, 1] ]. 54 GRAPH_MATRIX_DESCR = 1;
57 GRAPH_VECTOR_DESCR = 2;
62 @brief Graph representation. 66 def __init__(self, data, type_graph = None, space_descr = None, comments = None):
68 @brief Constructor of graph. 70 @param[in] data (list): Representation of graph. Considered as matrix if 'type_graph' is not specified. 71 @param[in] type_graph (type_graph_descr): Type of graph representation in 'data'. 72 @param[in] space_descr (list): Coordinates of each vertex that are used for graph drawing (can be omitted). 73 @param[in] comments (string): Comments related to graph. 80 if (type_graph
is not None):
85 if (len(row) != len(self.
__data)):
90 if ( (element != 0)
or (element != 1) ):
96 @return (uint) Size of graph defined by number of vertices. 105 @return (list) Graph representation. 113 @return (list) Space description. 124 @return (string) Comments. 132 @return (type_graph_descr) Type of graph representation. 140 @brief Read graph from file in GRPR format. 142 @param[in] filename (string): Path to file with graph in GRPR format. 144 @return (graph) Graph that is read from file. 148 file = open(filename,
'r'); 155 map_data_repr = dict();
158 if (line[0] ==
'c' or line[0] ==
'p'):
159 comments += line[1:];
161 elif (line[0] ==
'r'): 162 node_coordinates = [float(val) for val
in line[1:].split()];
163 if (len(node_coordinates) != 2):
164 raise NameError(
'Invalid format of space description for node (only 2-dimension space is supported)');
166 space_descr.append( [float(val)
for val
in line[1:].split()] );
168 elif (line[0] ==
'm'):
169 if ( (data_type
is not None)
and (data_type !=
'm') ):
170 raise NameError(
'Invalid format of graph representation (only one type should be used)');
173 data.append( [float(val)
for val
in line[1:].split()] );
175 elif (line[0] ==
'v'):
176 if ( (data_type
is not None)
and (data_type !=
'v') ):
177 raise NameError(
'Invalid format of graph representation (only one type should be used)');
180 data.append( [float(val)
for val
in line[1:].split()] );
182 elif (line[0] ==
'e'):
183 if ( (data_type
is not None)
and (data_type !=
'e') ):
184 raise NameError(
'Invalid format of graph representation (only one type should be used)');
187 vertices = [int(val)
for val
in line[1:].split()];
189 if (vertices[0]
not in map_data_repr):
190 map_data_repr[ vertices[0] ] = [ vertices[1] ];
192 map_data_repr[ vertices[0] ].append(vertices[1])
194 if (vertices[1]
not in map_data_repr):
195 map_data_repr[ vertices[1] ] = [ vertices[0] ];
197 map_data_repr[ vertices[1] ].append(vertices[0]);
200 elif (len(line.strip()) == 0):
continue;
204 raise NameError(
'Invalid format of file with graph description');
207 if (data_type ==
'e'):
208 for index
in range(len(map_data_repr)):
209 data.append([0] * len(map_data_repr));
211 for index_neighbour
in map_data_repr[index + 1]:
212 data[index][index_neighbour - 1] = 1;
218 if (data_type ==
'm'): graph_descr = type_graph_descr.GRAPH_MATRIX_DESCR;
219 elif (data_type ==
'v'): graph_descr = type_graph_descr.GRAPH_VECTOR_DESCR;
220 elif (data_type ==
'e'): graph_descr = type_graph_descr.GRAPH_MATRIX_DESCR;
222 raise NameError(
'Invalid format of file with graph description');
224 if (space_descr != []):
225 if (len(data) != len(space_descr)):
226 raise NameError(
"Invalid format of file with graph - number of nodes is different in space representation and graph description");
228 return graph(data, graph_descr, space_descr, comments);
236 @param[in] graph_instance (graph): Graph that should be drawn. 237 @param[in] map_coloring (list): List of color indexes for each vertex. Size of this list should be equal to size of graph (number of vertices). 238 If it's not specified (None) than graph without coloring will be dwarn. 240 @warning Graph can be represented if there is space representation for it. 244 if (graph_instance.space_description
is None):
245 raise NameError(
"The graph haven't got representation in space");
247 if (map_coloring
is not None):
248 if (len(graph_instance) != len(map_coloring)):
249 raise NameError(
"Size of graph should be equal to size coloring map");
253 axes = fig.add_subplot(111);
255 available_colors = [
'#00a2e8',
'#22b14c',
'#ed1c24',
256 '#fff200',
'#000000',
'#a349a4',
257 '#ffaec9',
'#7f7f7f',
'#b97a57',
258 '#c8bfe7',
'#880015',
'#ff7f27',
259 '#3f48cc',
'#c3c3c3',
'#ffc90e',
260 '#efe4b0',
'#b5e61d',
'#99d9ea',
261 '#7092b4',
'#ffffff'];
263 if (map_coloring
is not None):
264 if (len(map_coloring) > len(available_colors)):
265 raise NameError(
'Impossible to represent colored graph due to number of specified colors.');
267 x_maximum = -float(
'inf');
268 x_minimum = float(
'inf');
269 y_maximum = -float(
'inf');
270 y_minimum = float(
'inf');
272 for i
in range(0, len(graph_instance.space_description), 1):
273 if (graph_instance.type_graph_descr == type_graph_descr.GRAPH_MATRIX_DESCR):
274 for j
in range(i, len(graph_instance.space_description), 1):
275 if (graph_instance.data[i][j] == 1):
276 axes.plot([graph_instance.space_description[i][0], graph_instance.space_description[j][0]], [graph_instance.space_description[i][1], graph_instance.space_description[j][1]],
'k-', linewidth = 1.5);
278 elif (graph_instance.type_graph_descr == type_graph_descr.GRAPH_VECTOR_DESCR):
279 for j
in graph_instance.data[i]:
281 axes.plot([graph_instance.space_description[i][0], graph_instance.space_description[j][0]], [graph_instance.space_description[i][1], graph_instance.space_description[j][1]],
'k-', linewidth = 1.5);
284 if (map_coloring
is not None):
285 color_node = colors.hex2color(available_colors[map_coloring[i]]);
287 axes.plot(graph_instance.space_description[i][0], graph_instance.space_description[i][1], color = color_node, marker =
'o', markersize = 20);
289 if (x_maximum < graph_instance.space_description[i][0]): x_maximum = graph_instance.space_description[i][0];
290 if (x_minimum > graph_instance.space_description[i][0]): x_minimum = graph_instance.space_description[i][0];
291 if (y_maximum < graph_instance.space_description[i][1]): y_maximum = graph_instance.space_description[i][1];
292 if (y_minimum > graph_instance.space_description[i][1]): y_minimum = graph_instance.space_description[i][1];
294 plt.xlim(x_minimum - 0.5, x_maximum + 0.5);
295 plt.ylim(y_minimum - 0.5, y_maximum + 0.5);
def __init__(self, data, type_graph=None, space_descr=None, comments=None)
Constructor of graph.
def type_graph_descr(self)
def draw_graph(graph_instance, map_coloring=None)
Draw graph.
Enumeration of graph description.
def read_graph(filename)
Read graph from file in GRPR format.
def space_description(self)