Advertisement
Guest User

Untitled

a guest
Jun 25th, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.18 KB | None | 0 0
  1. /*
  2.  *  main.cpp
  3.  *  SemestralniProjekt PAR
  4.  *
  5.  *  Created by Martin Mates and Frantisek Szabo on 20.10.10.
  6.  *
  7.  */
  8.  
  9. #include <iostream>
  10. #include <stdio.h>
  11. #include <string.h>
  12.  
  13. #define _DEBUG_ true
  14. #define MAX_FILE_LINE 200 // Maximalni delka radky vstupniho souboru
  15. #define MAX_NODES 100 // Maximalni pocet uzlu grafu
  16. #define STACK_SIZE 100 // Delka zasobniku
  17.  
  18. int loadGraph(FILE *fr, int **graph, int *numberOfNodes);
  19. int rateGraph(FILE *fr, char *path);
  20. void push(char **stack, char *value, int *index);
  21. char* pop(char **stack, int *stack_index);
  22. char* lookAtTop(char **stack, int stack_index);
  23. int expand(char **stack, int *stack_index, int numberOfNodes);
  24. int edgeCut(char *verticies, int numberOfNodes, int **graph);
  25. void printStack(char **stack, int *stack);
  26.  
  27.  
  28. int main (int argc, char **argv) {
  29.     FILE *fr; // Soubor s grafem pro cteni
  30.     int numberOfNodes; // Pocet uzlu grafu
  31.     int minCut = 1000000; // Minimalni rez
  32.     char* resultSets; // Vysledna mnozina bodu
  33.    
  34.     int **graph = new int* [MAX_NODES]; // Matice s grafem
  35.     for (int i = 0; i < MAX_NODES; i++) {
  36.         graph[i] = new int[MAX_NODES];
  37.     }
  38.    
  39.     if (_DEBUG_ == false) {
  40.         // Zpracovani vstupnich parametru -----------------------------
  41.         if (argc > 1) {            
  42.             if ((fr = fopen(argv[1], "r")) == NULL) { // Otevreni souboru s grafem
  43.                 printf("Soubor %s se nepodarilo otevrit.\n", argv[1]);
  44.                 return 0;
  45.             }
  46.             if (argc > 2) {
  47.                 if (strcmp(argv[2], "-c") == 0) {
  48.                     rateGraph(fr, argv[1]);
  49.                     fclose(fr);
  50.                     return(0);
  51.                 } else {
  52.                     printf("Druhy parametr je chybny. \n");
  53.                     fclose(fr);
  54.                     return 0;
  55.                 }          
  56.             }      
  57.         } else {
  58.             printf("Nebyly zadany zadne parametry. \n");
  59.             printf("Help: \n");
  60.             printf("   Prvni parametr: [filename] Cesta k .txt souboru s grafem [povinny] \n");
  61.             printf("   Druhy parametr: [-c] Ohodnoti neohodnoceny graf a ulozi ho do souboru [volitelny] \n");
  62.             return 0;
  63.         }
  64.         // -----------------------------------------------------------
  65.     } else {
  66.         fr = fopen("/Volumes/Macintosh HDD 2/graf50_40_rated.txt", "r");
  67.     }
  68.  
  69.    
  70.     loadGraph(fr, graph, &numberOfNodes); // Nacteni grafu ze souboru
  71.    
  72.     // Print graph
  73.     for (int i = 0; i < numberOfNodes; i++) {
  74.         for (int j = 0; j < numberOfNodes; j++) {
  75.             printf("%i ", graph[i][j]);
  76.         }
  77.         printf("\n");
  78.     }
  79.    
  80.     // Deklarace zasobniku
  81.     char **stack = new char* [STACK_SIZE];
  82.     for (int i = 0; i < STACK_SIZE; i++) {
  83.         stack[i] = new char[numberOfNodes + 1];
  84.     }
  85.     int stack_index = 0;
  86.    
  87.     // Alokovani resultSetu
  88.     resultSets = (char *) malloc(numberOfNodes + 1);
  89.    
  90.    
  91.     char *initString;
  92.     initString  = (char *) malloc(numberOfNodes + 1);
  93.     for (int i = 0; i < numberOfNodes; i++) {
  94.         initString[i] = 'x';
  95.     }
  96.     initString[numberOfNodes] = '\0';
  97.    
  98.     push(stack, initString, &stack_index);
  99.     printStack(stack, &stack_index);
  100.     while (stack_index > 0) {
  101.        
  102.         if (_DEBUG_) {
  103.             printf("MinCut = %d \n", minCut);
  104.             printf("Stack index: %d\n", stack_index);
  105.         }
  106.        
  107.         // Vypocita se edgeCut z posledni hodnoty zasobiku
  108.         int localEdgeCut = edgeCut(lookAtTop(stack, stack_index - 1), numberOfNodes, graph);
  109.        
  110.         // Pokud je edgeCut 0, expandujeme. Nejspis jsou sama x nebo jsou vsechny body v 1 mnozine
  111.         if (localEdgeCut == 0) {
  112.             // Expandujeme
  113.             expand(stack, &stack_index, numberOfNodes);
  114.         } else {
  115.             // Pokud je edgeCut mensi nez globalni minCut pokracujeme. Jinak zahazujeme
  116.             if (localEdgeCut < minCut) {
  117.                 // Expandujeme
  118.                 if (expand(stack, &stack_index, numberOfNodes) == 0) {
  119.                     // Pokud uz nejde expandovat jsme ve spodni vetvy a mame novy min rez
  120.                     minCut = localEdgeCut;
  121.                     strcpy(resultSets, lookAtTop(stack, stack_index));
  122.                 }
  123.             } else {
  124.                 if (_DEBUG_) {
  125.                     printf("ZAHAZUJI: %s\n", lookAtTop(stack, stack_index - 1));
  126.                 }
  127.                 // Zahazujeme neperspektivni vetev
  128.                 pop(stack, &stack_index);
  129.             }
  130.         }
  131.        
  132.         printStack(stack, &stack_index);
  133.        
  134.         printf("----------------------------------------------------------\n");
  135.     }
  136.    
  137.  
  138.    
  139.     fclose(fr);
  140.    
  141.     printf("MINIMAL CUT IS: %d\n", minCut);
  142.     printf("RESULT SESTS: %s\n", resultSets);
  143. }
  144.  
  145.  
  146. void printStack(char **stack, int *stack_index) {
  147.     for (int i = 0; i < *stack_index; i++) {
  148.         printf("[%s],", stack[i]);
  149.     }
  150.     printf("\n");
  151. }
  152.  
  153. void push(char **stack, char *str, int *stack_index) {
  154.     strcpy(stack[*stack_index], str);
  155.     *stack_index = *stack_index + 1;
  156.     if (*stack_index > STACK_SIZE) {
  157.         printf("[error] Stack overflow.\n");
  158.     }
  159. }
  160.  
  161. char* pop(char **stack, int *stack_index) {
  162.     *stack_index = *stack_index - 1;
  163.     if (*stack_index > -1) {
  164.         return stack[*stack_index];
  165.     } else {
  166.         return 0;
  167.     }
  168. }
  169.  
  170. char* lookAtTop(char **stack, int stack_index) {
  171.     if (stack_index > -1) {
  172.         return stack[stack_index];
  173.     } else {
  174.         return 0;
  175.     }
  176. }
  177.  
  178. int expand(char **stack, int *stack_index, int numberOfNodes) {
  179.    
  180.     char *str;
  181.     str  = (char *) malloc(numberOfNodes + 1);
  182.    
  183.     int indexToExpand = -1;
  184.     strcpy(str, pop(stack, stack_index));
  185.    
  186.    
  187.     for (int i = 0; i < numberOfNodes; i++) {
  188.         if (str[i] == 'x') {
  189.             indexToExpand = i;
  190.             break;
  191.         }
  192.     }
  193.    
  194.     if (indexToExpand == -1) { // Uz nejde expandovat
  195.         return 0;
  196.     }
  197.    
  198.     if (_DEBUG_) {
  199.         //printf("index to expand: %d \n", indexToExpand);
  200.         printf("item to expand: %s \n", str);
  201.         //printf("strlen: %d \n", strlen(str));
  202.         //printf("str[1] = %c\n", str[1]);
  203.     }
  204.    
  205.     str[indexToExpand] = '0';
  206.     push(stack, str, stack_index);
  207.     str[indexToExpand] = '1';
  208.     push(stack, str, stack_index);
  209.  
  210.    
  211.     return 1;
  212. }
  213.  
  214. /*
  215.  * Vypocita hranovy rez grafu podle zadaneho stringu
  216.  */
  217. int edgeCut(char *verticies, int numberOfNodes, int **graph) { 
  218.     // Mnoziny bodu a jejich vynulovani
  219.     int setA[numberOfNodes];
  220.     int setB[numberOfNodes];   
  221.     for (int i = 0; i < numberOfNodes; i++) {
  222.         setA[i] = setB[i] = 0;
  223.     }
  224.    
  225.     // Rozdeleni stringu do mnozin A a B
  226.     for (int i = 0; i < numberOfNodes; i++) {
  227.         if (verticies[i] != 'x') {
  228.             if (verticies[i] == '0') {
  229.                 setA[i] = 1;
  230.             } else {
  231.                 setB[i] = 1;
  232.             }
  233.         }
  234.     }
  235.    
  236.     unsigned int result = 0;
  237.     for (int i = 0; i < numberOfNodes; i++) { // projedeme vsechny radky
  238.         if (setA[i] == 1) { // resime jen spravne radky
  239.             for (int j = 0; j < numberOfNodes; j++) {
  240.                 if (setB[j] == 1) result += graph[i][j]; // vynechavame sloupce
  241.             }
  242.         }
  243.     }
  244.    
  245.    
  246.     if (_DEBUG_) {
  247.         printf("Counting edgeCut from %s:\n", verticies);
  248.         printf("setA:");
  249.         for (int i = 0; i < numberOfNodes; i++) {
  250.             printf("%d,", setA[i]);
  251.         }
  252.         printf("\nsetB:");
  253.         for (int i = 0; i < numberOfNodes; i++) {
  254.             printf("%d,", setB[i]);
  255.         }
  256.         printf("\n");
  257.         printf("EDGE CUT = %i\n", result);
  258.     }
  259.    
  260.    
  261.     return result;
  262. }
  263.  
  264. /*
  265.  * Ohodnoti graf ze souboru s matici incidence
  266.  * a vytvori soubor s takto ohodnocenym grafem
  267.  */
  268. int rateGraph(FILE *fr, char *path) {
  269.     char str[MAX_FILE_LINE]; // Prectena radka
  270.     int lineNumber = 0; // Cislo aktualne ctene radky
  271.     int lineLenght; // Pocet znaku na aktualne ctene radce
  272.     int j; // Pomocna promenna, index radku
  273.     int graph[MAX_NODES][MAX_NODES];
  274.     int numberOfNodes; // Pocet uzlu grafu precteny z prvni radky souboru
  275.     FILE *fw; // Vystupni soubor a grafem
  276.    
  277.     srand (time(NULL)); // Seed random function
  278.    
  279.     j = 0; // Index radku pole pro graf
  280.     while (fgets(str, MAX_FILE_LINE, fr) != NULL) {
  281.         lineLenght = strlen(str);
  282.        
  283.         if (lineLenght == (MAX_FILE_LINE - 1) && str[lineLenght - 1] != '\n') {
  284.             printf("Radka vstupniho souboru je prilis dlouha.");
  285.             return 0;
  286.         }
  287.        
  288.         if (str[lineLenght - 1] == '\n') {
  289.             str[lineLenght - 1] = '\0'; // odstraneni konce radky a nahrazeni koncem retezce
  290.         }
  291.        
  292.         if (lineNumber != 0) {
  293.             for (int i = 0; i < lineLenght-1; i++) {
  294.                
  295.                 if (j <= i) { // jen pro horni trojuhelnikovou matici a diagonalu
  296.                     graph[j][i] = str[i] - 48;
  297.                     if (graph[j][i] == 1) {
  298.                         graph[j][i] = rand() % 255 + 1;
  299.                     }
  300.                     graph[i][j] = graph[j][i];
  301.                 }
  302.                
  303.             }
  304.             j++; // Dalsi radek zvetsime index
  305.  
  306.         } else { // Prvni radka souboru, nacte se pocet uzlu
  307.             numberOfNodes = atoi(str);
  308.         }
  309.  
  310.         lineNumber++;
  311.     }
  312.    
  313.     // Cesta k vystupnimu souboru stejna jako ke vstupnimu, jen se prida _rated do nazvu
  314.     char *ext;
  315.     ext = strstr(path, ".txt");
  316.     strncpy(ext, "_rated.txt", 11);
  317.    
  318.     if ((fw = fopen(path , "w")) == NULL) {
  319.         printf("Vystupni soubor %s s grafem se nepodarilo vytvorit.", path);
  320.         return 0;
  321.     }
  322.    
  323.     // Zapis do souboru
  324.     fprintf(fw, "%i\n", numberOfNodes);
  325.     for (int i = 0; i < numberOfNodes; i++) {
  326.         for (int j = 0; j < numberOfNodes; j++) {
  327.             fprintf(fw, "%i,", graph[i][j]);
  328.         }
  329.         fprintf(fw, "\n");
  330.     }
  331.     printf("Byl vytvoren soubor %s s ohodnocenym grafem.\n", path);
  332.    
  333.     fclose(fw);
  334.    
  335.     return 1;
  336. }
  337.  
  338. /*
  339.  * Precte graf se souboru a naplni pole graph.
  340.  * Zjisti take pocet uzlu grafu.
  341.  */
  342. int loadGraph(FILE *fr, int **graph, int *numberOfNodes) {
  343.     char str[MAX_FILE_LINE];
  344.     int lineNumber = 0; // Cislo aktualne ctene radky
  345.     int lineLenght; // Pocet znaku na aktualne ctene radce
  346.     int gi = -1, gj = 0; // Pomocne indexy grafu, -1 protoze prvni radek souboru je pocet uzlu
  347.  
  348.    
  349.     while (fgets(str, MAX_FILE_LINE, fr) != NULL) {
  350.         lineLenght = strlen(str);
  351.        
  352.         if (lineLenght == (MAX_FILE_LINE - 1) && str[lineLenght - 1] != '\n') {
  353.             printf("Radka vstupniho souboru je prilis dlouha.");
  354.             return 0;
  355.         }
  356.        
  357.         if (str[lineLenght - 1] == '\n') {
  358.             str[lineLenght - 1] = '\0'; // odstraneni konce radky a nahrazeni koncem retezce
  359.         }
  360.        
  361.         if (lineNumber == 0) { // Pri cteni prvniho radku se nacte pocet uzlu
  362.             *numberOfNodes = atoi(str);
  363.         } else {
  364.             // Cteni radku po znacich, dokud je znak cislo, prirazuj znaky do number, az se narazi na carku cislo se ulozi do pole graph
  365.             char number[4];
  366.             int ni = 0;
  367.             for (int i = 0; i < lineLenght - 1; i++) {
  368.                 if (str[i] != ',') {
  369.                     number[ni] = str[i];
  370.                     ni++;
  371.                 } else {
  372.                     //printf("%i ", atoi(number));
  373.                     //printf("ukladam %i do [%i,%i]\n", atoi(number), gi,gj);
  374.                     graph[gi][gj] = atoi(number);
  375.                     gj++; // Skoncilo cislo, index sloupce grafu zvysit
  376.                     ni = 0;
  377.                     for (int i = 0; i < 4; i++) {
  378.                         number[i] = 0;
  379.                     }
  380.                 }
  381.             }
  382.            
  383.             //printf("\n");
  384.         }
  385.         gj = 0;
  386.         gi++;
  387.         lineNumber++;
  388.     }
  389.      
  390.    
  391.     return 0;
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement