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:
|