Bob103

C#_HAmilton_&_20

Jun 1st, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 26.41 KB | None | 0 0
  1. class Program
  2.     {
  3.         public class Stack
  4.         {
  5.             private class Node //вложенный класс, реализующий элемент стека
  6.             {
  7.                 private object inf;
  8.                 private Node next;
  9.                 public Node(object nodeInfo)
  10.                 {
  11.                     inf = nodeInfo;
  12.                     next = null;
  13.                 }
  14.                 public Node Next
  15.                 {
  16.                     get { return next; }
  17.                     set { next = value; }
  18.                 }
  19.                 public object Inf
  20.                 {
  21.                     get { return inf; }
  22.                     set { inf = value; }
  23.                 }
  24.             } //конец класса Node
  25.             private Node head; //ссылка на вершину стека
  26.             public Stack() //конструктор класса, создает пустой стек
  27.             {
  28.                 head = null;
  29.             }
  30.             public void Push(object nodeInfo) // добавляет элемент в вершину стека
  31.             {
  32.                 Node r = new Node(nodeInfo);
  33.                 r.Next = head;
  34.                 head = r;
  35.             }
  36.             public object Pop() //извлекает элемент из вершины стека, если он не пуст
  37.             {
  38.                 if (head == null)
  39.                 {
  40.                     throw new Exception("Стек пуст");
  41.                 }
  42.                 else
  43.                 {
  44.                     Node r = head;
  45.                     head = r.Next;
  46.                     return r.Inf;
  47.                 }
  48.             }
  49.             public bool IsEmpty //определяет пуст или нет стек
  50.             {
  51.                 get
  52.                 {
  53.                     if (head == null)
  54.                     {
  55.                         return true;
  56.                     }
  57.                     else
  58.                     {
  59.                         return false;
  60.                     }
  61.                 }
  62.             }
  63.         }
  64.         public class Queue
  65.         {
  66.             private class Node //вложенный класс, реализующий базовый элемент очереди
  67.             {
  68.                 private object inf;
  69.                 private Node next;
  70.                 public Node(object nodeInfo)
  71.                 {
  72.                     inf = nodeInfo;
  73.                     next = null;
  74.                 }
  75.                 public Node Next
  76.                 {
  77.                     get { return next; }
  78.                     set { next = value; }
  79.                 }
  80.                 public object Inf
  81.                 {
  82.                     get { return inf; }
  83.                     set { inf = value; }
  84.                 }
  85.             } //конец класса Node
  86.             private Node head;
  87.             private Node tail;
  88.             public Queue()
  89.             {
  90.                 head = null;
  91.                 tail = null;
  92.             }
  93.             public void Add(object nodeInfo)
  94.             {
  95.                 Node r = new Node(nodeInfo);
  96.                 if (head == null)
  97.                 {
  98.                     head = r;
  99.                     tail = r;
  100.                 }
  101.                 else
  102.                 {
  103.                     tail.Next = r;
  104.                     tail = r;
  105.                 }
  106.             }
  107.             public object Take()
  108.             {
  109.                 if (head == null)
  110.                 {
  111.                     throw new Exception("Очередь пуста.");
  112.                 }
  113.                 else
  114.                 {
  115.                     Node r = head;
  116.                     head = head.Next;
  117.                     if (head == null)
  118.                     {
  119.                         tail = null;
  120.                     }
  121.                     return r.Inf;
  122.                 }
  123.             }
  124.             public bool IsEmpty
  125.             {
  126.                 get
  127.                 {
  128.                     if (head == null)
  129.                     {
  130.                         return true;
  131.                     }
  132.                     else
  133.                     {
  134.                         return false;
  135.                     }
  136.                 }
  137.             }
  138.         }
  139.  
  140.         public class Graph
  141.         {
  142.             private class Node //вложенный класс для скрытия данных и алгоритмов
  143.             {
  144.                 private int[,] array; //матрица смежности
  145.                 public int this[int i, int j] //индексатор для обращения к матрице смежности
  146.                 {
  147.                     get
  148.                     {
  149.                         return array[i, j];
  150.                     }
  151.                     set
  152.                     {
  153.                         array[i, j] = value;
  154.                     }
  155.                 }
  156.                 public bool this[int i] //индексатор для обращения к матрице меток
  157.                 {
  158.                     get
  159.                     {
  160.                         return nov[i];
  161.                     }
  162.                     set
  163.                     {
  164.                         nov[i] = value;
  165.                     }
  166.                 }
  167.                 public int Size //свойство для получения размерности матрицы смежности
  168.                 {
  169.                     get
  170.                     {
  171.                         return array.GetLength(0);
  172.                     }
  173.                 }
  174.                 private bool[] nov; //вспомогательный массив: если i-ый элемент массива равен
  175.                                     //true, то i-ая вершина еще не просмотрена; если i-ый
  176.                                     //элемент равен false, то i-ая вершина просмотрена
  177.                 public void NovSet() //метод помечает все вершины графа как непросмотреные
  178.                 {
  179.                     for (int i = 0; i < Size; i++)
  180.                     {
  181.                         nov[i] = true;
  182.                     }
  183.                 }
  184.                 //конструктор вложенного класса, инициализирует матрицу смежности и
  185.                 // вспомогательный массив
  186.                 public Node(int[,] a)
  187.                 {
  188.                     array = a;
  189.                     nov = new bool[a.GetLength(0)];
  190.                 }
  191.                 //реализация алгоритма обхода графа в глубину
  192.                 public void Dfs(int v)
  193.                 {
  194.                     Console.Write("{0} ", v); //просматриваем текущую вершину
  195.                     nov[v] = false; //помечаем ее как просмотренную
  196.                                     // в матрице смежности просматриваем строку с номером v
  197.                     for (int u = 0; u < Size; u++)
  198.                     {
  199.                         //если вершины v и u смежные, к тому же вершина u не просмотрена,
  200.                         if (array[v, u] != 0 && nov[u])
  201.                         {
  202.                             Dfs(u); // то рекурсивно просматриваем вершину
  203.                         }
  204.                     }
  205.                 }
  206.                 //реализация алгоритма обхода графа в ширину
  207.                 public void Bfs(int v)
  208.                 {
  209.                     Queue q = new Queue(); // инициализируем очередь
  210.                     q.Add(v); //помещаем вершину v в очередь
  211.                     nov[v] = false; // помечаем вершину v как просмотренную
  212.                     while (!q.IsEmpty) // пока очередь не пуста
  213.                     {
  214.                         v = Convert.ToInt32(q.Take()); //извлекаем вершину из очереди
  215.                         Console.Write("{0} ", v); //просматриваем ее
  216.                         for (int u = 0; u < Size; u++) //находим все вершины
  217.                         {
  218.                             if (array[v, u] != 0 && nov[u]) // смежные с данной и еще не просмотренные
  219.                             {
  220.                                 q.Add(u); //помещаем их в очередь
  221.                                 nov[u] = false; //и помечаем как просмотренные
  222.                             }
  223.                         }
  224.                     }
  225.                 }
  226.                 public long[,] Floyd(out int[,] p)
  227.                 {
  228.                     int i, j, k;
  229.                     //создаем массивы р и а
  230.                     long[,] a = new long[Size, Size];
  231.                     p = new int[Size, Size];
  232.                     for (i = 0; i < Size; i++)
  233.                     {
  234.                         for (j = 0; j < Size; j++)
  235.                         {
  236.                             if (i == j)
  237.                             {
  238.                                 a[i, j] = 0;
  239.                             }
  240.                             else
  241.                             {
  242.                                 if (array[i, j] == 0)
  243.                                 {
  244.                                     a[i, j] = int.MaxValue;
  245.                                 }
  246.                                 else
  247.                                 {
  248.                                     a[i, j] = array[i, j];
  249.                                 }
  250.                             }
  251.                             p[i, j] = -1;
  252.                         }
  253.                     }
  254.                     //осуществляем поиск кратчайших путей
  255.                     for (k = 0; k < Size; k++)
  256.                     {
  257.                         for (i = 0; i < Size; i++)
  258.                         {
  259.                             for (j = 0; j < Size; j++)
  260.                             {
  261.                                 long distance = a[i, k] + a[k, j];
  262.                                 if (a[i, j] > distance)
  263.                                 {
  264.                                     a[i, j] = distance;
  265.                                     p[i, j] = k;
  266.                                 }
  267.                             }
  268.                         }
  269.                     }
  270.                     return a;//в качестве результата возвращаем массив кратчайших путей между
  271.                 } //всеми парами вершин
  272.  
  273.  
  274.                 public void SearchG(int v, ref int[,] a, ref Stack c) //во вложенном классе
  275.                 {
  276.                     for (int i = 0; i < a.GetLength(0); i++)
  277.                     {
  278.                         if (a[v, i] != 0)
  279.                         {
  280.                             a[v, i] = 0; a[i, v] = 0;
  281.                             SearchG(i, ref a, ref c);
  282.                         }
  283.                     }
  284.                     c.Push(v);
  285.                 }
  286.  
  287.                 public long[] Dijkstr(int v, out int[] p)
  288.                 {
  289.                     nov[v] = false; // помечаем вершину v как просмотренную
  290.                                     //создаем матрицу с
  291.                     int[,] c = new int[Size, Size];
  292.                     for (int i = 0; i < Size; i++)
  293.                     {
  294.                         for (int u = 0; u < Size; u++)
  295.                         {
  296.                             if (array[i, u] == 0 || i == u)
  297.                             {
  298.                                 c[i, u] = int.MaxValue;
  299.                             }
  300.                             else
  301.                             {
  302.                                 c[i, u] = array[i, u];
  303.                             }
  304.                         }
  305.                     }
  306.                     //создаем матрицы d и p
  307.                     long[] d = new long[Size];
  308.                     p = new int[Size];
  309.                     for (int u = 0; u < Size; u++)
  310.                     {
  311.                         if (u != v)
  312.                         {
  313.                             d[u] = c[v, u];
  314.                             p[u] = v;
  315.                         }
  316.                     }
  317.                     for (int i = 0; i < Size - 1; i++) // на каждом шаге цикла
  318.                     {
  319.                         // выбираем из множества V\S такую вершину w, что D[w] минимально
  320.                         long min = int.MaxValue;
  321.                         int w = 0;
  322.                         for (int u = 0; u < Size; u++)
  323.                         {
  324.                             if (nov[u] && min > d[u])
  325.                             {
  326.                                 min = d[u];
  327.                                 w = u;
  328.                             }
  329.                         }
  330.                         nov[w] = false; //помещаем w в множество S
  331.                                         //для каждой вершины из множества V\S определяем кратчайший путь от
  332.                                         // источника до этой вершины
  333.                         for (int u = 0; u < Size; u++)
  334.                         {
  335.                             long distance = d[w] + c[w, u];
  336.                             if (nov[u] && d[u] > distance)
  337.                             {
  338.                                 d[u] = distance;
  339.                                 p[u] = w;
  340.                             }
  341.                         }
  342.                     }
  343.                     return d; //в качестве результата возвращаем массив кратчайших путей для
  344.                 } //заданного источника
  345.  
  346.                   //восстановление пути от вершины a до вершины b для алгоритма Дейкстры
  347.                 public void WayDijkstr(int a, int b, int[] p, ref Stack items)
  348.                 {
  349.                     items.Push(b); //помещаем вершину b в стек
  350.                     if (a == p[b]) //если предыдущей для вершины b является вершина а, то
  351.                     {
  352.                         items.Push(a); //помещаем а в стек и завершаем восстановление пути
  353.                     }
  354.                     else //иначе метод рекурсивно вызывает сам себя для поиска пути
  355.                     { //от вершины а до вершины, предшествующей вершине b
  356.                         WayDijkstr(a, p[b], p, ref items);
  357.                     }
  358.                 }
  359.                 public void SearchGm(int k, ref int[] St,int start)//вложенный класс
  360.                 {
  361.                     int v = St[k-1];
  362.                     for (int j = 0; j < array.GetLength(0); j++)
  363.                     {
  364.                         if (array[v, j] != 0)
  365.                         {
  366.                             if (k == array.GetLength(0) && j==start)
  367.                             {
  368.                                 St[k] = j;
  369.                                 foreach (int item in St)
  370.                                 {
  371.                                    Console.Write(item+" ");
  372.                                 }
  373.                                 Console.WriteLine();
  374.                             }
  375.                             else
  376.                             {
  377.                                 if (nov[j])
  378.                                 {
  379.                                     if (k >= St.Length)
  380.                                         return;
  381.                                     St[k] = j;
  382.                                     nov[j] = false;
  383.                                     SearchGm(k + 1, ref St,start);
  384.                                     nov[j] = true;
  385.                                    
  386.                                 }
  387.                             }
  388.  
  389.                         }
  390.  
  391.                     }
  392.                    
  393.                 }
  394.  
  395.             } //конец вложенного клаcса
  396.             private Node graph; //закрытое поле, реализующее АТД «граф»
  397.  
  398.             public Graph(string name) //конструктор внешнего класса
  399.             {
  400.                 using (StreamReader file = new StreamReader(name))
  401.                 {
  402.                     int n = int.Parse(file.ReadLine());
  403.                     int[,] a = new int[n, n];
  404.                     for (int i = 0; i < n; i++)
  405.                     {
  406.                         string line = file.ReadLine();
  407.                         string[] mas = line.Split(' ');
  408.                         for (int j = 0; j < n; j++)
  409.                         {
  410.                             a[i, j] = int.Parse(mas[j]);
  411.                         }
  412.                     }
  413.                     graph = new Node(a);
  414.                 }
  415.             }
  416.             public bool GraphCheck()
  417.             {
  418.                 bool check = true;
  419.                 int count = 0;
  420.                 int temp = 0;
  421.                 for (int i = 0; i < graph.Size; i++)
  422.                 {
  423.                     for (int j = 0; j < graph.Size; j++)
  424.                     {
  425.                         if (graph[i, j] != 0)
  426.                             count++;
  427.                     }
  428.                     if (count % 2 != 0)
  429.                     {
  430.                         temp++;
  431.                     }
  432.                     count = 0;
  433.                 }
  434.                 if (temp % 2 != 0)
  435.                     check = false;
  436.                 return check;
  437.             }
  438.             //метод выводит матрицу смежности на консольное окно
  439.             public void Show()
  440.             {
  441.                 for (int i = 0; i < graph.Size; i++)
  442.                 {
  443.                     for (int j = 0; j < graph.Size; j++)
  444.                     {
  445.                         Console.Write("{0,4}", graph[i, j]);
  446.                     }
  447.                     Console.WriteLine();
  448.                 }
  449.             }
  450.             public void Dfs(int v)
  451.             {
  452.                 graph.NovSet();//помечаем все вершины графа как непросмотренные
  453.                 graph.Dfs(v); //запускаем алгоритм обхода графа в глубину
  454.                 Console.WriteLine();
  455.             }
  456.             public void Bfs(int v)
  457.             {
  458.                 graph.NovSet();//помечаем все вершины графа как непросмотренные
  459.                 graph.Bfs(v); //запускаем алгоритм обхода графа в ширину
  460.                 Console.WriteLine();
  461.             }
  462.  
  463.  
  464.             public void Neighbouring()
  465.             {
  466.                 Console.Write("Вершины не смежные с вершиной: ");
  467.                 int v = int.Parse(Console.ReadLine());
  468.                 //просматриваем строку с номером v в матрице смежности
  469.                 for (int i = 0; i < graph.Size; i++)
  470.                 {
  471.                     //если на пересечении строки v и столбца i стоит не ноль, то вершина i является
  472.                     //соседней для вершины v
  473.                     if (graph[v, i] == 0 && v != i)
  474.                     {
  475.                         Console.Write("{0} ", i);
  476.                     }
  477.                 }
  478.                 Console.WriteLine();
  479.             }
  480.             public void SearchG(int start) //во внешнем классе Эйлеров
  481.             {
  482.                 int[,] a = new int[graph.Size, graph.Size];
  483.                 for (int i = 0; i < graph.Size; i++)
  484.                 {
  485.                     for (int j = 0; j < graph.Size; j++)
  486.                     {
  487.                         a[i, j] = graph[i, j];
  488.                     }
  489.                 }
  490.                 Stack c = new Stack();
  491.                 graph.SearchG(start, ref a, ref c);
  492.                 //while (c.Count != 0)
  493.                 while (!c.IsEmpty)
  494.                 {
  495.                     Console.Write("{0} ", (int)c.Pop() );
  496.                 }
  497.             }
  498.             public void SearchGm()//внешний класс Гамильтонов
  499.             {
  500.                 graph.NovSet();
  501.                 int[] St = new int[graph.Size + 1];
  502.                 graph[0] = false; //обращение к индексатору
  503.                 Console.Write("Вершина:");
  504.                 int k = int.Parse(Console.ReadLine());
  505.                 int start = k;
  506.                 St[0] = k;
  507.                // St[0] = 0;
  508.                 graph.SearchGm(k, ref St,start);
  509.             }
  510.  
  511.             public int GetLength()
  512.             {
  513.                 return graph.Size;
  514.             }
  515.            
  516.               //восстановление пути от вершины a до вершины в для алгоритма Флойда
  517.             public void WayFloyd(int a, int b, int[,] p, ref Queue items)
  518.             {
  519.                 int k = p[a, b];
  520.                 //если k<> -1, то путь состоит более чем из двух вершин а и b, и проходит через
  521.                 //вершину k, поэтому
  522.                 if (k != -1)
  523.                 {
  524.                     // рекурсивно восстанавливаем путь между вершинами а и k
  525.                     WayFloyd(a, k, p, ref items);
  526.                     items.Add(k); //помещаем вершину к в очередь
  527.                                   // рекурсивно восстанавливаем путь между вершинами k и b
  528.                     WayFloyd(k, b, p, ref items);
  529.                 }
  530.             }
  531.  
  532.             public int CentralApex()
  533.             {
  534.             int[,] p;
  535.             long[,] a = graph.Floyd(out p); //вызываем алгоритм Флойда
  536.             long min = int.MaxValue;
  537.             int imin = -1;
  538.  
  539.             for (int i = 0; i < graph.Size; i++)
  540.             {
  541.                 int imax = i;
  542.                 int jmax = 0;
  543.                 // для каждой строки матрицы определяем эксцентриситет
  544.                 for (int j = 0; j < graph.Size; j++)
  545.                 {
  546.                     if (a[i, j] > a[imax, jmax])
  547.                     {
  548.                         imax = i;
  549.                         jmax = j;
  550.                     }
  551.                 }
  552.                 //среди найденных эксцентриситетов определяем наименьший
  553.                 if (a[imax, jmax] < min)
  554.                 {
  555.                     min = a[imax, jmax];
  556.                     imin = imax;
  557.                 }
  558.             }
  559.             return imin; //возвращаем номер вершины с наименьшим эксцентриситетом
  560.         }
  561.             public void Dijkstr(int v)
  562.             {
  563.                 graph.NovSet();//помечаем все вершины графа как непросмотренные
  564.                 int[] p;
  565.                 long[] d = graph.Dijkstr(v, out p); //запускаем алгоритм Дейкстры
  566.                                                     //анализируем полученные данные и выводим их на экран
  567.                 Console.WriteLine("Длина кратчайшие пути от вершины {0} до вершины", v);
  568.                 for (int i = 0; i < graph.Size; i++)
  569.                 {
  570.                     if (i != v)
  571.                     {
  572.                         Console.Write("{0} равна {1}, ", i, d[i]);
  573.                         Console.Write("путь ");
  574.                         if (d[i] != int.MaxValue)
  575.                         {
  576.                             Stack items = new Stack();
  577.                             graph.WayDijkstr(v, i, p, ref items);
  578.                             while (!items.IsEmpty)
  579.                             {
  580.                                 Console.Write("{0} ", items.Pop());
  581.                             }
  582.                         }
  583.                     }
  584.                     Console.WriteLine();
  585.                 }
  586.             }
  587.  
  588.             public void InMinDistance()
  589.             {
  590.                 graph.NovSet(); //помечаем все вершины графа как непросмотренные
  591.                 int[] p;
  592.                 Console.Write("Введите вершину=");
  593.                 int v = int.Parse(Console.ReadLine());
  594.                 long[] d = graph.Dijkstr(v, out p); //запускаем алгоритм дейкстры
  595.                 long min = long.MaxValue;
  596.                 //вычисляем наименьшее расстояние для достижимых вершин
  597.                 for (int i = 0; i < p.Length; i++)
  598.                     if (min > d[i] && d[i] != 0)
  599.                         min = d[i];
  600.                 //выводим на экран все вершины, находящиеся от заданной на наименьшем расстоянии
  601.                 if (min == 0)
  602.                     Console.WriteLine("Из заданной вершины другие вершины недостижимы");
  603.                 else
  604.                 {
  605.                     Console.Write("На наименьшем удалении от вершины {0} находятся вершины: ",v);
  606.                     for (int i = 0; i < d.Length; i++)
  607.                         if (d[i] == min)
  608.                             Console.Write(i+" ");
  609.                     Console.WriteLine();
  610.                 }
  611.  
  612.             }
  613.  
  614.         }
  615.        
  616.  
  617.  
  618.         static void Main(string[] args)
  619.         {
  620.             Graph g = new Graph(@"E:/input.txt");
  621.             g.SearchGm();
  622.             //g.InMinDistance();
  623.         }
  624.     }
Add Comment
Please, Sign In to add comment