kestutis

PQ-3

Apr 10th, 2012
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.79 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>//strtol,srand,rand
  3. #include <time.h>//time
  4. #include <assert.h>//assert
  5. #include <limits.h>//INT_MAX
  6.  
  7. #include <vector>
  8.  
  9. #define MAX_VERTEX 41
  10. #define MAX_LINE 30
  11.  
  12.  
  13. std::vector< std::vector<int> > V(MAX_VERTEX);
  14. std::vector< std::vector<int> > BV(MAX_VERTEX);//Backup;
  15. int sum_of_vertices;
  16. const char dataFile[] = "kargerAdj.txt";//"./"hw3/test2b2.txt";//"./"hw3/n8m14_2.txt";//"./"hw3/adjList08m1.txt";//"kargerAdj.txt";
  17. //From https://github.com/franciscopassos/coursera-algo-class-2012-hw_unittests
  18. //[TEST_CASES][]
  19. const int Ctest_cases = 34;
  20. const char testCases[][MAX_LINE] = {"hw3/adjList01m1.txt|1",
  21. "hw3/adjList02m2.txt|2",
  22. "hw3/adjList03m1.txt|1",
  23. "hw3/adjList04m1.txt|1",
  24. "hw3/adjList05m2.txt|2",
  25. "hw3/adjList06m3.txt|3",
  26. "hw3/adjList07m1.txt|1",
  27. "hw3/adjList08m1.txt|1",
  28. "hw3/adjList09m1.txt|1",
  29. "hw3/adjList10m2.txt|2",
  30. "hw3/n3m3_2.txt|2",
  31. "hw3/n3m5_2.txt|2",
  32. "hw3/n4m5_2.txt|2",
  33. "hw3/n4m6_3.txt|3",
  34. "hw3/n5m5_2.txt|2",
  35. "hw3/n8m14_2.txt|2",
  36. "hw3/test0_m3.txt|3",
  37. "hw3/test0_m5.txt|5",
  38. "hw3/test1.2.txt|2",
  39. "hw3/test1bm3.txt|3",
  40. "hw3/test1_m5.txt|5",
  41. "hw3/test1_m6.txt|6",
  42. "hw3/test2.4.txt|4",
  43. "hw3/test2b2.txt|2",
  44. "hw3/test2_m5.txt|5",
  45. "hw3/test2_m7.txt|7",
  46. "hw3/test3.1.txt|1",
  47. "hw3/test3_m3.txt|3",
  48. "hw3/test4.3.txt|3",
  49. "hw3/test4_m5.txt|5",
  50. "hw3/test5_m4.txt|4",
  51. "hw3/test6_m4.txt|4",
  52. "hw3/test7_m4.txt|4",
  53. "hw3/test8_m3.txt|3",
  54. "hw3/test9_m4.txt|4"};
  55.  
  56. void print_graph_data() {
  57.     for (unsigned i=0; i<V.size() ; i++)
  58.         for (unsigned j=0; j<V[i].size() ; j++)
  59.             printf("Vertex: %d; Adjacent vertex: %d\n", i, V[i][j]);
  60.     puts("");
  61. }
  62.  
  63. void read_data(const char dataFile[]) {
  64.     sum_of_vertices = 0;//Set initial value to global variable
  65.     FILE * pFile = fopen(dataFile, "r");
  66.     if ( pFile == NULL ) perror("Error opening file");
  67.     else
  68.     {
  69.         //http://stackoverflow.com/questions/2287121/how-to-read-integers-from-a-file-line-by-line-in-c
  70.         //http://webstaff.itn.liu.se/~kenbj/tng033/www.cppreference.com/index.html
  71.         //http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html
  72.         //http://www.gnu.org/software/libc/manual/html_node/Creating-a-Pipe.html#Creating-a-Pipe
  73.         //http://stackoverflow.com/questions/2287121/how-to-read-integers-from-a-file-line-by-line-in-c
  74.         //http://tldp.org/LDP/lpg/node11.html
  75.         char line[1024], *p, *e = NULL;
  76.         int number;
  77.         while ( fgets(line, sizeof(line), pFile) ) {
  78.             int vertex = -1;
  79.  
  80.             //maybe TODO: create pipe and scan with fscanf
  81.             for (p = line;
  82.                 (number = strtol(p, &e, 10)) > -1 && p != e;/* scan and check do "e" moved to new place*/ // "> -1" is for nothing...
  83.                 p = e /*last place where we were*/) {
  84.                 if(vertex == -1) {
  85.                     vertex = number;
  86.                     ++sum_of_vertices;
  87.                 } else {
  88.                     //printf("%d %d\n", vertex, number);
  89.                     //assert(number );
  90.                     V[vertex].push_back(number);
  91.                     assert(vertex != number);//Because in my implementation of algorithm it is not checked before first iteration
  92.                 }
  93.                 //printf("%d ", number);
  94.             }
  95.             //puts("");
  96.         }
  97.         fclose (pFile);
  98.     }
  99.     //print_graph_data();//If needs to print graph
  100. }
  101.  
  102. int pick_vertex() {
  103.     int picked_vertex;// = -1;
  104.     do {
  105.         picked_vertex = rand() % V.size();
  106.     } while ( V[picked_vertex].empty() );
  107.     return picked_vertex;
  108. }
  109. int pick_vertex_neighbour(int vertex_id) {
  110.     int picked_vertex_neighbour;
  111.     do {
  112.         picked_vertex_neighbour = rand() % V[vertex_id].size();
  113.         //printf("b");
  114.     } while ( vertex_id == V[vertex_id][picked_vertex_neighbour] );
  115.     return V[vertex_id][picked_vertex_neighbour];
  116. }
  117.  
  118. int minimum_cut() {
  119.     std::vector<int>::iterator it;
  120.     while (sum_of_vertices > 2) {
  121.         //pick a remaining edge (u,v) uniformly at random
  122.         int vertex_id = pick_vertex();//u
  123.         assert( !V[vertex_id].empty() );
  124.         //printf("u%2d", vertex_id);
  125.         int vertex_neighbour_val = pick_vertex_neighbour(vertex_id);//v
  126.         //printf(" v%2d", vertex_neighbour_val);
  127.    
  128.  
  129.         //Line below don't change anything to results...
  130.         //if(1 == rand() % 2) swap(vertex_neighbour_val, vertex_id);
  131.  
  132.         //less vertices is result of merge process
  133.         --sum_of_vertices;
  134.  
  135.         //merge (or "contract") u and v into a single vertex
  136.         //merge to vertex_neighbour_val. Maybe would be better to merge into vertex_id?
  137.         while( !V[vertex_id].empty() ) {
  138.             //int last_element_val = V[vertex_id].back(); // Get value
  139.             //if( last_element_val != vertex_neighbour_val && last_element_val != vertex_id)
  140.             //  V[vertex_neighbour_val].push_back( last_element_val );
  141.             //printf(" %d", last_element_val);
  142.             V[vertex_neighbour_val].push_back( V[vertex_id].back() );
  143.             V[vertex_id].pop_back(); // Remove
  144.             //printf("d");
  145.         }
  146.         assert( V[vertex_id].empty() );
  147.  
  148.         //Change secondary vertex edges "indexes" to merged primary vertex index
  149.         //Could be even more straight forward (less cost) if I make not through all verteces, but through all vertex edges in above cycle
  150.         for (unsigned int i=0; i < V.size(); i++ )
  151.             for (unsigned int j=0; j < V[i].size(); j++ )
  152.                 if(V[i][j] == vertex_id)
  153.                     V[i][j] = vertex_neighbour_val;
  154.  
  155.         //remove self-loops
  156.         for ( it=V[vertex_neighbour_val].begin() ; it < V[vertex_neighbour_val].end();  )
  157.             if(*it == vertex_neighbour_val)
  158.                 //printf(" d%d", *it);
  159.                     it = V[vertex_neighbour_val].erase(it);
  160.             else it++;
  161.         //puts("");
  162.     }
  163.  
  164.     //return cut represented by final 2 vertices.
  165.     unsigned int min = INT_MAX;
  166.     for (unsigned i=0; i<V.size() ; i++)
  167.             if( !V[i].empty() ) {
  168.                 //return V[i].size();
  169.                 //printf("%d %d\n", i, V[i].size());
  170.                 if(V[i].size() < min)
  171.                     min = V[i].size();
  172.             }
  173.  
  174.     return (int)min;
  175. }
  176.  
  177. void test_cases(const char testcases[][MAX_LINE]) {
  178.     char data_file[1024];
  179.     int correct_answer;
  180.     for(int i=0; i<Ctest_cases; i++) {
  181.         sscanf(testCases[i], "%[^|]|%d", data_file, &correct_answer);
  182.         printf("File: %s", data_file);
  183.  
  184.         int min = INT_MAX;
  185.         read_data(data_file);
  186.         int Bsum_of_vertices = sum_of_vertices;
  187.         BV = V;
  188.         for(int i=0; i<10000; i++) {
  189.  
  190.             //Copy of backup input
  191.             V.clear();
  192.             V.resize(MAX_VERTEX);
  193.             V = BV;
  194.             sum_of_vertices = Bsum_of_vertices;
  195.        
  196.             int curr = minimum_cut();
  197.             if(curr < min)
  198.                 min = curr;
  199.         }
  200.         //assert(min == correct_answer);
  201.         if(min != correct_answer)
  202.             printf("\tcorrect: %d; current: %d;", correct_answer, min);
  203.         else
  204.             printf("\tOK");
  205.         puts("");
  206.     }
  207. }
  208.  
  209. int main() {
  210.     int min = INT_MAX;
  211.     read_data(dataFile);
  212.     int Bsum_of_vertices = sum_of_vertices;
  213.     BV = V;
  214.     int correct_count=0;//Correct answer counter
  215.     srand ( time(NULL) );
  216.     for(int i=0; i<10000; i++) {
  217.  
  218.         //Copy backup of input
  219.         V.clear();
  220.         V.resize(MAX_VERTEX);
  221.         V = BV;
  222.         sum_of_vertices = Bsum_of_vertices;
  223.        
  224.         int curr = minimum_cut();
  225.         if(curr < min)
  226.             min = curr;
  227.         if(curr == 3) ++correct_count;
  228.     }
  229.     printf("PQ-3 min: %d.\n",  min);
  230.     printf("Correct times: %d.\n",  correct_count);
  231.  
  232.     test_cases(testCases);
  233.  
  234.     return 0;
  235. }
Advertisement
Add Comment
Please, Sign In to add comment