Шаг 122.
Потоки в сетях. Система дорог

    На этом шаге мы приведем программу вычисления потока в сети и дадим несколько определений, связанных с системой дорог.


    Пример [1, 2].
#include <iostream.h>
#define TRUE 1
#define FALSE 0
typedef int Boolean;
#define MaxNodes 8
#define MaxInt 1000  //Машинный эквивалент бесконечности.
class Spisok
{
  private:
    int cap[MaxNodes][MaxNodes];  //Функция пропускной способности.
    int flow[MaxNodes][MaxNodes]; //Максимальная функция потока.
    Boolean Any (Boolean *);
  public:
    void Vvod();
    void Maxflow (int, int, int *);
    void Vyvod (int);
};

void main()
{
  Spisok A;
  int s;  //Источник.
  int t;  //Сток.
  int totflow; //Значение потока от узла s к узлу t.

  //Задайте пропускную способность.
  A.Vvod();
  cout << "Укажите источник... "; cin >> s;
  cout << "Укажите сток... "; cin >> t;
  //Вывод результатов.
  A.Maxflow (s,t,&totflow);
  A.Vyvod(totflow);
}

void Spisok::Vvod()
{
  for (int i=0;i<MaxNodes;i++)
   for (int j=0;j<MaxNodes;j++)
   {
     cout << "Введите элемент " << i << " " << j<< " ";
     cin >> cap[i][j];
   }
}

void Spisok::Vyvod(int totflow)
{
  for (int i=0;i<MaxNodes;i++)
  {
    for (int j=0;i<MaxNodes;i++)
      cout << flow[i][j] << " ";
    cout << endl;
  }
  cout << "Значение потока: " << totflow << endl;
}

Boolean Spisok::Any (Boolean *Q)
{
  Boolean A = FALSE;

  for (int i=0;i<MaxNodes;i++) A = (A || Q[i]);
  return A;
}

void Spisok::Maxflow (int s, int t, int *totflow)
{
  int nd,i,x,pred;
  Boolean endpath[MaxNodes];
  Boolean onpath[MaxNodes];
  Boolean forward[MaxNodes];
  int     improve[MaxNodes];
  int     precede[MaxNodes];

  for (nd=0;nd<MaxNodes;nd++)
   for (i=0;i<MaxNodes;i++)
            flow[nd][i] = 0;
  *totflow = 0;
  do {
    //Попытка найти полупуть из s в t.
    for (nd=0;nd<MaxNodes;nd++)
    {
      endpath[nd] = FALSE;
      onpath [nd] = FALSE;
    }
    endpath[s] = TRUE;
    onpath [s] = TRUE;
    improve[s] = MaxInt;
    // Мы допускаем, что s обеспечивает неопределенный поток.
    while  (!onpath[t] && Any (&endpath[0])) 
    {
      // Попытка расширить существующий путь.
      nd = 0;
      while (!endpath[nd]) nd++;
      endpath[nd] = FALSE;
      for (i=0;i<MaxNodes;i++)
      {
        if (flow[nd][i]<cap[nd][i] && !onpath[i])
        {
           endpath[i]  = TRUE;
           onpath [i]  = TRUE;
           precede[i]  = nd;
           forward[nd] = TRUE;
           x = cap[nd][i] - flow[nd][i];
           if  ( improve[nd]<x ) improve[i] = improve[nd];
           else  improve[i] = x;
        }
        if (flow[i][nd]>0 && !onpath[i])
        {
           onpath [i]  = TRUE;
           endpath[i]  = TRUE;
           precede[i]  = nd;
           forward[nd] = FALSE;
           if ( improve[nd]<flow[i][nd] )
                 improve[i] = improve[nd];
           else  improve[i] = flow[i][nd];
        }
      }
    }
    if ( onpath[t] )
    // Поток на полупути к t может быть увеличен.
    {
       x = improve[t];
       *totflow += x;
       nd = t;
       while ( nd!=s )
       // Возвращение обратно вдоль пути.
       {
          pred = precede [nd];
          if ( forward[pred] )
          // Увеличение потока от pred.
                flow[pred][nd] += x;
          else // Уменьшение потока от pred.
                flow[pred][nd] -= x;
          nd = pred;
       }
    }            
  } while ( onpath[t] );
}
Текст этой программы можно взять здесь.

    Система дорог - это размеченный мультиграф (без петель), который отличается от графа тем, что в нем одна и та же пара (различных) вершин может быть связана более чем одним ребром [3, с.97-98]. При этом вершины соответствуют городам, а ребра - дорогам. Односторонним дорогам соответствуют дуги, а двусторонним дорогам - ребра.

    Каждая дорога имеет некоторую длину - положительное вещественное число. Понятие пути, достижимости и замкнутого пути определяются для системы дорог аналогично подобным понятиям для графа и ориентированного графа.

    Длина пути в системе дорог - это сумма длин дорог этого пути.

    Расстояние между двумя городами - это длина минимального пути между этими городами.

   


(1) Tenenbaum A., Augenstein M. Data Structures Using Pascal. Englewood Cliffs. - N.Y.: Prentice-Hall, Inc. 1981.
(2) Лэнгсам Й., Огенстейн М., Тененбаум А. Структуры данных для персональных ЭВМ: Пер. с англ. - М.: Мир, 1989. - 568 с.
(3) Касьянов В.H., Сабельфельд В.К. Сборник заданий по практикуму на ЭВМ. - М.: Hаука, 1986. - 272 с.

    На этом шаге мы намеревались закончить изложение материала, связанного со структурами данных. Однако определенная недосказанность последних шагов вынудила нас отыскать дополнительный материал по сетям. Мы не будем менять ранее опубликованные шаги, а в следующих шагах вернемся к ранее изложенному материалу и рассмотрим его более подробно.

    Таким образом, на следующем шаге мы подробно рассмотрим алгоритм Дейкстры.




Предыдущий шаг Содержание Следующий шаг