Slavik9510

Untitled

May 20th, 2023
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.30 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Xml.Linq;
  8.  
  9. namespace DOLab7
  10. {
  11.     public class Vertex
  12.     {
  13.         public int id;
  14.         public List<Vertex> AdjacentVerticies;
  15.         public List<int> Distances;
  16.  
  17.         public Vertex()
  18.         {
  19.             AdjacentVerticies = new List<Vertex>();
  20.             Distances = new List<int>();
  21.         }
  22.  
  23.  
  24.         public int GetFullWeight()
  25.         {
  26.             int sum = 0;
  27.             for (int i = 0; i < Distances.Count; i++)
  28.             {
  29.                 sum += Distances[i];
  30.             }
  31.             return sum;
  32.         }
  33.     }
  34.     public class GomoriXy
  35.     {
  36.         private List<Vertex> verticies = new List<Vertex>();
  37.  
  38.         private List<Vertex> neighborsCombination;
  39.         public GomoriXy(string path)
  40.         {
  41.             string[] data = File.ReadAllLines(path);
  42.             int peaks = data.Length;
  43.  
  44.             for (int i = 0; i < peaks; i++)
  45.             {
  46.                 verticies.Add(new Vertex());
  47.             }
  48.  
  49.             for (int i = 0; i < peaks; i++)
  50.             {
  51.                 verticies[i].id = i + 1;
  52.  
  53.                 string[] distances = data[i].Split(" ");
  54.  
  55.                 for (int j = 0; j < distances.Length; j++)
  56.                 {
  57.                     if (j != i && int.Parse(distances[j]) != 0)
  58.                     {
  59.                         //Додаємо до вершини іншу суміжну вершину
  60.                         verticies[i].AdjacentVerticies.Add(verticies[j]);
  61.                         //Під цим же індексом додаємо відстань до цієї вершини
  62.                         verticies[i].Distances.Add(int.Parse(distances[j]));
  63.                     }
  64.                 }
  65.             }
  66.         }
  67.         public void Solve()
  68.         {
  69.             int[,] maximumFlowMatrix = new int[verticies.Count, verticies.Count];
  70.  
  71.             for (int i = 0; i < verticies.Count; i++)
  72.             {
  73.                 for (int j = 0; j < verticies.Count; j++)
  74.                 {
  75.                     int min = verticies[i].GetFullWeight(); //Як min спочатку беремо повну вагу(вага дуг, якщо вершину обрізати саму)
  76.  
  77.                     neighborsCombination = new List<Vertex>();
  78.  
  79.                     neighborsCombination.Add(verticies[i]);
  80.                     MinCut(neighborsCombination, verticies[j], ref min); //А тут рахуємо чи не буде вага менша, якщо обрізати декілька вершин
  81.                     maximumFlowMatrix[i, j] = min;
  82.                 }
  83.             }
  84.             printFinalResults(maximumFlowMatrix);
  85.         }
  86.         public void MinCut(List<Vertex> combination, Vertex current, ref int min)
  87.         {
  88.             //Тут перевіряємо всі можливі комбінації розрізів
  89.             List<Vertex> newCombination = new List<Vertex>(combination);
  90.  
  91.             for (int i = 0; i < verticies.Count; i++)
  92.             {
  93.                 if (newCombination.Contains(verticies[i]) || verticies[i] == current)
  94.                 {
  95.                     continue;
  96.                 }
  97.  
  98.                 bool isConnected = CheckConnection(verticies[i], newCombination);
  99.                 if (isConnected)
  100.                 {
  101.                     //якщо до i-тої вершини є шлях з поточного розрізу додаємо її до розрізу
  102.                     newCombination.Add(verticies[i]);
  103.                 }
  104.                 else
  105.                 {
  106.                     continue;
  107.                 }
  108.  
  109.                 int currentWeigth = GetWeightOfCut(newCombination);
  110.                 if (currentWeigth < min)
  111.                 {
  112.                     //Тут знаходимо вагу мінімального розрізу
  113.                     min = GetWeightOfCut(newCombination);
  114.                     neighborsCombination = new List<Vertex>(newCombination);
  115.                 }
  116.                 //Рекурсивно повторюємо
  117.                 MinCut(newCombination, current, ref min);
  118.                 //Коли перебрали всі суміжні i-тої вершини, видаляємо її з розрізу
  119.                 //Коли переберемо всі можливі комбінації в min буде міститися вага мінімальної,
  120.                 //її ми і запишемо в матрицю (maximumFlowMatrix[i, j] = min)
  121.                 newCombination.Remove(verticies[i]);
  122.             }
  123.         }
  124.         public bool CheckConnection(Vertex apex, List<Vertex> combination)
  125.         {
  126.             for (int i = 0; i < combination.Count; i++)
  127.             {
  128.                 for (int j = 0; j < combination[i].AdjacentVerticies.Count; j++)
  129.                 {
  130.                     if (combination[i].AdjacentVerticies[j] == apex)
  131.                     {
  132.                         return true;
  133.                     }
  134.                 }
  135.             }
  136.             return false;
  137.         }
  138.         public int GetWeightOfCut(List<Vertex> apexes)
  139.         {
  140.             int sum = 0;
  141.             for (int i = 0; i < apexes.Count; i++)
  142.             {
  143.                 for (int j = 0; j < apexes[i].AdjacentVerticies.Count; j++)
  144.                 {
  145.                     if (!apexes.Contains(apexes[i].AdjacentVerticies[j]))
  146.                     {
  147.                         sum += apexes[i].Distances[j];
  148.                     }
  149.                 }
  150.             }
  151.             return sum;
  152.         }
  153.         private void printFinalResults(int[,] matrix)
  154.         {
  155.             Console.WriteLine("Матриця МП-кiв мiж вузлами мережi:\n");
  156.  
  157.             for (int i = 0; i < verticies.Count; i++)
  158.             {
  159.                 for (int j = 0; j < verticies.Count; j++)
  160.                 {
  161.                     if (i == j)
  162.                     {
  163.                         Console.Write("-".PadRight(4));
  164.                     }
  165.                     else
  166.                     {
  167.                         Console.Write($"{matrix[i, j]}".PadRight(4));
  168.                     }
  169.                 }
  170.                 Console.WriteLine();
  171.             }
  172.         }
  173.     }
  174. }
Add Comment
Please, Sign In to add comment