Bob103

C#_Eilerov

May 21st, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.87 KB | None | 0 0
  1. public class Graph
  2.     {
  3.  
  4.         public class Queue
  5.         {
  6.             private class Node //вложенный класс, реализующий базовый элемент очереди
  7.             {
  8.                 private object inf;
  9.                 private Node next;
  10.                 public Node(object nodeInfo)
  11.                 {
  12.                     inf = nodeInfo;
  13.                     next = null;
  14.                 }
  15.                 public Node Next
  16.                 {
  17.                     get { return next; }
  18.                     set { next = value; }
  19.                 }
  20.                 public object Inf
  21.                 {
  22.                     get { return inf; }
  23.                     set { inf = value; }
  24.                 }
  25.             } //конец класса Node
  26.             private Node head;
  27.             private Node tail;
  28.             public Queue()
  29.             {
  30.                 head = null;
  31.                 tail = null;
  32.             }
  33.             public void Add(object nodeInfo)
  34.             {
  35.                 Node r = new Node(nodeInfo);
  36.                 if (head == null)
  37.                 {
  38.                     head = r;
  39.                     tail = r;
  40.                 }
  41.                 else
  42.                 {
  43.                     tail.Next = r;
  44.                     tail = r;
  45.                 }
  46.             }
  47.             public object Take()
  48.             {
  49.                 if (head == null)
  50.                 {
  51.                     throw new Exception("Очередь пуста.");
  52.                 }
  53.                 else
  54.                 {
  55.                     Node r = head;
  56.                     head = head.Next;
  57.  
  58.                     if (head == null)
  59.                     {
  60.                         tail = null;
  61.                     }
  62.                     return r.Inf;
  63.                 }
  64.             }
  65.             public bool IsEmpty
  66.             {
  67.                 get
  68.                 {
  69.                     if (head == null)
  70.                     {
  71.                         return true;
  72.                     }
  73.                     else
  74.                     {
  75.                         return false;
  76.                     }
  77.                 }
  78.             }
  79.         }
  80.  
  81.  
  82.  
  83.  
  84.         private class Node //вложенный класс для скрытия данных и алгоритмов
  85.         {
  86.             private int[,] array; //матрица смежности
  87.             public int this[int i, int j] //индексатор для обращения к матрице смежности
  88.             {
  89.                 get
  90.                 {
  91.                     return array[i, j];
  92.                 }
  93.                 set
  94.                 {
  95.                     array[i, j] = value;
  96.                 }
  97.             }
  98.             public int Size //свойство для получения размерности матрицы смежности
  99.             {
  100.                 get
  101.                 {
  102.                     return array.GetLength(0);
  103.                 }
  104.             }
  105.             private bool[] nov; //вспомогательный массив: если i-ый элемент массива равен
  106.                                 //true, то i-ая вершина еще не просмотрена; если i-ый
  107.                                 //элемент равен false, то i-ая вершина просмотрена
  108.             public void NovSet() //метод помечает все вершины графа как непросмотреные
  109.             {
  110.                 for (int i = 0; i < Size; i++)
  111.                 {
  112.                     nov[i] = true;
  113.                 }
  114.             }
  115.             public bool NovGet(int i) //метод помечает все вершины графа как непросмотреные
  116.             {
  117.  
  118.                 return nov[i];
  119.  
  120.             }
  121.             //конструктор вложенного класса, инициализирует матрицу смежности и
  122.             // вспомогательный массив
  123.             public Node(int[,] a)
  124.             {
  125.                 array = a;
  126.                 nov = new bool[a.GetLength(0)];
  127.             }
  128.             //реализация алгоритма обхода графа в глубину
  129.  
  130.             public void Dfs(int v)
  131.             {
  132.                 Console.Write("{0} ", v); //просматриваем текущую вершину
  133.                 nov[v] = false; //помечаем ее как просмотренную
  134.                                 // в матрице смежности просматриваем строку с номером v
  135.                 for (int u = 0; u < Size; u++)
  136.                 {
  137.                     //если вершины v и u смежные, к тому же вершина u не просмотрена,
  138.                     if (array[v, u] != 0 && nov[u])
  139.                     {
  140.                         Dfs(u); // то рекурсивно просматриваем вершину
  141.                     }
  142.                 }
  143.             }
  144.             //реализация алгоритма Флойда
  145.             public long[,] Floyd(out int[,] p)
  146.             {
  147.                 int i, j, k;
  148.                 //создаем массивы р и а
  149.                 long[,] a = new long[Size, Size];
  150.                 p = new int[Size, Size];
  151.                 for (i = 0; i < Size; i++)
  152.                 {
  153.                     for (j = 0; j < Size; j++)
  154.                     {
  155.                         if (i == j)
  156.                         {
  157.                             a[i, j] = 0;
  158.                         }
  159.                         else
  160.                         {
  161.                             if (array[i, j] == 0)
  162.                             {
  163.                                 a[i, j] = int.MaxValue;
  164.                             }
  165.                             else
  166.                             {
  167.                                 a[i, j] = array[i, j];
  168.                             }
  169.                         }
  170.                         p[i, j] = -1;
  171.                     }
  172.                 }
  173.                 //осуществляем поиск кратчайших путей
  174.                 for (k = 0; k < Size; k++)
  175.                 {
  176.                     for (i = 0; i < Size; i++)
  177.                     {
  178.                         for (j = 0; j < Size; j++)
  179.                         {
  180.                             long distance = a[i, k] + a[k, j];
  181.                             if (a[i, j] > distance)
  182.                             {
  183.                                 a[i, j] = distance;
  184.                                 p[i, j] = k;
  185.                             }
  186.                         }
  187.                     }
  188.                 }
  189.                 return a;//в качестве результата возвращаем массив кратчайших путей между
  190.             } //всеми парами вершин
  191.               //восстановление пути от вершины a до вершины в для алгоритма Флойда
  192.             public void WayFloyd(int a, int b, int[,] p, ref Queue items)
  193.             {
  194.                 int k = p[a, b];
  195.                 //если k<> -1, то путь состоит более чем из двух вершин а и b, и проходит через
  196.                 //вершину k, поэтому
  197.                 if (k != -1)
  198.                 {
  199.                     // рекурсивно восстанавливаем путь между вершинами а и k
  200.                     WayFloyd(a, k, p, ref items);
  201.                     items.Add(k); //помещаем вершину к в очередь
  202.                                   // рекурсивно восстанавливаем путь между вершинами k и b
  203.                     WayFloyd(k, b, p, ref items);
  204.                 }
  205.             }
  206.             public void Reach(int v)
  207.             {
  208.                 nov[v] = false;
  209.                 for (int u = 0; u < Size; u++)
  210.                 {
  211.                     if
  212.                     (array[v, u] != 0 && nov[u])
  213.                     {
  214.                         Reach(u);
  215.                     }
  216.                 }
  217.             }
  218.  
  219.             public void SearchG(int v, ref int[,] a, ref Stack c) //во вложенном классе
  220.             {
  221.                 for (int i = 0; i < a.GetLength(0); i++)
  222.                 {
  223.                     if (a[v, i] != 0)
  224.                     {
  225.                         a[v, i] = 0; a[i, v] = 0;
  226.                         SearchG(i, ref a, ref c);
  227.                     }
  228.                 }
  229.                 c.Push(v);
  230.             }
  231.  
  232.  
  233.         } //конец вложенного клаcса
  234.  
  235.  
  236.  
  237.         private Node graph; //закрытое поле, реализующее АТД «граф»
  238.         public Graph(string name) //конструктор внешнего класса
  239.         {
  240.             using (StreamReader file = new StreamReader(name))
  241.             {
  242.                 int n = int.Parse(file.ReadLine());
  243.                 int[,] a = new int[n, n];
  244.                 for (int i = 0; i < n; i++)
  245.                 {
  246.                     string line = file.ReadLine();
  247.                     string[] mas = line.Split(' ');
  248.                     for (int j = 0; j < n; j++)
  249.                     {
  250.                         a[i, j] = int.Parse(mas[j]);
  251.                     }
  252.                 }
  253.                 graph = new Node(a);
  254.             }
  255.         }
  256.  
  257.         //метод выводит матрицу смежности на консольное окно
  258.         public void Show()
  259.         {
  260.             for (int i = 0; i < graph.Size; i++)
  261.             {
  262.                 for (int j = 0; j < graph.Size; j++)
  263.                 {
  264.                     Console.Write("{0,4}", graph[i, j]);
  265.                 }
  266.                 Console.WriteLine();
  267.             }
  268.         }
  269.         public void Dfs(int v)
  270.         {
  271.             graph.NovSet();//помечаем все вершины графа как непросмотренные
  272.             graph.Dfs(v); //запускаем алгоритм обхода графа в глубину
  273.             Console.WriteLine();
  274.         }
  275.         public void Floyd()
  276.         {
  277.             int[,] p;
  278.             long[,] a = graph.Floyd(out p); //запускаем алгоритм Флойда
  279.             int i, j;
  280.             //анализируем полученные данные и выводим их на экран
  281.             for (i = 0; i < graph.Size; i++)
  282.             {
  283.                 for (j = 0; j < graph.Size; j++)
  284.                 {
  285.                     if (i != j)
  286.                     {
  287.                         if (a[i, j] == int.MaxValue)
  288.                         {
  289.                             Console.WriteLine("Пути из вершины {0} в вершину {1} не существует", i, j);
  290.                         }
  291.                         else
  292.                         {
  293.                             Console.Write("Кратчайший путь от вершины {0} до вершины {1} равен {2}, ", i, j, a[i, j]);
  294.  
  295.                             Console.Write(" путь ");
  296.                             Queue items = new Queue();
  297.                             items.Add(i);
  298.                             graph.WayFloyd(i, j, p, ref items);
  299.                             items.Add(j);
  300.                             while (!items.IsEmpty)
  301.                             {
  302.                                 Console.Write("{0} ", items.Take());
  303.                             }
  304.                             Console.WriteLine();
  305.                         }
  306.                     }
  307.                 }
  308.             }
  309.         }
  310.         public void Reachable(int v)
  311.         {
  312.             graph.NovSet();
  313.             Console.Write("Вершины достижимые из {0} вершины: ", v);
  314.             graph.Reach(v);
  315.             for (int i = 0; i < graph.Size; i++)
  316.             {
  317.                 if (!graph.NovGet(i) && i != v) //если вершина была просмотрена, то она достижима
  318.                 {
  319.                     Console.Write("{0} ", i);
  320.                 }
  321.             }
  322.             Console.WriteLine();
  323.         }
  324.  
  325.         public void SearchG() //во внешнем классе
  326.         {
  327.             int[,] a = new int[graph.Size, graph.Size];
  328.             for (int i = 0; i < graph.Size; i++)
  329.             {
  330.                 for (int j = 0; j < graph.Size; j++)
  331.                 {
  332.                     a[i, j] = graph[i, j];
  333.                 }
  334.             }
  335.             Stack c = new Stack();
  336.             graph.SearchG(0, ref a, ref c);
  337.             while (c.Count != 0)
  338.             {
  339.                 Console.Write("{0} ", (int)c.Pop() + 1);
  340.             }
  341.         }
  342.  
  343.     }
Advertisement
Add Comment
Please, Sign In to add comment