Grafalgo
Library of useful data structures and algorithms
|
00001 00009 #include "stdinc.h" 00010 #include "Wgraph.h" 00011 00012 namespace grafalgo { 00013 00018 Wgraph::Wgraph(int numv, int maxe) : Graph(numv,maxe) { 00019 makeSpace(numv, maxe); 00020 } 00021 00023 Wgraph::~Wgraph() { freeSpace(); } 00024 00029 void Wgraph::makeSpace(int numv, int maxe) { 00030 try { 00031 wt = new int[maxe+1]; 00032 } catch (std::bad_alloc e) { 00033 stringstream ss; 00034 ss << "Wgraph::makeSpace: insufficient space for " 00035 << maxe << " edge weights"; 00036 string s = ss.str(); 00037 throw OutOfSpaceException(s); 00038 } 00039 } 00040 00042 void Wgraph::freeSpace() { delete [] wt; } 00043 00049 void Wgraph::resize(int numv, int maxe) { 00050 freeSpace(); 00051 Graph::resize(numv,maxe); 00052 try { makeSpace(numv,maxe); } catch(OutOfSpaceException e) { 00053 string s; s = "Wgraph::resize:" + e.toString(s); 00054 throw OutOfSpaceException(s); 00055 } 00056 } 00057 00062 void Wgraph::expand(int numv, int maxe) { 00063 if (numv <= n() && maxe <= maxEdge) return; 00064 Wgraph old(this->n(),this->maxEdge); old.copyFrom(*this); 00065 resize(numv,maxe); this->copyFrom(old); 00066 } 00067 00069 void Wgraph::copyFrom(const Wgraph& source) { 00070 if (&source == this) return; 00071 if (source.n() > n() || source.m() > maxEdge) 00072 resize(source.n(),source.m()); 00073 else clear(); 00074 for (edge e = source.first(); e != 0; e = source.next(e)) { 00075 edge ee = join(source.left(e),source.right(e)); 00076 setWeight(ee,source.weight(e)); 00077 } 00078 sortAdjLists(); 00079 } 00080 00085 bool Wgraph::readAdjList(istream& in) { 00086 if (!Util::verify(in,'[')) return 0; 00087 vertex u; 00088 if (!Adt::readItem(in,u)) return 0; 00089 if (u > n()) expand(u,m()); 00090 if (!Util::verify(in,':')) return 0; 00091 while (in.good() && !Util::verify(in,']')) { 00092 vertex v; 00093 if (!Adt::readItem(in,v)) return 0; 00094 if (v > n()) expand(v,m()); 00095 if (m() >= maxEdge) expand(n(),max(1,2*m())); 00096 int w; 00097 if (!Util::verify(in,'(') || !Util::readInt(in,w) || 00098 !Util::verify(in,')')) 00099 return 0; 00100 if (u < v) { edge e = join(u,v); setWeight(e,w); } 00101 } 00102 return in.good(); 00103 } 00104 00111 string& Wgraph::edge2string(edge e, vertex u, string& s) const { 00112 stringstream ss; 00113 vertex v = mate(u,e); 00114 ss << "(" << item2string(u,s); 00115 ss << "," << item2string(v,s) << "," << weight(e) << ")"; 00116 s = ss.str(); 00117 return s; 00118 } 00119 00125 string& Wgraph::adjList2string(vertex u, string& s) const { 00126 stringstream ss; s = ""; 00127 if (firstAt(u) == 0) return s; 00128 int cnt = 0; 00129 ss << "[" << Adt::item2string(u,s) << ":"; 00130 for (edge e = firstAt(u); e != 0; e = nextAt(u,e)) { 00131 vertex v = mate(u,e); 00132 ss << " " << item2string(v,s) << "(" << weight(e) << ")"; 00133 if (++cnt >= 15 && nextAt(u,e) != 0) { 00134 ss << "\n"; cnt = 0; 00135 } 00136 } 00137 ss << "]\n"; 00138 s = ss.str(); 00139 return s; 00140 } 00141 00146 void Wgraph::randWeight(int lo, int hi) { 00147 for (edge e = first(); e != 0; e = next(e)) 00148 setWeight(e,Util::randint(lo,hi)); 00149 } 00150 00160 string& Wgraph::toDotString(string& s) const { 00161 stringstream ss; 00162 ss << "graph G { " << endl; 00163 int cnt = 0; 00164 for (edge e = first(); e != 0; e = next(e)) { 00165 vertex u = min(left(e),right(e)); 00166 vertex v = max(left(e),right(e)); 00167 ss << Adt::item2string(u,s) << " -- "; 00168 ss << Adt::item2string(v,s); 00169 ss << " [label = \" " << weight(e) << " \"] ; "; 00170 if (++cnt == 10) { s += "\n"; cnt = 0; } 00171 } 00172 ss << "}\n" << endl; 00173 s = ss.str(); 00174 return s; 00175 } 00176 00177 } // ends namespace