Grafalgo
Library of useful data structures and algorithms
|
00001 00008 #include "Flograph.h" 00009 00010 #define flo(x) floInfo[x].flo 00011 #define cpy(x) floInfo[x].cpy 00012 00013 namespace grafalgo { 00014 00021 Flograph::Flograph(int numv, int maxe, int s1, int t1) 00022 : Digraph(numv, maxe), s(s1), t(t1) { 00023 assert(n() >= 2 && maxEdge >= 0 && 1 <= s && s <= n() 00024 && 1 <= t && t <= n() && s != t); 00025 makeSpace(numv,maxe); 00026 } 00027 00028 Flograph::~Flograph() { freeSpace(); } 00029 00034 void Flograph::makeSpace(int numv, int maxe) { 00035 try { 00036 floInfo = new FloInfo[maxe+1]; 00037 } catch (std::bad_alloc e) { 00038 stringstream ss; 00039 ss << "Flograph::makeSpace: insufficient space for " 00040 << maxe << " edge weights"; 00041 string s = ss.str(); 00042 throw OutOfSpaceException(s); 00043 } 00044 } 00045 00047 void Flograph::freeSpace() { delete [] floInfo; } 00048 00054 void Flograph::resize(int numv, int maxe) { 00055 freeSpace(); 00056 Digraph::resize(numv,maxe); 00057 try { makeSpace(numv,maxe); } catch(OutOfSpaceException e) { 00058 string s; s = "Flograph::resize:" + e.toString(s); 00059 throw OutOfSpaceException(s); 00060 } 00061 } 00062 00067 void Flograph::expand(int numv, int maxe) { 00068 if (numv <= n() && maxe <= maxEdge) return; 00069 Flograph old(this->n(),this->maxEdge); old.copyFrom(*this); 00070 resize(numv,maxe); this->copyFrom(old); 00071 } 00072 00074 void Flograph::copyFrom(const Flograph& source) { 00075 if (&source == this) return; 00076 if (source.n() > n() || source.m() > maxEdge) 00077 resize(source.n(),source.m()); 00078 else clear(); 00079 for (edge e = source.first(); e != 0; e = source.next(e)) { 00080 edge ee = join(source.tail(e),source.head(e)); 00081 setCapacity(ee,source.cap(source.tail(e),e)); 00082 setFlow(ee,source.f(source.tail(e),e)); 00083 } 00084 sortAdjLists(); 00085 } 00086 00091 bool Flograph::readAdjList(istream& in) { 00092 if (!Util::verify(in,'[')) return 0; 00093 bool isSrc = false; bool isSnk = false; 00094 if (Util::verify(in,'-')) { 00095 if (!Util::verify(in,'>',true)) return 0; 00096 isSnk = true; 00097 } 00098 vertex u; 00099 if (!Adt::readItem(in,u)) return 0; 00100 if (Util::verify(in,'-')) { 00101 if (!Util::verify(in,'>',true)) return 0; 00102 isSrc = true; 00103 } 00104 if (!Util::verify(in,':')) return 0; 00105 if (u > n()) expand(u,m()); 00106 if (isSrc) setSrc(u); 00107 if (isSnk) setSnk(u); 00108 while (in.good() && !Util::verify(in,']')) { 00109 vertex v; 00110 if (!Adt::readItem(in,v)) return 0; 00111 if (v > n()) expand(v,m()); 00112 if (m() >= maxEdge) expand(n(),max(1,2*m())); 00113 int capacity, flow; 00114 if (!Util::verify(in,'(') || !Util::readInt(in,capacity) || 00115 !Util::verify(in,',') || !Util::readInt(in,flow) || 00116 !Util::verify(in,')')) 00117 return 0; 00118 edge e = join(u,v); 00119 setCapacity(e,capacity); setFlow(e,flow); 00120 } 00121 return in.good(); 00122 } 00123 00129 edge Flograph::join(vertex u, vertex v) { 00130 assert(1 <= u && u <= n() && 1 <= v && v <= n() && m() < maxEdge); 00131 edge e = Digraph::join(u,v); setFlow(e,0); 00132 return e; 00133 } 00134 00137 void Flograph::clearFlow() { 00138 for (edge e = first(); e != 0; e = next(e)) setFlow(e,0); 00139 } 00140 00147 void Flograph::addFlow(vertex v, edge e, flow ff) { 00148 if (tail(e) == v) { 00149 if (ff + flo(e) > cpy(e) || ff + flo(e) < 0) { 00150 Util::fatal("addflow: requested flow outside allowed " 00151 "range"); 00152 } 00153 flo(e) += ff; 00154 } else { 00155 if (flo(e) - ff < 0 || flo(e) - ff > cpy(e)) { 00156 Util::fatal("addflow: requested flow outside allowed " 00157 "range"); 00158 } 00159 flo(e) -= ff; 00160 } 00161 } 00162 00168 string& Flograph::edge2string(edge e, string& s) const { 00169 stringstream ss; 00170 vertex u = tail(e); vertex v = head(e); 00171 if (e == 0) { 00172 ss << "-"; 00173 } else { 00174 ss << "(" << item2string(u,s); 00175 ss << "," << item2string(v,s) 00176 << "," << cap(u,e) << "," << f(u,e) << ")"; 00177 } 00178 s = ss.str(); 00179 return s; 00180 } 00181 00187 string& Flograph::adjList2string(vertex u, string& s) const { 00188 s = ""; 00189 if (firstOut(u) == 0) return s; 00190 stringstream ss; 00191 ss << "["; 00192 if (u == snk()) ss << "->"; 00193 ss << Adt::item2string(u,s); 00194 if (u == src()) ss << "->"; 00195 ss << ":"; 00196 int cnt = 0; 00197 for (edge e = firstOut(u); e != 0; e = nextOut(u,e)) { 00198 vertex v = head(e); 00199 ss << " " << Adt::item2string(v,s) << "(" << cap(u,e) << "," 00200 << f(u,e) << ")"; 00201 if (++cnt >= 15 && nextOut(u,e) != 0) { 00202 ss << "\n"; cnt = 0; 00203 } 00204 } 00205 ss << "]\n"; 00206 s = ss.str(); 00207 return s; 00208 } 00209 00214 string& Flograph::toDotString(string& s) const { 00215 stringstream ss; 00216 ss << "digraph G { " << endl; 00217 ss << Adt::item2string(src(),s) 00218 << " [ style = bold, peripheries = 2, color = red]; " 00219 << endl; 00220 ss << Adt::item2string(snk(),s) 00221 << " [ style = bold, peripheries = 2, color = blue]; " 00222 << endl; 00223 int cnt = 0; 00224 for (edge e = first(); e != 0; e = next(e)) { 00225 vertex u = min(left(e),right(e)); 00226 vertex v = max(left(e),right(e)); 00227 ss << Adt::item2string(u,s) << " -> "; 00228 ss << Adt::item2string(v,s); 00229 ss << " [label = \"(" << cap(u,e) << "," << f(u,e) << ")\"]; "; 00230 if (++cnt == 10) { s += "\n"; cnt = 0; } 00231 } 00232 ss << "}\n" << endl; 00233 s = ss.str(); 00234 return s; 00235 } 00236 00242 void Flograph::shuffle(int vp[], int ep[]) { 00243 edge e; 00244 FloInfo *floInfo1 = new FloInfo[m()+1]; 00245 00246 Digraph::shuffle(vp,ep); 00247 for (e = 1; e <= m(); e++) floInfo1[ep[e]] = floInfo[e]; 00248 for (e = 1; e <= m(); e++) floInfo[e] = floInfo1[e]; 00249 s = vp[s]; t = vp[t]; 00250 00251 delete [] floInfo1; 00252 } 00253 00264 void Flograph::rgraph(int numv, int nume, int mss) { 00265 mss = max(1,mss); mss = min(mss,(numv-2)/4); 00266 numv = max(numv,3); nume = max(2*mss,nume); 00267 00268 if (n() != numv || maxEdge < nume) resize(numv,nume); 00269 else clear(); 00270 Digraph::rgraph(numv-2,nume-2*mss); 00271 setSrc(numv-1); setSnk(numv); 00272 00273 vertex *neighbors = new vertex[2*mss+1]; 00274 Util::genPerm(2*mss,neighbors); 00275 for (int i = 1; i <= mss; i++) { 00276 join(src(),neighbors[i]); 00277 } 00278 Util::genPerm(2*mss,neighbors); 00279 for (int i = 1; i <= mss; i++) { 00280 join((numv-2)-neighbors[i],snk()); 00281 } 00282 sortAdjLists(); 00283 00284 delete [] neighbors; 00285 } 00286 00292 void Flograph::randCapacity(flow ec1, flow ec2) { 00293 for (edge e = first(); e != 0; e = next(e)) { 00294 if (tail(e) == s || head(e) == t) 00295 setCapacity(e,Util::randint(1,ec1)); 00296 else 00297 setCapacity(e,Util::randint(1,ec2)); 00298 } 00299 } 00300 00301 } // ends namespace