Advertisement
Guest User

Untitled

a guest
Jun 24th, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 KB | None | 0 0
  1.  
  2. /*  
  3.  *  Алгоритм Форда - Фалкерсона для поиска максимального потока в транспортной сети.
  4.  *  
  5.  *  Транспортная сеть задается числом узлов N (2 <= N <= MAX_N) и набором ребер
  6.  *  с указанием пропускной способности каждого существующего ребра C (0 <= C <= MAXC).
  7.  *  Если пропускная способность ребра равна 0, то ребра нет.
  8.  *
  9.  *  Поток ищется между источником S (вершина с номером 0), и стоком T (вершина с номером N-1).
  10.  *
  11.  *  Идея алгоритма заключается в итеративном увеличении потока с 0 до максимально возможного. На каждой итерации ищется путь,
  12.  *  по которому можно пустить дополнительный поток из источника в сток.
  13.  *  Алгоритм работает за время O(E * f), где E - число ребер, f - максимальный поток в сети.
  14.  */
  15.  
  16. #define MAX_N 3     // maximum vertex count
  17. #define MAX_M 3     // maximum number of edges
  18. #define MAXC 3      // maximum edge constraint
  19.  
  20. // algorithm states:
  21. #define UNKNOWN                 0
  22. #define SEARCHING_PATH          1
  23. #define SEARCHING_FINISHED      2
  24. #define CALCULATING_INC_VALUE   3
  25. #define CALCULATING_FINISHED    4
  26. #define INCREASING_FLOW         5
  27. #define INCREASING_FINISHED     6
  28. #define ALGORITHM_FINISHED      7
  29.  
  30.  
  31. typedef array {
  32.     int a[MAX_N];
  33. }
  34.  
  35.  
  36. byte state;     // current state
  37.  
  38. int n;          // states' count
  39.  
  40. array c[MAX_N]; // edge constrains
  41. array f[MAX_N]; // edge flow
  42.  
  43. bool foundPath;
  44. int incFlowValue;
  45. int maxFlow;
  46.  
  47. int pi;                 // path index
  48. int path[MAX_N];        // for path saving
  49. bool visited[MAX_N];    // is vertex x visited?
  50.  
  51.  
  52. /* ------------------------------- auxiliary "functions" -------------------------------- */
  53.  
  54. int minValue;
  55.  
  56. inline min(a, b) {
  57.     if
  58.     :: (a < b)  ->
  59.         minValue = a;
  60.     :: else     ->
  61.         minValue = b;
  62.     fi;
  63. }
  64.  
  65. int randomValue;
  66.  
  67. // generate random in range [minV, maxV]
  68. inline genRandom(minV, maxV) {
  69.     randomValue = minV;
  70.     do
  71.     :: (randomValue == maxV)        ->
  72.         break;  // increased up to max value -> stop
  73.     :: else                     ->
  74.         if
  75.         :: randomValue++;   // randomly increment
  76.         :: break;           // or stop
  77.         fi;
  78.     od;
  79. }
  80.  
  81.  
  82. /* ------------------------------- algorithm "functions" -------------------------------- */
  83.  
  84. int i, j;   // temp variables
  85.  
  86.  
  87. inline findPathImpl() {
  88.     // clearing
  89.     for (i : 0..(n-1)) {
  90.         visited[i] = false;
  91.     }
  92.  
  93.     foundPath = false; 
  94.     pi = 0;
  95.     path[pi] = 0;   // starting from source
  96.     bool findNext;
  97.    
  98.     // searching...
  99.     do
  100.     :: ((!foundPath) && (pi >= 0))  ->
  101.         if
  102.         :: (!visited[path[pi]])     ->  // going forward
  103.             visited[path[pi]] = true;
  104.             if
  105.             :: (path[pi] == n - 1)  ->  foundPath = true;
  106.             :: else                 ->  path[pi+1] = 0; // new search
  107.             fi;
  108.         :: else                     ->  // continuing search
  109.             path[pi+1]++;
  110.         fi;
  111.    
  112.         if
  113.         :: (!foundPath)     -> 
  114.             pi++;
  115.             findNext = false;
  116.             do
  117.             :: ((path[pi] < n) && (!findNext))  ->
  118.                 i = path[pi - 1];
  119.                 j = path[pi];
  120.                 if
  121.                 :: ((c[i].a[j] - f[i].a[i] > 0) && (!visited[j]))   ->
  122.                     findNext = true;
  123.                 :: else     ->
  124.                     path[pi]++;
  125.                 fi;
  126.             :: else             ->  break;
  127.             od;
  128.             if
  129.             :: (!findNext)  ->  pi = pi - 2;
  130.             :: else         ->  skip;
  131.             fi;
  132.         :: else     ->  skip;
  133.         fi;
  134.     :: else     -> break;
  135.     od;
  136. }
  137.  
  138.  
  139. inline findPath() {
  140.     state = SEARCHING_PATH;
  141.     findPathImpl();
  142.     state = SEARCHING_FINISHED;
  143. }
  144.  
  145.  
  146. int pi2;
  147.  
  148. inline calculateIncreaseValue() {
  149.     state = CALCULATING_INC_VALUE;
  150.    
  151.     incFlowValue = 2 * MAXC;
  152.     pi2 = 0;
  153.     do
  154.     :: (pi2 < pi)   ->
  155.         i = path[pi2];
  156.         j = path[pi2 + 1];
  157.        
  158.         min(incFlowValue, c[i].a[j] - f[i].a[j]);
  159.         incFlowValue = minValue;
  160.        
  161.         pi2++;
  162.     :: else         ->  break;
  163.     od;
  164.        
  165.     state = CALCULATING_FINISHED;
  166. }
  167.  
  168. inline increaseFlow() {
  169.     state = INCREASING_FLOW;
  170.  
  171.     pi2 = 0;
  172.     do
  173.     :: (pi2 < pi)   ->
  174.         i = path[pi2];
  175.         j = path[pi2 + 1];
  176.  
  177.         f[i].a[j] = f[i].a[j] + incFlowValue;
  178.         f[j].a[i] = f[j].a[i] - incFlowValue;
  179.  
  180.         pi2++;
  181.     :: else         ->  break;
  182.     od;
  183.     maxFlow = maxFlow + incFlowValue;
  184.  
  185.     state = INCREASING_FINISHED;
  186. }  
  187.  
  188.  
  189. inline findMaxFlow() {
  190.     maxFlow = 0;
  191.  
  192.     findPath();
  193.     do
  194.     :: (foundPath)  ->
  195.         calculateIncreaseValue();
  196.         if
  197.         :: (incFlowValue > 0) -> increaseFlow();
  198.         :: skip;
  199.         fi;
  200.        
  201.         findPath();
  202.     :: else         ->  break;
  203.     od;
  204.    
  205.     state = ALGORITHM_FINISHED;
  206. }
  207.  
  208.  
  209. init {
  210.     printf("INIT: Starting\n\n");
  211.    
  212.     printf("Generating input:\n");
  213.  
  214.     genRandom(2, MAX_N);
  215.     n = randomValue;
  216.     genRandom(0, MAX_M);
  217.     int m = randomValue;
  218.     printf("Vertex count = %d\n", n);
  219.     printf("Edges (count = %d):\n", m);
  220.     int en, cc;
  221.     for (en : 0..(m-1)) {
  222.         genRandom(0, n - 1);
  223.         i = randomValue;
  224.         genRandom(0, n - 1);
  225.         j = randomValue;
  226.         genRandom(1, MAXC);
  227.         cc = randomValue;
  228.         printf("%d -> %d, c = %d\n", i, j, cc);
  229.         c[i].a[j] = cc;
  230.     }
  231.     printf("\n");
  232.    
  233.     printf("Starting algorithm...\n");
  234.     findMaxFlow();
  235.     printf("Finished. Max flow = %d\n\n", maxFlow);
  236.    
  237.     findPathImpl();
  238.    
  239.     printf("INIT: Finished\n");
  240. }
  241.  
  242.  
  243. ltl notZeroIncrease {[]((state == INCREASING_FLOW) -> (incFlowValue > 0))}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement