예제 #1
0
        public static void RunAlgorithm(MnMatrix graph, int[] copulationVerticesX, int[] copulationVerticesY)
        {
            double min = graph.ToColumnWiseArray().Min();

            if (min < 0)
            {
                for (int i = 0; i < graph.ColumnCount; i++)
                {
                    for (int j = 0; j < graph.RowCount; j++)
                    {
                        graph[j, i] = graph[j, i] - i + 1;
                    }
                }
            }

            int limit = 0;

            if (copulationVerticesX.Length > copulationVerticesY.Length)
            {
                limit = copulationVerticesX.Length - copulationVerticesY.Length;
            }

            double[] verticesXLabel = new double[copulationVerticesX.Length];
            double[] verticesYLabel = new double[copulationVerticesY.Length];

            Initialize(graph, verticesXLabel, verticesYLabel);

            while (true)
            {
                for (int i = 0; i < copulationVerticesX.Length; i++)
                {
                    copulationVerticesX[i] = -1;
                }

                for (int i = 0; i < copulationVerticesY.Length; i++)
                {
                    copulationVerticesY[i] = -1;
                }

                DenseMatrix equalityGraph = CreateEqualityGraph(graph, verticesXLabel, verticesYLabel);

                int[,] vertices;
                HungarianAlgorithm.RunAlgorithm(equalityGraph, copulationVerticesX, copulationVerticesY, out vertices);

                if (CountCopulation(copulationVerticesX) == limit)
                {
                    return;
                }

                //if (CountCopulation(copulationVerticesY) == 0)
                //{
                //    return;
                //}

                var F1UF2 = new List <int>();
                var L2    = new List <int>();
                var L1UL3 = new List <int>();

                for (int i = 0; i < copulationVerticesX.Length; i++)
                {
                    if (vertices[0, i] == 0)
                    {
                        F1UF2.Add(i);
                    }
                }


                for (int i = 0; i < copulationVerticesY.Length; i++)
                {
                    if (vertices[1, i] == 0)
                    {
                        L2.Add(i);
                    }
                    else
                    {
                        L1UL3.Add(i);
                    }
                }

                double minDelta = _maximumEdge + 1;
                foreach (var i in F1UF2)
                {
                    foreach (var j in L1UL3)
                    {
                        //                       if (graph[i, j] == -1) continue;
                        double delta = verticesXLabel[i] + verticesYLabel[j] - graph.At(i, j);
                        if (delta < minDelta)
                        {
                            minDelta = delta;
                        }
                    }
                }

                foreach (var i in F1UF2)
                {
                    verticesXLabel[i] -= minDelta;
                }

                foreach (var i in L2)
                {
                    verticesYLabel[i] += minDelta;
                }
            }
        }