00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00018 #ifndef __defined_libdai_weightedgraph_h
00019 #define __defined_libdai_weightedgraph_h
00020
00021
00022 #include <vector>
00023 #include <map>
00024 #include <iostream>
00025 #include <set>
00026 #include <limits>
00027 #include <climits>
00028
00029 #include <boost/graph/adjacency_list.hpp>
00030 #include <boost/graph/prim_minimum_spanning_tree.hpp>
00031
00032
00033 namespace dai {
00034
00035
00037 class DEdge {
00038 public:
00040 size_t n1;
00041
00043 size_t n2;
00044
00046 DEdge() {}
00047
00049 DEdge( size_t m1, size_t m2 ) : n1(m1), n2(m2) {}
00050
00052 bool operator==( const DEdge &x ) const { return ((n1 == x.n1) && (n2 == x.n2)); }
00053
00055 bool operator!=( const DEdge &x ) const { return !(*this == x); }
00056
00058 bool operator<( const DEdge &x ) const {
00059 return( (n1 < x.n1) || ((n1 == x.n1) && (n2 < x.n2)) );
00060 }
00061
00063 friend std::ostream & operator << (std::ostream & os, const DEdge & e) {
00064 os << "(" << e.n1 << "," << e.n2 << ")";
00065 return os;
00066 }
00067 };
00068
00069
00071 class UEdge {
00072 public:
00074 union {
00075 size_t n1;
00076 size_t first;
00077 };
00079 union {
00080 size_t n2;
00081 size_t second;
00082 };
00083
00085 UEdge() {}
00086
00088 UEdge( size_t m1, size_t m2 ) : n1(m1), n2(m2) {}
00089
00091 UEdge( const DEdge &e ) : n1(e.n1), n2(e.n2) {}
00092
00094 bool operator==( const UEdge &x ) {
00095 return ((n1 == x.n1) && (n2 == x.n2)) || ((n1 == x.n2) && (n2 == x.n1));
00096 }
00097
00099 bool operator<( const UEdge &x ) const {
00100 size_t s = n1, l = n2;
00101 if( s > l )
00102 std::swap( s, l );
00103 size_t xs = x.n1, xl = x.n2;
00104 if( xs > xl )
00105 std::swap( xs, xl );
00106 return( (s < xs) || ((s == xs) && (l < xl)) );
00107 }
00108
00110 friend std::ostream & operator << (std::ostream & os, const UEdge & e) {
00111 if( e.n1 < e.n2 )
00112 os << "{" << e.n1 << "," << e.n2 << "}";
00113 else
00114 os << "{" << e.n2 << "," << e.n1 << "}";
00115 return os;
00116 }
00117 };
00118
00119
00121 class GraphEL : public std::set<UEdge> {
00122 public:
00124 GraphEL() {}
00125
00127 template <class InputIterator>
00128 GraphEL( InputIterator begin, InputIterator end ) {
00129 insert( begin, end );
00130 }
00131 };
00132
00133
00135 typedef GraphEL Graph;
00136
00137
00139 template<class T> class WeightedGraph : public std::map<UEdge, T> {};
00140
00141
00143
00147 class RootedTree : public std::vector<DEdge> {
00148 public:
00150 RootedTree() {}
00151
00153
00155 RootedTree( const GraphEL &T, size_t Root );
00156 };
00157
00158
00160
00162 template<typename T> RootedTree MinSpanningTreePrims( const WeightedGraph<T> &G ) {
00163 RootedTree result;
00164 if( G.size() > 0 ) {
00165 using namespace boost;
00166 using namespace std;
00167 typedef adjacency_list< vecS, vecS, undirectedS, property<vertex_distance_t, int>, property<edge_weight_t, double> > boostGraph;
00168 typedef pair<size_t, size_t> E;
00169
00170 set<size_t> nodes;
00171 vector<E> edges;
00172 vector<double> weights;
00173 edges.reserve( G.size() );
00174 weights.reserve( G.size() );
00175 for( typename WeightedGraph<T>::const_iterator e = G.begin(); e != G.end(); e++ ) {
00176 weights.push_back( e->second );
00177 edges.push_back( E( e->first.n1, e->first.n2 ) );
00178 nodes.insert( e->first.n1 );
00179 nodes.insert( e->first.n2 );
00180 }
00181
00182 boostGraph g( edges.begin(), edges.end(), weights.begin(), nodes.size() );
00183 vector< graph_traits< boostGraph >::vertex_descriptor > p( num_vertices(g) );
00184 prim_minimum_spanning_tree( g, &(p[0]) );
00185
00186
00187 GraphEL tree;
00188 size_t root = 0;
00189 for( size_t i = 0; i != p.size(); i++ )
00190 if( p[i] != i )
00191 tree.insert( UEdge( p[i], i ) );
00192 else
00193 root = i;
00194
00195 result = RootedTree( tree, root );
00196 }
00197 return result;
00198 }
00199
00200
00202
00204 template<typename T> RootedTree MaxSpanningTreePrims( const WeightedGraph<T> &G ) {
00205 if( G.size() == 0 )
00206 return RootedTree();
00207 else {
00208 T maxweight = G.begin()->second;
00209 for( typename WeightedGraph<T>::const_iterator it = G.begin(); it != G.end(); it++ )
00210 if( it->second > maxweight )
00211 maxweight = it->second;
00212
00213 WeightedGraph<T> gr( G );
00214
00215
00216 for( typename WeightedGraph<T>::iterator it = gr.begin(); it != gr.end(); it++ )
00217 it->second = maxweight - it->second;
00218 return MinSpanningTreePrims( gr );
00219 }
00220 }
00221
00222
00224
00230 GraphEL RandomDRegularGraph( size_t N, size_t d );
00231
00232
00233 }
00234
00235
00236 #endif