00001 #include "dinic.hpp"
00002
00003 #include <fstream>
00004
00005 #include "PG_ostream.hpp"
00006
00007 void print()
00008 {
00009 if( _libbase.rank() == 0 ) std::cout << "Der Graph: " << std::endl;
00010 std::cout << *g;
00011 }
00012
00013 AllToAllBuffer dummy_buf;
00014
00015 void read_graph( std::istream & istr )
00016 {
00017 char c;
00018 bool has_pline = false;
00019 size_t vsize=0;
00020 while( istr.get(c) )
00021 {
00022 switch(c)
00023 {
00024 case 'p':
00025 istr >> vsize;
00026 for( size_t i = 0 ; i < vsize ; i++ )
00027 {
00028 vertex_property_type v_prop(0);
00029 g->insert( i, v_prop );
00030 }
00031 has_pline = true;
00032 case 'c':
00033 case '#':
00034 do {
00035 istr.get(c);
00036 } while( c != '\n' );
00037 break;
00038 case 'n':
00039 case 'v':
00040 {
00041 VertexID_t v;
00042 proc_t p;
00043 istr >> v;
00044 istr >> p;
00045 int size = -1;
00046 do {
00047 size++;
00048 istr.get(c);
00049 } while( c != '\n' );
00050 char * name = new char[size];
00051 for(int i = 0 ; i < size ; i++ ) istr.unget();
00052 istr.get( name, size ); istr.get(c);
00053 if( has_pline )
00054 {
00055
00056 }
00057 else
00058 {
00059 std::cout<<"error"<<std::endl;exit(0);
00060
00061 g->insert( v );
00062 }
00063 if( strcmp( name, "s" ) == 0 ) (*set_s_vertex).insert( v );
00064 if( strcmp( name, "t" ) == 0 ) (*set_t_vertex).insert( v );
00065 }
00066 break;
00067 case 'a':
00068 case 'e':
00069 VertexID_t v1, v2;
00070 EdgeID_t e;
00071 unsigned int cap;
00072 istr >> e;
00073 istr >> v1;
00074 istr >> v2;
00075 istr >> cap;
00076 do {
00077 istr.get(c);
00078 } while( c != '\n' );
00079 network_edges_property_type e_prop( cap,
00080 network_edges_property_type::next_type( 0 ));
00081 add_edge_with_id( network_edges, e, v1, v2, e_prop, *g, dummy_buf );
00082 }
00083 }
00084 }
00085
00086 void random_graph( VertexID_t vsize, EdgeID_t esize, unsigned int maxcap, unsigned int seed, std::ostream & ostr )
00087 {
00088 ostr << "p " << vsize << " " << esize << std::endl;
00089 srand( seed );
00090 VertexID_t v = 0, s = rand() % vsize, t = rand() % vsize;
00091 if( s == t ) t = (t + 1) % vsize;
00092 for(; v < vsize ; v++ )
00093 {
00094 if( v == s )
00095 ostr << "v " << v << " 0 s" << std::endl;
00096 if( v == t )
00097 ostr << "v " << v << " 0 t" << std::endl;
00098
00099 vertex_property_type v_prop;
00100 g->insert( v, v_prop );
00101 }
00102 (*set_s_vertex).insert( s );
00103 (*set_t_vertex).insert( t );
00104 for( EdgeID_t e = 0 ; e < esize ; e++ )
00105 {
00106 VertexID_t v1 = rand() % vsize, v2 = rand() % vsize;
00107 if( v1 == v2 ) v2 = (v2 + 1) % vsize;
00108 unsigned int cap = (rand() % maxcap) + 1;
00109 network_edges_property_type e_prop( cap,
00110 network_edges_property_type::next_type( 0 ));
00111 add_edge_with_id( network_edges, e, v1, v2, e_prop, *g, dummy_buf );
00112 ostr << "e " << e << " " << v1 << " " << v2 << " " << cap <<std::endl;
00113 }
00114 }
00115
00116 void rect_graph_add_edge( VertexID_t v1, VertexID_t v2, EdgeID_t * e, unsigned int maxcap, std::ostream & ostr )
00117 {
00118 unsigned int cap = (rand() % maxcap) + 1;
00119 network_edges_property_type e_prop( cap,
00120 network_edges_property_type::next_type( 0 ));
00121 add_edge_with_id( network_edges, *e, v1, v2, e_prop, *g, dummy_buf );
00122 ostr << "e " << *e << " " << v1 << " " << v2 << " " << cap <<std::endl;
00123 (*e)++;
00124 }
00125
00126 void rectangular_graph( size_t breadth, size_t length, unsigned int maxcap, unsigned int seed, std::ostream & ostr )
00127 {
00128 size_t vsize = breadth * length + 2;
00129 size_t esize = 4 * breadth * length - breadth - 3 * length + 2;
00130 ostr << "p " << vsize << " " << esize << std::endl;
00131 srand( seed );
00132
00133 VertexID_t v = 0, s = vsize - 2, t = vsize - 1;
00134 for(; v < vsize ; v++ )
00135 {
00136 vertex_property_type v_prop;
00137 g->insert( v, v_prop );
00138 }
00139 (*set_s_vertex).insert( s );
00140 (*set_t_vertex).insert( t );
00141 ostr << "v " << s << " 0 s" << std::endl;
00142 ostr << "v " << t << " 0 t" << std::endl;
00143
00144 EdgeID_t e = 0;
00145 for( size_t i = 0 ; i < breadth ; i++ )
00146 {
00147 for( size_t j = 0 ; j < length ; j++ )
00148 {
00149 VertexID_t v1 = i + j * breadth;
00150 if( j < length - 1 )
00151 rect_graph_add_edge( v1, i + (j + 1) * breadth,
00152 &e, maxcap, ostr );
00153 if( j < length - 1 && i < breadth - 1 )
00154 rect_graph_add_edge( v1, i + 1 + (j + 1) * breadth,
00155 &e, maxcap, ostr );
00156 if( j < length - 1 && i > 0 )
00157 rect_graph_add_edge( v1, i - 1 + (j + 1) * breadth,
00158 &e, maxcap, ostr );
00159 if( i < breadth - 1 )
00160 rect_graph_add_edge( v1, i + 1 + j * breadth,
00161 &e, maxcap, ostr );
00162 if( i > 0 )
00163 rect_graph_add_edge( v1, i - 1 + j * breadth,
00164 &e, maxcap, ostr );
00165 }
00166 rect_graph_add_edge( s, i, &e, maxcap, ostr );
00167 rect_graph_add_edge( i + breadth * ( length - 1 ), t,
00168 &e, maxcap, ostr );
00169 }
00170 }
00171
00172 void dinic_read_graph( int argc, char **argv )
00173 {
00174 if( argc != 2 && argc != 7 )
00175 {
00176 if( rank() == 0 )
00177 {
00178 std::cout << "USAGE: dinic <Datafile>\n"
00179 << " dinic r <VertiexSize> <EdgeSize> <MaxCapacity> <Seed> <Datafile>\n"
00180 << " dinic q <Breadth> <Length> <MaxCapacity> <Seed> <Datafile>\n"
00181 << "Calculates the maximum flow of a graph.\n"
00182 << "The first variant reads the graph from <Datafile>.\n"
00183 << "The second one creates a random graph out of four parameters and stores it in <Datafile>."
00184 << std::endl;
00185 }
00186 ParGraph_finalize();
00187 exit(0);
00188 }
00189
00190 if( rank() == 0 )
00191 {
00192 if( argc == 2 )
00193 {
00194 std::ifstream istr( argv[1] );
00195 read_graph( istr );
00196 std::cout<<"Graph eingelesen"<<std::endl;
00197 }
00198 else
00199 {
00200 VertexID_t v = atoi( argv[2] );
00201 EdgeID_t e = atoi( argv[3] );
00202 unsigned int c = atoi( argv[4] );
00203 unsigned int s = atoi( argv[5] );
00204 std::ofstream ostr( argv[6] );
00205 if( argv[1][0] == 'r' )
00206 random_graph( v, e, c, s, ostr );
00207 if( argv[1][0] == 'q' )
00208 rectangular_graph( v, e, c, s, ostr );
00209 std::cout<<"Graph zufällig erzeugt"<<std::endl;
00210 }
00211 }
00212 }