The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.
The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.
The ResGraphAdaptor is based on this composition.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #include <lemon/list_graph.h>
20 #include <lemon/graph_utils.h>
21 #include <lemon/graph_writer.h>
23 #include <lemon/graph_to_eps.h>
31 using namespace lemon;
34 // It gives back a position for each node. The position of the nodes
35 // are on the circle with the given center and radius.
37 // Because we use the descriptor map it will hold the proprty described above
38 // even if a node added or deleted.
39 template <typename Graph>
43 typedef xy<double> Value;
44 typedef typename Graph::Node Key;
46 CircleMap(const Graph& _graph,
47 const Value& _center = Value(0.0, 0.0),
49 : descriptor(_graph), center(_center), radius(_radius) {}
51 Value operator[](const Key& key) const {
52 double angle = descriptor[key] * 2 * M_PI
53 / (double)descriptor.inverse().size();
54 double x = std::cos(angle) * radius + center.x;
55 double y = std::sin(angle) * radius + center.y;
61 DescriptorMap<Graph, typename Graph::Node> descriptor;
67 std::srand(std::time(0));
68 typedef ListGraph Graph;
69 typedef Graph::Node Node;
70 typedef Graph::Edge Edge;
74 std::cout << "Generating graph: " << std::endl;
79 for (int i = 0; i < NODE; ++i) {
83 // Creating descriptor map and inverse
84 DescriptorMap<Graph, Node> nodeDesc(graph);
85 DescriptorMap<Graph, Node>::InverseMap nodeInv(nodeDesc);
88 // The descriptor map always maps an integer value for each node.
89 // The range of the values is always [0..n - 1] where n is the
90 // number of the nodes of the graph. The inverse map gives back the
91 // the node by its descriptor value.
93 // The inversemap cannot works without its DescriptorMap because
94 // it holds reference to it.
95 const int EDGE = (int)(NODE * std::log(double(NODE)));
96 for (int i = 0; i < EDGE; ++i) {
97 int si = (int)(std::rand() / (RAND_MAX + 1.0) * NODE);
98 int ti = (int)(std::rand() / (RAND_MAX + 1.0) * NODE);
100 graph.addEdge(nodeInv[si], nodeInv[ti]);
103 GraphWriter<Graph>(std::cout, graph).run();
105 std::cout << std::endl;
106 std::cout << "Postscript file: descriptor_map_demo.eps" << std::endl;
108 // Make postscript from the graph.
110 CircleMap<Graph> coords(graph, xy<double>(0.0, 0.0), 10.0);
112 graphToEps(graph,"descriptor_map_demo.eps").scaleToA4().
113 title("Generated graph").
114 copyright("(C) 2006 LEMON Project").
117 enableParallel().parEdgeDist(1).
118 drawArrows().arrowWidth(1).arrowLength(1).