Grafalgo
Library of useful data structures and algorithms
|
00001 00009 #include "Wdigraph.h" 00010 00011 namespace grafalgo { 00012 00017 Wdigraph::Wdigraph(int numv, int maxe) : Digraph(numv,maxe) { 00018 makeSpace(numv,maxe); 00019 } 00020 00021 Wdigraph::~Wdigraph() { freeSpace(); } 00022 00027 void Wdigraph::makeSpace(int numv, int maxe) { 00028 try { 00029 len = new int[maxe+1]; 00030 } catch (std::bad_alloc e) { 00031 stringstream ss; 00032 ss << "Wdigraph::makeSpace: insufficient space for " 00033 << maxe << " edge lengths"; 00034 string s = ss.str(); 00035 throw OutOfSpaceException(s); 00036 } 00037 } 00038 00040 void Wdigraph::freeSpace() { delete [] len; } 00041 00047 void Wdigraph::resize(int numv, int maxe) { 00048 freeSpace(); 00049 Digraph::resize(numv,maxe); 00050 try { makeSpace(numv,maxe); } catch(OutOfSpaceException e) { 00051 string s; s = "Wdigraph::resize:" + e.toString(s); 00052 throw OutOfSpaceException(s); 00053 } 00054 } 00055 00060 void Wdigraph::expand(int numv, int maxe) { 00061 if (numv <= n() && maxe <= maxEdge) return; 00062 Wdigraph old(this->n(),this->maxEdge); old.copyFrom(*this); 00063 resize(numv,maxe); this->copyFrom(old); 00064 } 00065 00067 void Wdigraph::copyFrom(const Wdigraph& source) { 00068 if (&source == this) return; 00069 if (source.n() > n() || source.m() > maxEdge) 00070 resize(source.n(),source.m()); 00071 else clear(); 00072 for (edge e = source.first(); e != 0; e = source.next(e)) { 00073 edge ee = join(source.tail(e),source.head(e)); 00074 setLength(ee,source.length(e)); 00075 } 00076 sortAdjLists(); 00077 } 00078 00083 bool Wdigraph::readAdjList(istream& in) { 00084 if (!Util::verify(in,'[')) return 0; 00085 vertex u; 00086 if (!Adt::readItem(in,u)) return 0; 00087 if (u > n()) expand(u,m()); 00088 if (!Util::verify(in,':')) return 0; 00089 while (in.good() && !Util::verify(in,']')) { 00090 vertex v; 00091 if (!Adt::readItem(in,v)) return 0; 00092 if (v > n()) expand(v,m()); 00093 if (m() >= maxEdge) expand(n(),max(1,2*m())); 00094 int w; 00095 if (!Util::verify(in,'(') || !Util::readInt(in,w) || 00096 !Util::verify(in,')')) 00097 return 0; 00098 edge e = join(u,v); setLength(e,w); 00099 } 00100 return in.good(); 00101 } 00102 00108 string& Wdigraph::adjList2string(vertex u, string& s) const { 00109 stringstream ss; s = ""; 00110 if (firstAt(u) == 0) return s; 00111 int cnt = 0; 00112 ss << "[" << Adt::item2string(u,s) << ":"; 00113 for (edge e = firstOut(u); e != 0; e = nextOut(u,e)) { 00114 vertex v = head(e); 00115 ss << " " << item2string(v,s) << "(" << length(e) << ")"; 00116 if (++cnt >= 15 && nextOut(u,e) != 0) { 00117 ss << "\n"; cnt = 0; 00118 } 00119 } 00120 ss << "]\n"; 00121 s = ss.str(); 00122 return s; 00123 } 00124 00125 00132 string& Wdigraph::edge2string(edge e, string& s) const { 00133 stringstream ss; 00134 vertex u = tail(e); vertex v = head(e); 00135 ss << "(" << item2string(u,s) << ","; 00136 ss << item2string(v,s) << "," << length(e) + ")"; 00137 s = ss.str(); 00138 return s; 00139 } 00140 00150 string& Wdigraph::toDotString(string& s) const { 00151 stringstream ss; 00152 ss << "digraph G { " << endl; 00153 int cnt = 0; 00154 for (edge e = first(); e != 0; e = next(e)) { 00155 vertex u = tail(e); vertex v = head(e); 00156 ss << Adt::item2string(u,s) << " -> "; 00157 ss << Adt::item2string(v,s); 00158 ss << " [label = \" " << length(e) << " \"] ; "; 00159 if (++cnt == 10) { s += "\n"; cnt = 0; } 00160 } 00161 ss << "}\n" << endl; 00162 s = ss.str(); 00163 return s; 00164 } 00165 00170 /* 00171 bool Wdigraph::readEdge(istream& in) { 00172 vertex u, v; int len; 00173 if (!Util::verify(in,'(') || !Util::readNode(in,u,n()) || 00174 !Util::verify(in,',') || !Util::readNode(in,v,n()) || 00175 !Util::verify(in,',') || !Util::readNum(in,len) || 00176 !Util::verify(in,')')) { 00177 return false; 00178 } 00179 edge e = join(u,v); 00180 setLength(e,len); 00181 00182 return true; 00183 } 00184 */ 00185 00190 void Wdigraph::randLength(int lo, int hi) { 00191 for (edge e = first(); e != 0; e = next(e)) 00192 setLength(e,Util::randint(lo,hi)); 00193 } 00194 00195 } // ends namespace