Slavik9510

Untitled

Apr 30th, 2023
941
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 15.44 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data.Common;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace DO_Lab5
  10. {
  11.     struct Consumer
  12.     {
  13.         public int transportationCosts;
  14.         public int metNeeds;
  15.         public bool isHighlighted;
  16.     }
  17.     internal class DiffRentMethod
  18.     {
  19.         //----------------------------
  20.         private void printArr()
  21.         {
  22.             for (int i = 0; i < consumers.GetLength(0); i++)
  23.             {
  24.                 for (int j = 0; j < consumers.GetLength(1); j++)
  25.                 {
  26.                     if (consumers[i, j].metNeeds == -1)
  27.                     {
  28.                         Console.Write($"{consumers[i, j].transportationCosts}".PadRight(7));
  29.                     }
  30.                     else
  31.                     {
  32.                         Console.Write($"{consumers[i, j].transportationCosts}/{consumers[i, j].metNeeds}".PadRight(7));
  33.                     }
  34.                 }
  35.  
  36.                 if (signs[i] < 0)
  37.                 {
  38.                     Console.WriteLine($"\t-{Math.Abs(stocksBalance[i])}");
  39.                 }
  40.                 else
  41.                 {
  42.                     Console.WriteLine($"\t+{Math.Abs(stocksBalance[i])}");
  43.                 }
  44.             }
  45.             Console.WriteLine("_________________________________________________");
  46.             for (int i = 0; i < difference.Length; i++)
  47.             {
  48.                     Console.Write($"{difference[i]}".PadRight(7));
  49.             }
  50.             Console.WriteLine();
  51.             Console.WriteLine();
  52.         }
  53.         //----------------------------
  54.         private Consumer[,] consumers;
  55.         private int[,] initialPrices;
  56.         private int[] needs;
  57.         private int[] stocks;
  58.         private int[] stocksBalance;
  59.         private int[] difference;
  60.         private int[] signs;
  61.         public DiffRentMethod(string path)
  62.         {
  63.             string[] data = File.ReadAllLines(path);
  64.             stocks = new int[data.Length - 1];
  65.             stocksBalance = new int[stocks.Length];
  66.             Array.Fill(stocksBalance, int.MinValue);
  67.             needs = new int[data.Last().Split(' ').Length];
  68.             difference = new int[needs.Length];
  69.             signs = new int[stocksBalance.Length];
  70.  
  71.             consumers = new Consumer[stocks.Length, needs.Length];
  72.             initialPrices = new int[stocks.Length, needs.Length];
  73.  
  74.             for (int i = 0; i < data.Length; i++)
  75.             {
  76.                 string[] current = data[i].Split(' ');
  77.                 if (i < data.Length - 1)
  78.                 {
  79.                     for (int j = 0; j < current.Length; j++)
  80.                     {
  81.                         if (j < current.Length - 1)
  82.                         {
  83.                             consumers[i, j].transportationCosts = int.Parse(current[j]);
  84.                             initialPrices[i, j] = consumers[i, j].transportationCosts;
  85.                             consumers[i, j].metNeeds = -1;
  86.                         }
  87.                         else
  88.                         {
  89.                             stocks[i] = int.Parse(current[j]);
  90.                         }
  91.                     }
  92.                 }
  93.                 else
  94.                 {
  95.                     for (int j = 0; j < current.Length; j++)
  96.                     {
  97.                         needs[j] = int.Parse(current[j]);
  98.                     }
  99.                 }
  100.             }
  101.             if (stocks.Sum() != needs.Sum())
  102.             {
  103.                 Console.WriteLine("Задача вiдкритого типу!");
  104.                 Console.WriteLine("Потреби " + needs.Sum());
  105.                 Console.WriteLine("Запаси " + stocks.Sum());
  106.                 Environment.Exit(0);
  107.             }
  108.         }
  109.         private void findMinInColumn()
  110.         {
  111.             for (int i = 0; i < consumers.GetLength(0); i++)
  112.             {
  113.                 for (int j = 0; j < consumers.GetLength(1); j++)
  114.                 {
  115.                     consumers[i, j].isHighlighted = false;
  116.                     consumers[i, j].metNeeds = -1;
  117.                 }
  118.             }
  119.  
  120.             int row = -1, min = -1;
  121.             for (int j = 0; j < consumers.GetLength(1); j++)
  122.             {
  123.                 min = consumers[0, j].transportationCosts;
  124.                 row = 0;
  125.                 for (int i = 1; i < consumers.GetLength(0); i++)
  126.                 {
  127.                     if (consumers[i, j].transportationCosts < min)
  128.                     {
  129.                         min = consumers[i, j].transportationCosts;
  130.                         row = i;
  131.                     }
  132.                 }
  133.                 for (int i = 0; i < consumers.GetLength(0); i++)
  134.                 {
  135.                     if (consumers[i, j].transportationCosts == min)
  136.                     {
  137.                         consumers[i, j].isHighlighted = true;
  138.                     }
  139.                 }
  140.             }
  141.         }
  142.         private bool initHighlighted()
  143.         {
  144.             int[] stocksVal = (int[])stocks.Clone();
  145.             int[] needsVal = (int[])needs.Clone();
  146.             stocksBalance = (int[])stocks.Clone();
  147.  
  148.             for (int i = 0; i < consumers.GetLength(0); i++)
  149.             {
  150.                 for (int j = 0; j < consumers.GetLength(1); j++)
  151.                 {
  152.                     if (consumers[i, j].isHighlighted && consumers[i, j].metNeeds == -1)
  153.                     {
  154.                         fillCell(i, j);
  155.                     }
  156.                 }
  157.             }
  158.  
  159.             if (needs.Where(p => p == 0).Count() == needs.Length)
  160.             {
  161.                 return true;
  162.             }
  163.             stocks = stocksVal;
  164.             needs = needsVal;
  165.             return false;
  166.         }
  167.         private bool fillSingleInColumn()
  168.         {
  169.             int row = -1, column = -1, count = 0;
  170.             for (int j = 0; j < consumers.GetLength(1); j++)
  171.             {
  172.                 row = -1; column = -1; count = 0;
  173.                 for (int i = 0; i < consumers.GetLength(0); i++)
  174.                 {
  175.                     if (consumers[i, j].isHighlighted && consumers[i, j].metNeeds == -1)
  176.                     {
  177.                         row = i; column = j; count++;
  178.                     }
  179.                 }
  180.                 if (count == 1)
  181.                 {
  182.                     fillCell(row, column);
  183.                     return true;
  184.                 }
  185.             }
  186.             return false;
  187.         }
  188.         private bool fillSingleInRow()
  189.         {
  190.             int row = -1, column = -1, count = 0;
  191.             for (int i = 0; i < consumers.GetLength(0); i++)
  192.             {
  193.                 row = -1; column = -1; count = 0;
  194.                 for (int j = 0; j < consumers.GetLength(1); j++)
  195.                 {
  196.                     if (consumers[i, j].isHighlighted && consumers[i, j].metNeeds == -1)
  197.                     {
  198.                         row = i; column = j; count++;
  199.                     }
  200.                 }
  201.                 if (count == 1)
  202.                 {
  203.                     fillCell(row, column);
  204.                     return true;
  205.                 }
  206.             }
  207.             return false;
  208.         }
  209.         private void fillCell(int row, int column)
  210.         {
  211.             int valueToTransport = Math.Min(stocks[row], needs[column]);
  212.             consumers[row, column].metNeeds = valueToTransport;
  213.             stocks[row] -= valueToTransport;
  214.             needs[column] -= valueToTransport;
  215.         }
  216.         private bool isHighlightedFullyFilled()
  217.         {
  218.             foreach (Consumer consumer in consumers)
  219.             {
  220.                 if (consumer.isHighlighted && consumer.metNeeds == -1)
  221.                 {
  222.                     return false;
  223.                 }
  224.             }
  225.             return true;
  226.         }
  227.         private void CalcStockBalance()
  228.         {
  229.             List<int> skippedColumns = new List<int>();
  230.             stocksBalance = (int[])stocks.Clone();
  231.             for (int i = 0; i < consumers.GetLength(0); i++)
  232.             {
  233.                 for (int j = 0; j < consumers.GetLength(1); j++)
  234.                 {
  235.                     if (skippedColumns.Contains(j))
  236.                     {
  237.                         continue;
  238.                     }
  239.  
  240.                     if (consumers[i, j].isHighlighted)
  241.                     {
  242.                         stocksBalance[i] -= needs[j];
  243.                         skippedColumns.Add(j);
  244.                     }
  245.                 }
  246.             }
  247.         }
  248.         private void fillCheaperInColumn()
  249.         {
  250.             int row = -1, column = -1, min = int.MaxValue;
  251.             for (int i = 0; i < consumers.GetLength(0); i++)
  252.             {
  253.                 for (int j = 0; j < consumers.GetLength(1); j++)
  254.                 {
  255.                     if (consumers[i, j].isHighlighted && consumers[i, j].metNeeds == -1)
  256.                     {
  257.                         if (initialPrices[i, j] < min)
  258.                         {
  259.                             min = initialPrices[i, j];
  260.                             row = i;
  261.                             column = j;
  262.                         }
  263.                     }
  264.                 }
  265.                 if (row != -1)
  266.                 {
  267.                     fillCell(row, column);
  268.                     return;
  269.                 }
  270.             }
  271.         }
  272.         private bool fillHighlighted()
  273.         {
  274.  
  275.             if (stocksBalance[0] == int.MinValue)
  276.             {
  277.                 bool result = initHighlighted();
  278.                 CalcStockBalance();
  279.                 return result;
  280.             }
  281.  
  282.             int[] stocksVal = (int[])stocks.Clone();
  283.             int[] needsVal = (int[])needs.Clone();
  284.             stocksBalance = (int[])stocks.Clone();
  285.  
  286.             bool isFilled = false;
  287.             while (!isFilled)
  288.             {
  289.                 bool fCol = fillSingleInColumn();
  290.                 bool fRow = fillSingleInRow();
  291.                 if (fCol == false && fRow == false)
  292.                 {
  293.                     fillCheaperInColumn();
  294.                 }
  295.                 isFilled = isHighlightedFullyFilled();
  296.             }
  297.             CalcStockBalance();
  298.  
  299.             if (stocksBalance.Where(p => p == 0).Count() == stocksBalance.Length)
  300.             {
  301.                 return true;
  302.             }
  303.  
  304.             stocks = stocksVal;
  305.             needs = needsVal;
  306.             return false;
  307.         }
  308.         private int calcSign(int row)
  309.         {
  310.             if (stocksBalance[row] > 0)
  311.             {
  312.                 return 1;
  313.             }
  314.             else if (stocksBalance[row] < 0)
  315.             {
  316.                 return -1;
  317.             }
  318.             else
  319.             {
  320.  
  321.                 List<int> highlighted = new List<int>();
  322.                 for (int j = 0; j < consumers.GetLength(1); j++)
  323.                 {
  324.                     if (consumers[row, j].isHighlighted)
  325.                     {
  326.                         highlighted.Add(j);
  327.                     }
  328.                 }
  329.                 for (int j = 0; j < highlighted.Count; j++)
  330.                 {
  331.                     List<int> highlightedInColumn = new List<int>();
  332.                     int column = highlighted[j];
  333.                     for (int i = 0; i < consumers.GetLength(0); i++)
  334.                     {
  335.                         if (i == row) continue;
  336.                         if (consumers[i, column].isHighlighted)
  337.                         {
  338.                             highlightedInColumn.Add(i);
  339.                         }
  340.                     }
  341.                     if (highlightedInColumn.Count != 0)
  342.                     {
  343.                         bool hasNegative = false;
  344.                         foreach (int current in highlightedInColumn)
  345.                         {
  346.                             if (stocksBalance[current] < 0)
  347.                             {
  348.                                 hasNegative = true;
  349.                                 break;
  350.                             }
  351.                         }
  352.                         if (hasNegative)
  353.                         {
  354.                             return -1;
  355.                         }
  356.                         else return 1;
  357.                     }
  358.                 }
  359.                 return -1;
  360.             }
  361.         }
  362.         private List<int> getHighlightedInColumnIndicies(int column)
  363.         {
  364.             List<int> highlighted = new List<int>();
  365.             for (int i = 0; i < consumers.GetLength(0); i++)
  366.             {
  367.                 if (consumers[i, column].isHighlighted)
  368.                 {
  369.                     highlighted.Add(i);
  370.                 }
  371.             }
  372.             return highlighted;
  373.         }
  374.         private int getDifRent()
  375.         {
  376.             Array.Fill(difference, 0);
  377.             for (int i = 0; i < stocksBalance.Length; i++)
  378.             {
  379.                 signs[i] = calcSign(i);
  380.             }
  381.             for (int j = 0; j < consumers.GetLength(1); j++)
  382.             {
  383.                 List<int> highlightedInRow = getHighlightedInColumnIndicies(j);
  384.                 foreach (int highlighted in highlightedInRow)
  385.                 {
  386.                     if (signs[highlighted] > 0)
  387.                     {
  388.                         difference[j] = -1;
  389.                         break;
  390.                     }
  391.                 }
  392.                 if (difference[j] == -1)
  393.                 {
  394.                     continue;
  395.                 }
  396.                 int minDif = int.MaxValue;
  397.                 int highlightedVal = consumers[highlightedInRow[0], j].transportationCosts;
  398.                 for (int i = 0; i < consumers.GetLength(0); i++)
  399.                 {
  400.                     if (highlightedInRow.Contains(i) || signs[i] == -1)
  401.                     {
  402.                         continue;
  403.                     }
  404.                     if (consumers[i, j].transportationCosts - highlightedVal < minDif)
  405.                     {
  406.                         minDif = consumers[i, j].transportationCosts - highlightedVal;
  407.                     }
  408.                 }
  409.                 difference[j] = minDif;
  410.             }
  411.             return difference.Where(i => i > 0).Min();
  412.         }
  413.         private void addRent(int rent)
  414.         {
  415.             for (int i = 0; i < consumers.GetLength(0); i++)
  416.             {
  417.                 if (signs[i] < 0)
  418.                 {
  419.                     for (int j = 0; j < consumers.GetLength(1); j++)
  420.                     {
  421.                         consumers[i, j].transportationCosts += rent;
  422.                     }
  423.                 }
  424.             }
  425.         }
  426.         public void Solve()
  427.         {
  428.             bool isSolved = false;
  429.             while (!isSolved)
  430.             {
  431.                 findMinInColumn();
  432.                 isSolved = fillHighlighted();
  433.                 if (isSolved)
  434.                 {
  435.                     printArr();
  436.                     break;
  437.                 }
  438.                 int diffRent = getDifRent();
  439.                 printArr();
  440.                 addRent(diffRent);
  441.             }
  442.             Console.WriteLine("SOLVED");
  443.             int sum = 0;
  444.             for (int i = 0; i < initialPrices.GetLength(0); i++)
  445.             {
  446.                 for (int j = 0; j < initialPrices.GetLength(1); j++)
  447.                 {
  448.                     if (consumers[i, j].isHighlighted)
  449.                     {
  450.                         sum += initialPrices[i, j] * consumers[i, j].metNeeds;
  451.                     }
  452.                 }
  453.             }
  454.             Console.WriteLine($"Sum = {sum}");
  455.         }
  456.     }
  457. }
  458.  
Advertisement
Add Comment
Please, Sign In to add comment