Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="costs"></param>
        /// <param name="rowsCovered"></param>
        /// <param name="colsCovered"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <returns></returns>
        internal static int RunStep4(int[,] costs, bool[] rowsCovered, bool[] colsCovered, int w, int h)
        {
            if (costs == null)
            {
                throw new ArgumentNullException(nameof(costs));
            }

            if (rowsCovered == null)
            {
                throw new ArgumentNullException(nameof(rowsCovered));
            }

            if (colsCovered == null)
            {
                throw new ArgumentNullException(nameof(colsCovered));
            }

            var minValue = HungarianAlgorithm.FindMinimum(costs, rowsCovered, colsCovered, w, h);

            for (var i = 0; i < h; i++)
            {
                for (var j = 0; j < w; j++)
                {
                    if (rowsCovered[i])
                    {
                        costs[i, j] += minValue;
                    }
                    if (!colsCovered[j])
                    {
                        costs[i, j] -= minValue;
                    }
                }
            }
            return(2);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="costs"></param>
        /// <param name="masks"></param>
        /// <param name="rowsCovered"></param>
        /// <param name="colsCovered"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <param name="pathStart"></param>
        /// <returns></returns>
        internal static int RunStep2(int[,] costs, byte[,] masks, bool[] rowsCovered, bool[] colsCovered, int w, int h, ref Location pathStart)
        {
            if (costs == null)
            {
                throw new ArgumentNullException(nameof(costs));
            }

            if (masks == null)
            {
                throw new ArgumentNullException(nameof(masks));
            }

            if (rowsCovered == null)
            {
                throw new ArgumentNullException(nameof(rowsCovered));
            }

            if (colsCovered == null)
            {
                throw new ArgumentNullException(nameof(colsCovered));
            }

            while (true)
            {
                var loc = HungarianAlgorithm.FindZero(costs, rowsCovered, colsCovered, w, h);
                if (loc.row == -1)
                {
                    return(4);
                }

                masks[loc.row, loc.column] = 2;

                var starCol = HungarianAlgorithm.FindStarInRow(masks, w, loc.row);
                if (starCol != -1)
                {
                    rowsCovered[loc.row] = true;
                    colsCovered[starCol] = false;
                }
                else
                {
                    pathStart = loc;
                    return(3);
                }
            }
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="masks"></param>
        /// <param name="rowsCovered"></param>
        /// <param name="colsCovered"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <param name="path"></param>
        /// <param name="pathStart"></param>
        /// <returns></returns>
        internal static int RunStep3(byte[,] masks, bool[] rowsCovered, bool[] colsCovered, int w, int h, Location[] path, Location pathStart)
        {
            if (masks == null)
            {
                throw new ArgumentNullException(nameof(masks));
            }

            if (rowsCovered == null)
            {
                throw new ArgumentNullException(nameof(rowsCovered));
            }

            if (colsCovered == null)
            {
                throw new ArgumentNullException(nameof(colsCovered));
            }

            var pathIndex = 0;

            path[0] = pathStart;

            while (true)
            {
                var row = HungarianAlgorithm.FindStarInColumn(masks, h, path[pathIndex].column);
                if (row == -1)
                {
                    break;
                }

                pathIndex++;
                path[pathIndex] = new Location(row, path[pathIndex - 1].column);

                var col = HungarianAlgorithm.FindPrimeInRow(masks, w, path[pathIndex].row);

                pathIndex++;
                path[pathIndex] = new Location(path[pathIndex - 1].row, col);
            }

            ConvertPath(masks, path, pathIndex + 1);
            ClearCovers(rowsCovered, colsCovered, w, h);
            ClearPrimes(masks, w, h);

            return(1);
        }
Пример #4
0
        /// <summary>
        /// Finds the optimal assignments for a given matrix of agents and costed tasks such that the total cost is minimized.
        /// </summary>
        /// <param name="costs">A cost matrix; the element at row <em>i</em> and column <em>j</em> represents the cost of agent <em>i</em> performing task <em>j</em>.</param>
        /// <returns>A matrix of assignments; the value of element <em>i</em> is the column of the task assigned to agent <em>i</em>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="costs"/> is null.</exception>
        internal static int[] FindAssignments(this int[,] costs)
        {
            if (costs == null)
            {
                throw new ArgumentNullException(nameof(costs));
            }

            var h = costs.GetLength(0);
            var w = costs.GetLength(1);

            for (var i = 0; i < h; i++)
            {
                var min = int.MaxValue;

                for (var j = 0; j < w; j++)
                {
                    min = Math.Min(min, costs[i, j]);
                }

                for (var j = 0; j < w; j++)
                {
                    costs[i, j] -= min;
                }
            }

            var masks       = new byte[h, w];
            var rowsCovered = new bool[h];
            var colsCovered = new bool[w];

            for (var i = 0; i < h; i++)
            {
                for (var j = 0; j < w; j++)
                {
                    if (costs[i, j] == 0 && !rowsCovered[i] && !colsCovered[j])
                    {
                        masks[i, j]    = 1;
                        rowsCovered[i] = true;
                        colsCovered[j] = true;
                    }
                }
            }

            HungarianAlgorithm.ClearCovers(rowsCovered, colsCovered, w, h);

            var path      = new Location[w * h];
            var pathStart = default(Location);
            var step      = 1;

            while (step != -1)
            {
                switch (step)
                {
                case 1:
                    step = RunStep1(masks, colsCovered, w, h);
                    break;

                case 2:
                    step = RunStep2(costs, masks, rowsCovered, colsCovered, w, h, ref pathStart);
                    break;

                case 3:
                    step = RunStep3(masks, rowsCovered, colsCovered, w, h, path, pathStart);
                    break;

                case 4:
                    step = RunStep4(costs, rowsCovered, colsCovered, w, h);
                    break;
                }
            }

            var agentsTasks = new int[h];

            for (var i = 0; i < h; i++)
            {
                for (var j = 0; j < w; j++)
                {
                    if (masks[i, j] == 1)
                    {
                        agentsTasks[i] = j;
                        break;
                    }
                }
            }

            return(agentsTasks);
        }
Пример #5
0
        private void button1_Click(object sender, EventArgs e)
        {
            rtb_Matrix.Text = "";
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.Title = "Datoteka s popisom Radnika i poslova";
            if (dlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            int [,] matrix;
            string[] names;
            int      N   = 0;
            int      row = 0;

            string dat = dlg.FileName;

            using (StreamReader sr = File.OpenText(dat))
            {
                string line = sr.ReadLine();
                matrix = new int[line.Length - 1, line.Length - 1];
                names  = new string[line.Length - 1];
                while (line != null)
                {
                    string[] s = line.Split(',');

                    names[N] = s[0];
                    N++;

                    for (int i = 1; i < s.Length; i++)
                    {
                        matrix[row, i - 1] = int.Parse(s[i]);
                    }
                    row++;

                    line = sr.ReadLine();
                }
            }


            HungarianAlgorithm hungMethod = new HungarianAlgorithm(matrix, N);


            hungMethod.StepOne();
            int[] rez = hungMethod.results;


            for (int i = 0; i < N; i++)
            {
                rtb_Matrix.Text += names[i] + " ";
                for (int j = 0; j < N; j++)
                {
                    rtb_Matrix.Text += (string.Format("{0} ", matrix[i, j]));
                }
                rtb_Matrix.Text += "\n";
            }
            int sum = 0;

            lblIspis.Text = "Results: \n";
            for (int i = 0; i < N; i++)
            {
                sum           += rez[i];
                lblIspis.Text += names[i] + ": " + rez[i] + "$\n";
            }
            lblIspis.Text += "Total cost: " + sum.ToString() + "$";
        }