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
|
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// This file is part of the Boost Graph Library
//
// You should have received a copy of the License Agreement for the
// Boost Graph Library along with the software; see the file LICENSE.
// If not, contact Office of Research, Indiana University,
// Bloomington, IN 47405.
//
// Permission to modify the code and to distribute the code is
// granted, provided the text of this NOTICE is retained, a notice if
// the code was modified is included with the above COPYRIGHT NOTICE
// and with the COPYRIGHT NOTICE in the LICENSE file, and that the
// LICENSE file is distributed with the modified code.
//
// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
// By way of example, but not limitation, Licensor MAKES NO
// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
// OR OTHER RIGHTS.
//=======================================================================
#include <fstream> // for file I/O
#include <boost/graph/graphviz.hpp> // for read/write_graphviz()
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/lexical_cast.hpp>
int
main()
{
using namespace boost;
GraphvizDigraph g_dot;
read_graphviz("figs/ospf-graph.dot", g_dot);
typedef adjacency_list < vecS, vecS, directedS, no_property,
property < edge_weight_t, int > > Graph;
typedef graph_traits < Graph >::vertex_descriptor vertex_descriptor;
Graph g(num_vertices(g_dot));
property_map < GraphvizDigraph, edge_attribute_t >::type
edge_attr_map = get(edge_attribute, g_dot);
graph_traits < GraphvizDigraph >::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(g_dot); ei != ei_end; ++ei) {
int weight = lexical_cast < int >(edge_attr_map[*ei]["label"]);
property < edge_weight_t, int >edge_property(weight);
add_edge(source(*ei, g_dot), target(*ei, g_dot), edge_property, g);
}
vertex_descriptor router_six;
property_map < GraphvizDigraph, vertex_attribute_t >::type
vertex_attr_map = get(vertex_attribute, g_dot);
graph_traits < GraphvizDigraph >::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi)
if ("RT6" == vertex_attr_map[*vi]["label"]) {
router_six = *vi;
break;
}
std::vector < vertex_descriptor > parent(num_vertices(g));
// All vertices start out as there own parent
typedef graph_traits < Graph >::vertices_size_type size_type;
for (size_type p = 0; p < num_vertices(g); ++p)
parent[p] = p;
#ifdef BOOST_MSVC
std::vector<int> distance(num_vertices(g));
property_map<Graph, edge_weight_t>::type weightmap = get(edge_weight, g);
property_map<Graph, vertex_index_t>::type indexmap = get(vertex_index, g);
dijkstra_shortest_paths
(g, router_six, &parent[0], &distance[0], weightmap,
indexmap, std::less<int>(), closed_plus<int>(),
std::numeric_limits<int>::max(), 0, default_dijkstra_visitor());
#else
dijkstra_shortest_paths(g, router_six, predecessor_map(&parent[0]));
#endif
graph_traits < GraphvizDigraph >::edge_descriptor e;
for (size_type i = 0; i < num_vertices(g); ++i)
if (parent[i] != i) {
e = edge(parent[i], i, g_dot).first;
edge_attr_map[e]["color"] = "black";
}
#ifdef BOOST_MSVC
// VC++ can't handle write_graphviz :(
{
std::ofstream out("figs/ospf-sptree.dot");
out << "digraph loops {\n"
<< "size=\"3,3\"\n"
<< "ratio=\"fill\"\n"
<< "shape=\"box\"\n";
graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
out << *vi << "[";
for (std::map<std::string,std::string>::iterator ai = vattr_map[*vi].begin();
ai != vattr_map[*vi].end(); ++ai) {
out << ai->first << "=" << ai->second;
if (next(ai) != vattr_map[*vi].end())
out << ", ";
}
out<< "]";
}
for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
out << source(*ei, g) << " -> " << target(*ei, g) << "[";
std::map<std::string,std::string>& attr_map = eattr_map[*ei];
for (std::map<std::string,std::string>::iterator eai = attr_map.begin();
eai != attr_map.end(); ++eai) {
out << eai->first << "=" << eai->second;
if (next(eai) != attr_map.end())
out << ", ";
}
out<< "]";
}
out << "}\n";
}
#else
graph_property < GraphvizDigraph, graph_edge_attribute_t >::type &
graph_edge_attr_map = get_property(g_dot, graph_edge_attribute);
graph_edge_attr_map["color"] = "grey";
write_graphviz("figs/ospf-sptree.dot", g_dot);
#endif
std::ofstream rtable("routing-table.dat");
rtable << "Dest Next Hop Total Cost" << std::endl;
for (tie(vi, vi_end) = vertices(g_dot); vi != vi_end; ++vi)
if (parent[*vi] != *vi) {
rtable << vertex_attr_map[*vi]["label"] << " ";
vertex_descriptor v = *vi, child;
int path_cost = 0;
property_map < Graph, edge_weight_t >::type
weight_map = get(edge_weight, g);
do {
path_cost += get(weight_map, edge(parent[v], v, g).first);
child = v;
v = parent[v];
} while (v != parent[v]);
rtable << vertex_attr_map[child]["label"] << " ";
rtable << path_cost << std::endl;
}
return EXIT_SUCCESS;
}
|