Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/graphAlgorithms/match/match.cpp
00001 // usage: match {size|weight} {bipartite|general} method
00002 //
00003 // Match reads a graph from stdin, computes a matching
00004 // using the method specified by the argument and then prints the
00005 // resulting matching.
00006 //
00007 // Methods currently implemented include
00008 // 
00009 //  size  bipartite     altPath faltPath flowMatch
00010 //  size  general       edmonds
00011 // weight bipartite     flowMatch
00012 //
00013 
00014 #include "stdinc.h"
00015 #include "Dlist.h"
00016 #include "Wgraph.h"
00017 #include "altPath.h"
00018 #include "faltPath.h"
00019 #include "edmonds.h"
00020 #include "fastEdmonds.h"
00021 
00022 using namespace grafalgo;
00023 
00024 extern void flowMatch(Graph&,Dlist&,int&);
00025 extern void flowMatch(Wgraph&,Dlist&,int&,int&);
00026 
00027 int main(int argc, char *argv[]) {
00028         edge e; int i, mSize, mWeight;
00029         bool size, bipartite;
00030         Graph graf; Wgraph wg;
00031         
00032         if (argc != 4)
00033                 Util::fatal("usage: match {size|weight} {bipartite|general} "
00034                             "method");
00035 
00036         if (strcmp(argv[1],"size") == 0)  size = true;
00037         else if (strcmp(argv[1],"weight") == 0)  size = false;
00038         else
00039                 Util::fatal("usage: match {size|weight} {bipartite|general} "
00040                             "method");
00041 
00042         if (strcmp(argv[2],"bipartite") == 0)  bipartite = true;
00043         else if (strcmp(argv[2],"general") == 0)  bipartite = false;
00044         else
00045                 Util::fatal("usage: match {size|weight} {bipartite|general} "
00046                             "method");
00047 
00048         if (size) cin >> graf;
00049         else cin >> wg;
00050 
00051         int n = (size ? graf.n() : wg.n());
00052         int m = (size ? graf.m() : wg.m());
00053 
00054         Dlist match(m);
00055 
00056         if (size && bipartite) {
00057                 if (strcmp(argv[3],"altPath") == 0) {
00058                         altPath(graf,match,mSize);
00059                 } else if (strcmp(argv[3],"faltPath") == 0) {
00060                         faltPath(graf,match,mSize);
00061                 } else if (strcmp(argv[3],"flowMatch") == 0) {
00062                         flowMatch(graf,match,mSize);
00063                 } else {
00064                         Util::fatal("match: invalid method");
00065                 }
00066         } else if (!size && bipartite) {
00067                 if (strcmp(argv[3],"flowMatch") == 0) {
00068                         flowMatch(wg,match,mSize,mWeight);
00069                 } else {
00070                         Util::fatal("match: invalid method");
00071                 }
00072         } else if (size) {
00073                 if (strcmp(argv[3],"edmonds") == 0) {
00074                         edmonds(graf,match,mSize);
00075                 } else if (strcmp(argv[3],"fastEdmonds") == 0) {
00076                         fastEdmonds(graf,match,mSize);
00077                 } else {
00078                         cerr << argv[3];
00079                         Util::fatal("match: invalid method");
00080                 }
00081         } else { // no algorithms for other cases (yet)
00082                 Util::fatal("match: invalid method");
00083         }
00084         cout << mSize << " edges in matching";
00085         if (!size) cout << " with total weight " << mWeight;
00086         cout << endl;
00087 
00088         if (n > 100) exit(0); // don't print out really big matchings
00089         i = 0;
00090         for (e = match.first(); e != 0; e = match.next(e)) {
00091                 string s;
00092                 if (size) {
00093                         cout << "(" << graf.item2string(graf.left(e),s);
00094                         cout << "," << graf.item2string(graf.right(e),s);
00095                 } else {
00096                         cout << "(" << wg.item2string(wg.left(e),s);
00097                         cout << "," << wg.item2string(wg.right(e),s);
00098                         cout << "," << wg.weight(e);
00099                 }
00100                 cout << ") ";
00101                 if ((++i % 5) == 0) cout << endl;
00102         }
00103         cout << endl;
00104 }
 All Classes Files Functions Variables Typedefs Friends