123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.IO;
- namespace MinElKuzminEkz
- {
- internal class Program
- {
- private static StreamWriter traceWriter;
- private static StreamWriter debugWriter;
- public static void Main(string[] args)
- {
- try
- {
- // Открываем файлы для записи trace и debug логов
- traceWriter = new StreamWriter("trace_log.txt");
- debugWriter = new StreamWriter("debug_log.txt");
- // Добавляем слушателя для Trace
- Trace.Listeners.Add(new TextWriterTraceListener(traceWriter));
- Trace.AutoFlush = true;
- // Добавляем слушателя для Debug
- Debug.Listeners.Add(new TextWriterTraceListener(debugWriter));
- Debug.AutoFlush = true;
- Trace.WriteLine("Файл успешно считан");
- // Чтение данных из файла
- string[] lines = File.ReadAllLines("C:\\Users\\7\\source\\repos\\methodMinimalElKuzmin\\methodMinimalElKuzmin\\test.txt");
- // Инициализация массивов на основе данных из файла
- int[] a = Array.ConvertAll(lines[0].Split(','), int.Parse);
- int[] b = Array.ConvertAll(lines[1].Split(','), int.Parse);
- double[,] costs = new double[3, 3];
- // Заполнение матриц costs и supply_plan
- int index = 2; // начинаем с третьей строки файла
- for (int i = 0; i < 3; i++)
- {
- string[] costValues = lines[index].Split(',');
- for (int j = 0; j < 3; j++)
- {
- costs[i, j] = double.Parse(costValues[j]);
- }
- index++;
- }
- Trace.WriteLine("Матрица инициализирована");
- if (Utility.CheckClosure(a, b))
- {
- Console.WriteLine("Транспортная задача является закрытой");
- }
- else
- {
- Console.WriteLine("Транспортная задача является открытой");
- }
- // Применение метода
- int[,] supply_plan = Utility.MinElementMethod(a, b, costs); //MinElementMethod
- // Вывод плана поставок
- for (int i = 0; i < supply_plan.GetLength(0); i++)
- {
- for (int j = 0; j < supply_plan.GetLength(1); j++)
- {
- Console.Write($"{supply_plan[i, j]} ");
- }
- Console.WriteLine();
- }
- // Проверка на вырожденность опорного плана
- if (Utility.CheckIfVyrozhdeno(supply_plan))
- {
- Console.WriteLine("Опорный план вырожденный.");
- }
- else
- {
- Console.WriteLine("Опорный план невырожденный.");
- }
- // Расчёт целевой функции
- Console.WriteLine($"Целевая функция: {Utility.CalculateCelevayaFunction(costs, supply_plan)}");
- Console.WriteLine("Опорный план оптимален.");
- Trace.WriteLine("Программа успешно завершила рассчет");
- }
- catch (Exception ex)
- {
- Trace.WriteLine($"Error: {ex.Message}");
- Console.WriteLine($"Error: {ex.Message}");
- }
- finally
- {
- // Закрываем файлы после использования
- traceWriter.Close();
- debugWriter.Close();
- Console.ReadKey();
- }
- }
- }
- //класс utility
- public static class Utility
- {
- public static bool CheckClosure(int[] a, int[] b)
- {
- int sum_a = a.Sum();
- int sum_b = b.Sum();
- Debug.WriteLine($"Проверка на закрытость задачи: A = {sum_a}, B = {sum_b}");
- return sum_a == sum_b;
- }
- public static bool CheckIfVyrozhdeno(int[,] supply_plan)
- {
- int n = supply_plan.GetLength(0);
- int m = supply_plan.GetLength(1);
- int kolvo_polozh_komponent = 0;
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < m; j++)
- {
- if (supply_plan[i, j] > 0)
- {
- kolvo_polozh_komponent++;
- }
- }
- }
- Debug.WriteLine($"Проверка вырожденности A = {kolvo_polozh_komponent}, B = {n + m - 1}");
- return kolvo_polozh_komponent != n + m - 1;
- }
- public static double CalculateCelevayaFunction(double[,] costs, int[,] supply_plan)
- {
- double result = 0;
- for (int i = 0; i < costs.GetLength(0); i++)
- {
- for (int j = 0; j < costs.GetLength(1); j++)
- {
- if (supply_plan[i, j] > 0)
- {
- result += costs[i, j] * supply_plan[i, j];
- }
- }
- }
- Debug.WriteLine($"Рассчет целевой фунции = {result}");
- return result;
- }
- public static int[,] MinElementMethod(int[] a, int[] b, double[,] costs)
- {
- int n = a.Length;
- int m = b.Length;
- int[,] supply_plan = new int[n, m]; // матрица для опорного плана
- bool[,] bools_suply_plan = new bool[n, m];
- while (!CheckIfMatrixAllTrue(bools_suply_plan))
- {
- List<(int, int)> positions = FindMinElementPositions(costs, bools_suply_plan);
- int min_j = int.MaxValue;
- int index_of_min_j = -1;
- for (int k = 0; k < positions.Count; k++)
- {
- if (positions[k].Item2 < min_j)
- {
- min_j = positions[k].Item2;
- index_of_min_j = k;
- }
- }
- int min_i = positions.ElementAt(index_of_min_j).Item1;
- int value = Math.Min(a[min_i], b[min_j]);
- a[min_i] -= value;
- b[min_j] -= value;
- supply_plan[min_i, min_j] = value;
- bools_suply_plan[min_i, min_j] = true;
- if (a[min_i] == 0)
- {
- for (int j = 0; j < m; j++)
- {
- if (bools_suply_plan[min_i, j] == false)
- {
- bools_suply_plan[min_i, j] = true;
- }
- }
- }
- else if (b[min_j] == 0)
- {
- for (int i = 0; i < n; i++)
- {
- if (bools_suply_plan[i, min_j] == false)
- {
- bools_suply_plan[i, min_j] = true;
- }
- }
- }
- }
- Debug.WriteLine($"Метод минимального элемента : опорный план инициализирован");
- return supply_plan;
- }
- public static bool CheckIfMatrixAllTrue(bool[,] bools)
- {
- for (int i = 0; i < bools.GetLength(0); i++)
- {
- for (int j = 0; j < bools.GetLength(1); j++)
- {
- if (bools[i, j] == false)
- {
- return false;
- }
- }
- }
- return true;
- }
- public static List<(int, int)> FindMinElementPositions(double[,] costs, bool[,] bools)
- {
- List<(int, int)> positions = new List<(int, int)>();
- double min = double.MaxValue;
- for (int i = 0; i < costs.GetLength(0); i++)
- {
- for (int j = 0; j < costs.GetLength(1); j++)
- {
- if (bools[i, j] == false && costs[i, j] < min)
- {
- min = costs[i, j];
- positions.Clear();
- positions.Add((i, j));
- }
- else if (bools[i, j] == false && costs[i, j] == min)
- {
- positions.Add((i, j));
- }
- }
- }
- return positions;
- }
- }
- }
|