File: graph_types

package info (click to toggle)
polymake 3.0r2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 19,752 kB
  • ctags: 30,928
  • sloc: cpp: 151,785; perl: 32,510; ansic: 3,597; java: 2,654; python: 278; makefile: 181; xml: 103; sh: 79
file content (406 lines) | stat: -rw-r--r-- 14,402 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
#  Copyright (c) 1997-2015
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.polymake.org
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#-------------------------------------------------------------------------------

# @topic category property_types/Graph Types
# This contains all property types that are related to graphs.

# @topic category functions/Graph Operations
# Operations on graphs.

# @category Artificial
# Type tag for an __undirected__ [[Graph]].
declare property_type Undirected : c++ (special => 'Undirected', include => "polymake/Graph.h");

# @category Artificial
# Type tag for a __directed__ [[Graph]].
declare property_type Directed : c++ (special => 'Directed', include => "polymake/Graph.h");

# @category Artificial
# Type tag for an __undirected multigraph__.
declare property_type UndirectedMulti : c++ (special => 'UndirectedMulti', include => "polymake/Graph.h");

# @category Artificial
# Type tag for a __directed multigraph__.
declare property_type DirectedMulti : c++ (special => 'DirectedMulti', include => "polymake/Graph.h");

# @category Artificial
declare property_type EdgeList<*> : c++;

# @category Artificial
declare property_type EdgeIterator<*> : Iterator : c++ {

   method from_node() : c++;

   method to_node() : c++;
}

function entire(EdgeList:anchor) : c++ : returns(EdgeIterator);

##################################################################################

# @category Graph Types
# @tparam Dir one of [[Undirected]], [[Directed]], [[UndirectedMulti]] or [[DirectedMulti]], default: [[Undirected]]
declare property_type Graph<Dir=Undirected> : c++ (include => "polymake/Graph.h", operators => '@sets:wary == !=') {

   # Returns the total number of nodes.
   # @return Int
   user_method nodes() : c++;

   # Returns the total number of edges.
   # @return Int
   user_method edges() : c++;

   # Adds a new node without incident edes, returns its index.
   # @return Int
   user_method add_node() : non_const : c++;

   # Checks whether the node with given index exists.
   # @param Int node
   # @return Bool
   user_method node_exists($) : wary : c++;

   # Returns true if the given node index is either out of valid range or points to a formerly deleted node.
   # @param Int node
   # @return Bool
   user_method invalid_node($) : c++;

   # Returns true if the given node index is out of valid range.
   # @param Int node
   # @return Bool
   user_method node_out_of_range($) : c++;

   # Deletes all edges incident to the given node and marks it as invalid.
   # The numeration of other nodes stays unchanged.
   # @param Int node
   user_method delete_node($) : non_const : wary : void : c++;

   # Returns the index of the edge connecting two given nodes.
   # The edge is created if was not there.
   # In a multigraph, an arbitrary edge from the parallel bundle will be picked.
   # @param Int tail_node
   # @param Int head_node
   # @return Int
   user_method edge($$) : non_const : wary : c++;

   # In a multigraph, creates a new edge connecting two given nodes.
   # In a normal graph, creates a new edge only if the nodes were not connected yet.
   # Returns the index of the (new) edge.
   # @param Int tail_node
   # @param Int head_node
   # @return Int
   user_method add_edge($$) : non_const : wary : c++;

   # Checks whether two given nodes are connected by (at least) one edge.
   # @param Int tail_node
   # @param Int head_node
   # @return Bool
   user_method edge_exists($$) : wary : c++;

   # Returns an iterator visiting all (parallel) edges connecting two given nodes.
   # @param Int tail_node
   # @param Int head_node
   # @return Iterator
   user_method all_edges($$) : wary : lvalue_opt : c++ : returns(Iterator);

   # Deletes the edge connecting two given nodes, if there was one.
   # In a multigraph, deletes one arbitrary edge from the parallel bundle.
   # @param Int tail_node
   # @param Int head_node
   user_method delete_edge($$) : non_const : void : wary : c++;

   # Delete the edge in a multigraph pointed to by the given iterator
   # @param Iterator iterator as returned by [[all_edges]].
   user_method delete_edge(*) : non_const : void : wary : c++;

   # Deletes all edges in a multigraph connecting two given nodes.
   # @param Int tail_node
   # @param Int head_node
   user_method delete_all_edges($$) : non_const : void : wary : c++;

   # Contract the edge(s) between //node1// and //node2//. Reconnects all edges from //node2// to //node1//,
   # deleting the edge(s) between them and, finally, deleting //node2//.
   # @param Int node1
   # @param Int node2
   user_method contract_edge($$) : non_const : void : wary : c++;

   # Renumbers the valid nodes as to eliminate all gaps left after deleting.
   user_method squeeze() : non_const : void : c++;

   # Deletes all nodes of degree 0,
   # then renumbers the remaining nodes without gaps.
   user_method squeeze_isolated() : non_const : void : c++;

   # Returns a sequence of edges heading to (in Directed case) or incident to (in Undirected case) //node//.
   # @param Int node
   # @return EdgeList
   user_method in_edges($) : wary : anchor : c++ : returns(EdgeList);

   # Returns a sequence of edges leaving (in Directed case) or incident to (in Undirected case) //node//.
   # @param Int node
   # @return EdgeList
   user_method out_edges($) : wary : anchor : c++ : returns(EdgeList);


   # Returns the set of indices of nodes adjacent to //node//.
   # @param Int node
   # @return Set
   user_method adjacent_nodes($) : wary : lvalue_opt : c++;

   # Returns the set of indices of the nodes that have an edge heading to //node//.
   # @param Int node
   # @return Set
   user_method in_adjacent_nodes($) : wary : lvalue_opt : c++;

   # Returns the set of indices of the nodes with an edge arriving from //node//.
   # @param Int node
   # @return Set
   user_method out_adjacent_nodes($) : wary : lvalue_opt : c++;

   # Returns the number of edges heading to //node//.
   # @param Int node
   # @return Int
   user_method in_degree($) : wary : c++;

   # Returns the number of edges leaving //node//.
   # @param Int node
   # @return Int
   user_method out_degree($) : wary : c++;

   # Returns the number of edges incident to //node//.
   # @param Int node
   # @return Int
   user_method degree($) : wary : c++;

   # Returns true if some nodes have been deleted since the last [[squeeze]] operation.
   # @return Bool
   user_method has_gaps() : c++;

   # Returns the maximal node index + 1.
   # If the graph does not have gaps caused by node deletion, the result is equivalent to [[nodes]]().
   # @return Int
   user_method dim() : c++;

   # Create a graph with //n// isolated nodes.
   # @param Int n
   method construct(Int) : c++;

   # Create a (non-multi) graph with adjacency relation between nodes dictated by the given matrix.
   method construct(IncidenceMatrix) : c++;

   type_method toXML {
      my ($proto, $g)=splice @_, 0, 2;
      if ($g->has_gaps) {
         my ($writer, @attr)=@_;
         $writer->startTag("m", @attr, dim => $g->dim);
         local $writer->{"!dim"}=1;
         my $row_type;
         for (my $n=entire(common::nodes($g)); $n; ++$n) {
            my $nodelist=$n->out_adjacent_nodes;
            ($row_type //= $nodelist->type)->toXML->($nodelist, $writer, i=>$$n);
         }
         $writer->endTag("m");
      } else {
         my $am=adjacency_matrix($g);
         $am->type->toXML->($am, @_);
      }
   }

   method init_node_map(*:lvalue:wary) : void : c++;

   method init_edge_map(*:lvalue:wary) : void : c++;

   method enumerate_edges() : void : c++;
}


# @category Graph Operations
# Returns the adjacency matrix of graph nodes.
# For a normal graph, it will be a kind of [[IncidenceMatrix]],
# for multigraph, it will be a [[SparseMatrix<Int>]], with entries encoding the number of parallel edges between two nodes.
# @param Graph graph
# @return IncidenceMatrix both rows and columns correspond to the nodes
user_function adjacency_matrix(Graph:lvalue_opt:anchor) : c++;

function permuted_nodes(Graph, *) : c++;

function renumber_nodes(Graph:anchor) : c++;


# @category Graph Operations
# Returns the sequence of all edges of a graph.
# The edges will appear in ascending order of their tail and head nodes.
# In the Undirected case, the edges will appear once, ordered by the larger index of their incident nodes.
# @param Graph graph
# @return EdgeList
user_function edges(Graph) : c++ : returns(EdgeList);

# @category Artificial
declare property_type NodeSet<*> : c++;

# @category Artificial
declare property_type NodeIterator<*> : Iterator : c++ {

   method out_edges() : c++ : anchor : returns(EdgeList);

   method in_edges() : c++ : anchor : returns(EdgeList);

   method adjacent_nodes() : c++ : anchor;

   method out_adjacent_nodes() : c++ : anchor;

   method in_adjacent_nodes() : c++ : anchor;

   method degree() : c++;

   method in_degree() : c++;

   method out_degree() : c++;
}


# @category Graph Operations
# Returns the sequence of all valid nodes of a graph.
# @param Graph graph
# @return NodeSet
# @example > print nodes(cycle_graph(5)->ADJACENCY);
# {0 1 2 3 4}

user_function nodes(Graph:anchor) : c++ : returns(NodeSet);

function entire(NodeSet:anchor) : c++ : returns(NodeIterator);

# @category Graph Types
# The common abstract base class for all kinds of associative containers that can be attached to a [[Graph]].
# @tparam Dir kind of the host graph: [[Undirected]], [[Directed]], [[UndirectedMulti]], or [[DirectedMulti]]
# @tparam Element data associated with nodes or edges

declare property_type GraphMap<Dir,Element> {

   method construct(Graph<Dir>) : c++;

   method construct(Graph<Dir>, $@) {
      my ($proto, $graph)=splice @_,0,2;
      Core::CPlusPlus::assign_any($proto->construct->($graph), @_);
   }

   type_method equal {
      # the maps may contain gaps, hence got to use iterators
      my ($proto, $m1, $m2)=@_;
      my $elem_proto=$proto->params->[1];
      @$m1==@$m2 and do {
         for (my ($it1, $it2)=(entire($m1), entire($m2)); $it1; ++$it1, ++$it2) {
            $elem_proto->equal->($$it1, $$it2) or return 0;
         }
         1
      }
   }
}

# @category Graph Types
# Dense mapping of nodes to data items.
# @tparam Dir kind of the host graph, [[Undirected]], [[Directed]], [[UndirectedMulti]], or [[DirectedMulti]]
# @tparam Element data associated with nodes
declare property_type NodeMap<Dir,Element> : GraphMap<Dir,Element> \
   : c++ ( include => "polymake/Graph.h", operators => '@eq' );

# @category Graph Types
# Dense mapping of edges to data items.
# @tparam Dir kind of the host graph, [[Undirected]], [[Directed]], [[UndirectedMulti]], or [[DirectedMulti]]
# @tparam Element data associated with edges
declare property_type EdgeMap<Dir,Element> : GraphMap<Dir,Element> \
   : c++ ( include => "polymake/Graph.h", operators => '@eq' ) {

   # Access the data associated with an edge between two given nodes.
   # @param Int from source node
   # @param Int to target node
   user_method edge(Int,Int) : lvalue_opt : wary : c++(name => '()');
}

# @category Graph Types
# Sparse mapping of nodes to data items.
# @tparam Dir one of [[Undirected]], [[Directed]], [[UndirectedMulti]] or [[DirectedMulti]]
# @tparam Element data associated with nodes
declare property_type NodeHashMap<Dir,Element> : GraphMap<Dir,Element> \
   : c++ ( include => "polymake/Graph.h", operators => '@eq' );

# @category Graph Types
# Sparse mapping of edges to data items.
# @tparam Dir one of [[Undirected]], [[Directed]], [[UndirectedMulti]] or [[DirectedMulti]]
# @tparam Element data associated with edges
declare property_type EdgeHashMap<Dir,Element> : GraphMap<Dir,Element> \
   : c++ ( include => "polymake/Graph.h", operators => '@eq' ) {

   # Access the data associated with an edge between two given nodes.
   # The new data element is created on demand.
   # @param Int from source node
   # @param Int to target node
   user_method edge(Int,Int) : lvalue : wary : c++(name => '()');

   # Access the data associated with an edge between two given nodes.
   # @param Int from source node
   # @param Int to target node
   # @return Iterator pointing to the data element (must be dereferenced as ${...}) or undef if the element does not exist.
   user_method find(Int,Int) : wary : c++;

   # Delete the data associated with an edge between two given nodes.
   # @param Int from source node
   # @param Int to target node
   user_method erase(Int,Int) : non_const : void : wary : c++;
}

function createNodeMap<Element,Dir>(Graph<Dir>) { new NodeMap<Dir,Element>(@_) }

function createEdgeMap<Element,Dir>(Graph<Dir>) { new EdgeMap<Dir,Element>(@_) }

function createNodeHashMap<Element,Dir>(Graph<Dir>) { new NodeHashMap<Dir,Element>(@_) }

function createEdgeHashMap<Element,Dir>(Graph<Dir>) { new EdgeHashMap<Dir,Element>(@_) }


# @category Graph Operations
# Creates an induced subgraph for the given subset of nodes.
# @param Graph graph
# @param Set set indices of selected nodes
# @return Graph
# @example $g = new props::Graph(cycle_graph(5)->ADJACENCY);
# > $s1 = new Set(1,2,3);
# > print induced_subgraph($g,$s1);
# | {2}
# | {1 3}
# | {2}

user_function induced_subgraph(Graph:wary:anchor, *:anchor) : c++ ( include => "polymake/IndexedSubgraph.h" );


# @category Graph Operations
# Returns the node-edge incidence matrix of a graph.
# @param Graph graph
# @tparam Coord coordinate type for the resulting matrix, default: [[Int]]
# @return SparseMatrix<Coord>
# @example > print node_edge_incidences(cycle_graph(5)->ADJACENCY);
# | (5) (0 1) (3 1)
# | (5) (0 1) (1 1)
# | (5) (1 1) (2 1)
# | (5) (2 1) (4 1)
# | (5) (3 1) (4 1)

user_function node_edge_incidences<Coord=Int>(Graph) : c++ ( include => "polymake/node_edge_incidences.h" );


# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End: