Advertisement
Tolyamba

DM_LR1_v3

Dec 22nd, 2016
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.84 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace DM_LR1
  8. {
  9.     class Program
  10.     {
  11.         // ограничения по длине
  12.         const int MIN_LENGTH = 1;
  13.         const int MAX_LENGTH = 100;
  14.  
  15.         // ограничения значений
  16.         const int MIN_VALUE = -100;
  17.         const int MAX_VALUE = 100;
  18.  
  19.         // переменные для клики
  20.         public static int n;
  21.         public static int[,] g = new int[20, 20];
  22.         public static int[] res = new int[20];
  23.         public static int[] q = new int[20];
  24.         public static int N_res, i_end;
  25.  
  26.         static int ReadIntNumber(string stringForUser, int left, int right)
  27.         {
  28.             bool okInput = false;
  29.             int number = MIN_VALUE;
  30.             do
  31.             {
  32.                 Console.WriteLine(stringForUser);
  33.                 try
  34.                 {
  35.                     string buf = Console.ReadLine();
  36.                     number = Convert.ToInt32(buf); // могут возникнуть исключения FormatException, OverflowException
  37.                     if (number >= left && number <= right) okInput = true;
  38.                     else
  39.                     {
  40.                         Console.WriteLine("Некорректное значение! Повторите ввод. ");
  41.                         okInput = false;
  42.                     }
  43.                 }
  44.  
  45.                 catch (FormatException)
  46.                 {
  47.                     Console.WriteLine("Некорректное значение! Повторите ввод. ");
  48.                     okInput = false;
  49.                 }
  50.  
  51.                 catch (OverflowException)
  52.                 {
  53.                     Console.WriteLine("Некорректное значение! Повторите ввод. ");
  54.                     okInput = false;
  55.                 }
  56.  
  57.             } while (!okInput);
  58.             return number;
  59.         }
  60.  
  61.         static void PrintMenu()
  62.         {
  63.             Console.WriteLine("[1]. Алгоритм Шимбелла");
  64.             Console.WriteLine("[2]. Клика (неориентированный граф)");
  65.             Console.WriteLine("[3]. Выделение компонент связности графа");
  66.             Console.WriteLine();
  67.             Console.WriteLine("[4]. Выход");
  68.         }
  69.  
  70.  
  71.         static void algShimbella()
  72.         {
  73.             Console.Clear();
  74.             Console.WriteLine("Алгоритм Шимбелла\n");
  75.             int i, j;
  76.             // mas — матрица весов            
  77.             int n = ReadIntNumber("Введите размерность матрицы весов: ", MIN_LENGTH, MAX_LENGTH);
  78.             int[,] mas = new int[n, n];
  79.             int[,] mas2 = new int[n, n];
  80.  
  81.             for (i = 0; i < n; i++)
  82.             {
  83.                 for (j = 0; j < n; j++)
  84.                 {
  85.                     mas[i, j] = ReadIntNumber("Введите элемент матрицы [" + i + ", " + j + "]:", 0, MAX_LENGTH);
  86.                     mas2[i, j] = mas[i, j];
  87.                 }
  88.             }
  89.  
  90.             int min = 100;
  91.             int max = 0;
  92.             int s = 0;
  93.  
  94.             int x, h, a, b;
  95.             int[,] massum = new int[n, n];
  96.  
  97.             int k = ReadIntNumber("Введите число рёбер графа: ", MIN_LENGTH, MAX_LENGTH);
  98.             int t = ReadIntNumber("Какие пути между вершинами показать?\n [1]. Минимальные\n [2]. Максимальные", 1, 2);
  99.  
  100.             if (t == 1) //Находим минимальные пути
  101.             {
  102.                 for (h = 0; h < k - 1; h++)
  103.                 {
  104.                     for (i = 0; i < n; i++)
  105.                     {
  106.                         for (x = 0; x < n; x++)
  107.                         {
  108.                             for (j = 0; j < n; j++)
  109.                             {
  110.                                 if ((mas[i, j] == 0) || (mas2[j, x] == 0))
  111.  
  112.                                     s = 0;
  113.  
  114.                                 else
  115.                                 {
  116.                                     s = mas[i, j] + mas2[j, x];
  117.                                     if (s <= min)
  118.                                         min = s;
  119.                                 }
  120.                             }
  121.                             if (min == 100) { min = 0; }
  122.                             massum[i, x] = min;
  123.                             s = 0;
  124.                             min = 100;
  125.  
  126.                         }
  127.                     }
  128.                     Console.Write("Матрица для кратчайшего расстояния (количество рёбер: " + (h + 2) + "):\n");
  129.                     for (a = 0; a < n; a++)
  130.                     {
  131.                         for (b = 0; b < n; b++)
  132.                         {
  133.                             Console.Write("{0, 4}", massum[a, b]);
  134.                             mas[a, b] = massum[a, b];
  135.                             massum[a, b] = 0;
  136.                         }
  137.                         Console.WriteLine();
  138.                     }
  139.                     Console.WriteLine();
  140.                 }
  141.             }
  142.  
  143.             else //Находим максимальные пути
  144.             {
  145.                 for (h = 0; h < k - 1; h++)
  146.                 {
  147.                     for (i = 0; i < n; i++)
  148.                     {
  149.                         for (x = 0; x < n; x++)
  150.                         {
  151.                             for (j = 0; j < n; j++)
  152.                             {
  153.                                 if ((mas[i, j] == 0) || (mas2[j, x] == 0))
  154.                                     s = 0;
  155.                                 else
  156.                                 {
  157.                                     s = mas[i, j] + mas2[j, x];
  158.                                     if (s >= max)
  159.                                         max = s;
  160.                                 }
  161.                             }
  162.                             massum[i, x] = max;
  163.                             s = 0;
  164.                             max = 0;
  165.                         }
  166.                     }
  167.                     Console.Write("Матрица для максимального расстояния (количество рёбер: " + (h + 2) + "):\n");
  168.                     for (a = 0; a < n; a++)
  169.                     {
  170.                         for (b = 0; b < n; b++)
  171.                         {
  172.                             Console.Write("{0, 4}", massum[a, b]);
  173.                             mas[a, b] = massum[a, b];
  174.                             massum[a, b] = 0;
  175.                         }
  176.                         Console.WriteLine();
  177.                     }
  178.                     Console.WriteLine();
  179.                 }
  180.             }
  181.         }
  182.  
  183.         static void rec(int ii, int N) // рекурсивный алгоритм для клики
  184.         {
  185.             int i, j;
  186.             if (N > N_res) // текущая вершина, последняя результирующая вершина
  187.             {
  188.                 for (i = 0; i < i_end; i++)
  189.                     res[i] = q[i];
  190.                 N_res = N;
  191.             }
  192.  
  193.             if (ii == n) // рассмотрена последняя вершина
  194.                 return;
  195.  
  196.             for (i = ii; i < n; i++) // просматриваем вершины от текущей до последней
  197.             {
  198.                 for (j = 0; j < i_end; j++)
  199.                     if (g[q[j], i] == 0) // если данная вершина 0, выходим из цикла
  200.                         break;
  201.  
  202.                 if (j == i_end) // последняя вершина, до которой можно дойти
  203.                 {
  204.                     q[i_end++] = i;
  205.                     rec(ii + 1, N + 1);
  206.                     i_end--;
  207.                 }
  208.                 rec(ii + 1, N);
  209.             }
  210.         }
  211.  
  212.         static void click()
  213.         {
  214.             Console.Clear();
  215.             Console.WriteLine("Клика (неориентированный граф)\n");
  216.  
  217.             n = ReadIntNumber("Введите количество вершин: ", 1, 20);
  218.  
  219.             for (int i = 0; i < n; i++)
  220.             {
  221.                 for (int j = 0; j < n; j++)
  222.                     g[i, j] = ReadIntNumber("Введите элемент матрицы [" + i + ", " + j + "]:", 0, 1);
  223.             }
  224.  
  225.             for (int i = 0; i < n; i++)
  226.             {
  227.                 for (int j = 0; j < n; j++)
  228.                     if (g[i, j] == 1) g[j, i] = 1;
  229.             }
  230.  
  231.             Console.WriteLine("--- Матрица смежности (введёная) ---");
  232.             for (int i = 0; i < n; i++)
  233.             {
  234.                 for (int j = 0; j < n; j++)
  235.                     Console.Write(g[i, j] + " ");
  236.                 Console.WriteLine();
  237.             }
  238.  
  239.             for (int i = 0; i < n; i++) // для каждой вершины вызов функции
  240.             {
  241.                 i_end = 0;
  242.                 rec(i, 0);
  243.             }
  244.  
  245.             Console.WriteLine("-------------- Клика ---------------");
  246.             int count = 0;
  247.             Console.Write("Наибольший полный подграф: ");
  248.             for (int i = 0; i < N_res; i++)
  249.             {
  250.                 Console.Write(res[i] + 1 + " ");
  251.                 count++;
  252.             }
  253.             Console.WriteLine();
  254.             Console.WriteLine("Максимальная клика: " + count + '\n');
  255.         }
  256.  
  257.  
  258.         static void component()
  259.         {
  260.             Console.Clear();
  261.             Console.WriteLine("Выделение компонент связности\n");
  262.             int n = ReadIntNumber("Введите количество вершин: ", MIN_LENGTH, MAX_LENGTH);            
  263.             int[,] ms = new int[n, n]; // матрица смежности
  264.             for (int i = 0; i < n; i++)
  265.             {
  266.                 for (int j = 0; j < n; j++)
  267.                     ms[i, j] = ReadIntNumber("Введите элемент [" + i + ", " + j + "]: ", 0, 1);
  268.             }
  269.  
  270.             Console.WriteLine("--- Матрица смежности (введёная) ---");
  271.             for (int i = 0; i < n; i++)
  272.             {
  273.                 for (int j = 0; j < n; j++)
  274.                     Console.Write(ms[i, j]+ " ");
  275.                 Console.WriteLine();
  276.             }            
  277.             Console.WriteLine();
  278.  
  279.             // алгоритм флойда
  280.             int k = 0;
  281.             int n1 = ms.GetLength(0);
  282.             for (k = 0; k < n1; k++)
  283.                 for (int i = 0; i < n1; i++)
  284.                     for (int j = 0; j < n1; j++)
  285.                     {
  286.                         ms[i, i] = 1;
  287.                         if (ms[i, k] != 0 && ms[k, j] != 0)
  288.                             if ((ms[i, k] + ms[k, j] < ms[i, j]) || (ms[i, j] == 0))
  289.                                 ms[i, j] = 1;
  290.                     }
  291.  
  292.             Console.WriteLine("------- Матрица достижимости -------");
  293.             for (int i = 0; i < n1; i++)
  294.             {
  295.                 for (int j = 0; j < n1; j++)
  296.                     Console.Write(ms[i, j] + " ");
  297.                 Console.WriteLine();
  298.             }            
  299.             Console.WriteLine();
  300.  
  301.            
  302.             Console.WriteLine("---- Матрица сильной связности -----");
  303.             int[,] mss = new int[n, n]; // матрица сильной связности
  304.             for (int i = 0; i < n1; i++)
  305.             { // получаем матрицу сильной связности, умножая матрицу матрицу достижимости на транспонированную матрицу достижимости
  306.                 for (int j = 0; j < n1; j++)
  307.                     mss[i, j] = ms[i, j] & ms[j, i];
  308.             }
  309.             for (int i = 0; i < n1; i++)
  310.             {
  311.                 for (int j = 0; j < n1; j++)
  312.                     Console.Write(mss[i, j] + " ");
  313.                 Console.WriteLine();
  314.             }            
  315.             Console.WriteLine();        
  316.  
  317.             int count = 0; //счётчик компонент
  318.             int check = 0;
  319.             int[] kompon = new int[n]; // массив для временного хранения компонент
  320.             for (int a = 0; a < kompon.Length; a++)
  321.                 kompon[a] = 0;
  322.             bool[] prov = new bool[n]; // проверка на посещение вершины
  323.             for (int a = 0; a < prov.Length; a++)
  324.                 prov[a] = false;
  325.  
  326.             while (check != n)
  327.             {
  328.                 int i = 0;
  329.                 int j = 0;
  330.                 for(int b = 0; b < prov.Length; b++)
  331.                 {
  332.                     if (!prov[b])
  333.                     {
  334.                         i = b;
  335.                         j = b;
  336.                         break;
  337.                     }
  338.                 }
  339.  
  340.                 for (; i < n; i++)
  341.                 {
  342.                     for (; j < n; j++)
  343.                         if (mss[i, j] == 1 && kompon[j] == 0 && !prov[j])
  344.                         {
  345.                             kompon[j] = j + 1;
  346.                             prov[j] = true;
  347.                         }                    
  348.                 }
  349.  
  350.                 count++;
  351.                 Console.Write("Компонента " + count + ": { ");
  352.                 for (int a = 0; a < kompon.Length; a++)
  353.                     if (kompon[a] != 0) Console.Write(kompon[a] + " ");
  354.                 Console.Write("}");
  355.                 Console.WriteLine();                    
  356.                
  357.                 check++;
  358.                 for (int a = 0; a < kompon.Length; a++)
  359.                     kompon[a] = 0;
  360.  
  361.                 int t = 0;
  362.                 for (int a = 0; a < prov.Length; a++)
  363.                     if (prov[a]) t++;
  364.                 if (t == n) break;                
  365.             }
  366.             Console.WriteLine("Количество компонент связности: " + count + '\n');            
  367.         }
  368.  
  369.  
  370.         static void Main(string[] args)
  371.         {
  372.             int check = 0; // номер пункта меню
  373.             do
  374.             {
  375.                 PrintMenu();
  376.                 check = ReadIntNumber("", 1, 4); // 4 пункта меню
  377.                 switch (check)
  378.                 {
  379.                     case 1:
  380.                         algShimbella();
  381.                         break;
  382.                     case 2:
  383.                         click();
  384.                         break;
  385.                     case 3:
  386.                         component();
  387.                         break;
  388.                 }
  389.             } while (check < 4);
  390.         }
  391.     }
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement