Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/graphAlgorithms/sPath/check.cpp
00001 // usage:
00002 //      check [src]
00003 //
00004 // check reads two graphs from stdin, and checks to see
00005 // if the second is a shortest path tree of the first.
00006 // It prints a message for each discrepancy that it finds.
00007 //
00008 // This program is not bullet-proof. Caveat emptor.
00009 
00010 #include "stdinc.h"
00011 #include "List.h"
00012 #include "Wdigraph.h"
00013 
00014 using namespace grafalgo;
00015 
00016 void check(int, Wdigraph&, Wdigraph&);
00017 
00018 int main(int argc, char *argv[]) {
00019         int s = 1;
00020         if (argc == 2 && sscanf(argv[1],"%d",&s) != 1)
00021                 Util::fatal("usage: check [src]");
00022         Wdigraph dig; cin >> dig;
00023         Wdigraph sptree; cin >> sptree;
00024         check(s,dig,sptree);
00025 }
00026 
00027 void check(int s, Wdigraph& dig, Wdigraph& sptree) {
00028 // Verify that sptree is a shortest path tree of dig.
00029         vertex u,v; edge e, f;
00030 
00031         // check size of sptree matches dig
00032         if (sptree.n() != dig.n() || sptree.m() != sptree.n()-1)
00033                 Util::fatal("spt_check: size error, aborting");
00034 
00035         // check that sptree is a subgraph of dig
00036         for (v = 1; v <= sptree.n(); v++) {
00037                 if (v == s) continue;
00038                 f = sptree.firstIn(v);
00039                 if (f == 0) 
00040                         cout << "check: non-root vertex " << v
00041                              << " has no incoming edge\n";
00042                 u = sptree.tail(f);
00043                 for (e = dig.firstIn(v); ; e = dig.nextOut(v,e)) {
00044                         if (e == 0) {
00045                                 cout << "check: edge (" << u << "," << v
00046                                      << ") in sptree is not in dig\n";
00047                         }
00048                         if (dig.tail(e) == u) break;
00049                 }
00050         }
00051 
00052         // check that sptree reaches all the vertices
00053         bool* mark = new bool[sptree.n()+1]; int marked;
00054         for (u = 1; u <= sptree.n(); u++) mark[u] = false;
00055         mark[s] = true; marked = 1;
00056         List q(dig.n()); q.addLast(s);
00057         while (!q.empty()) {
00058                 u = q.first(); q.removeFirst();
00059                 for (e = sptree.firstOut(u); e != 0; e = sptree.nextOut(u,e)) {
00060                         v = sptree.head(e);
00061                         if (!mark[v]) {
00062                                 q.addLast(v); mark[v] = true; marked++;
00063                         }
00064                 }
00065         }
00066         if (marked != sptree.n()) {
00067                 cout << "check: sptree does not reach all vertices\n";
00068                 return;
00069         }
00070 
00071         // check that tree is minimum
00072         int du, dv; string s1;
00073         for (u = 1; u <= dig.n(); u++) {
00074                 du = sptree.firstIn(u) == 0 ?
00075                      0 : sptree.length(sptree.firstIn(u));
00076                 for (e = dig.firstOut(u); e != 0; e = dig.nextOut(u,e)) {
00077                         v = dig.head(e);
00078                         dv = sptree.firstIn(v) == 0 ?
00079                              0 : sptree.length(sptree.firstIn(v));
00080                         if (dv > du + dig.length(e))
00081                                 cout << "check: " << dig.edge2string(e,s1)
00082                                      << ") violates spt condition\n";
00083                         if (sptree.firstIn(v) != 0 && 
00084                             sptree.tail(sptree.firstIn(v)) == u && 
00085                             dv != du + dig.length(e))
00086                                 cout << "check: tree edge "
00087                                      << dig.edge2string(e,s1)
00088                                      << " violates spt condition\n";
00089                 }
00090         }
00091 }
 All Classes Files Functions Variables Typedefs Friends