コード例 #1
0
        /// <summary>
        /// Reduce a profit matrix by eliminating and forcing certain edges.
        /// </summary>
        /// <param name="full">Original complete profit. Its default value
        /// must be -Inf for the output to be valid (although it is possible
        /// to extend it to non-inf matrices, it becomes inefficient, so won't be done).</param>
        /// <param name="reducer">Descriptor of the changes that should be done.</param>
        private static SparseMatrix reduceprofit(SparseMatrix full, MurtyNode reducer)
        {
            SparseMatrix reduced = new SparseMatrix(full, double.NegativeInfinity);

            int[] removerows = new int[reducer.Forced.Length];
            int[] removecols = new int[reducer.Forced.Length];

            int h = 0;

            foreach (MatrixKey force in reducer.Forced)
            {
                removerows[h] = force.I;
                removecols[h] = force.K;

                h++;
            }

            reduced.RemoveRows(removerows);
            reduced.RemoveColumns(removecols);

            foreach (MatrixKey force in reducer.Forced)
            {
                reduced[force.I, force.K] = 1;
                // always bigger than the removed edges, hence will always be picked
            }

            foreach (MatrixKey eliminate in reducer.Eliminated)
            {
                reduced.RemoveAt(eliminate.I, eliminate.K);
                //reduced[eliminate.I, eliminate.K] = double.NegativeInfinity;
            }

            return(reduced);
        }
コード例 #2
0
        /// <summary>
        /// Efficient equality comparer with other MurtyNode.
        /// </summary>
        /// <param name="that">Compared node.</param>
        /// <returns>True if both nodes are structurally identical.
        /// This implies having the same field values and the same defined order for each field.</returns>
        public bool Equals(MurtyNode that)
        {
            if (this.Eliminated.Length != that.Eliminated.Length || this.Forced.Length != that.Forced.Length)
            {
                return(false);
            }

            for (int i = 0; i < this.Eliminated.Length; i++)
            {
                if (this.Eliminated[i] != that.Eliminated[i])
                {
                    return(false);
                }
            }

            for (int i = 0; i < this.Forced.Length; i++)
            {
                if (this.Forced[i] != that.Forced[i])
                {
                    return(false);
                }
            }

            if (this.Assignment == null)
            {
                return(that.Assignment == null);
            }
            else
            {
                if (that.Assignment == null)
                {
                    return(false);
                }

                for (int i = 0; i < this.Assignment.Length; i++)
                {
                    if (this.Assignment[i] != that.Assignment[i])
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Enumerate all possible pairings using a Murty's algorithm.
        /// </summary>
        /// <param name="profit">Profit matrix to be maximized.</param>
        /// <returns>Enumeration of most likely assignments pairing permutations (and their profit assignments).</returns>
        public static IEnumerable <Tuple <int[], double> > MurtyPairing(SparseMatrix profit)
        {
            var       frontier = new PriorityQueue <MurtyNode>();
            MurtyNode first    = new MurtyNode();

            first.Assignment = LinearAssignment(profit);

            //Console.WriteLine(profit.ToStringFull());

            frontier.Add(AssignmentValue(profit, first.Assignment), first);

            while (frontier.Count > 0)
            {
                //Console.WriteLine(frontier.Count);
                double    value;
                MurtyNode best = frontier.Pop(out value);
                //Console.WriteLine(frontier.Count);
                //Console.WriteLine(best);

                yield return(Tuple.Create(best.Assignment, value));

                //Console.WriteLine("children___");
                foreach (MurtyNode child in best.Children)
                {
                    child.Assignment = LinearAssignment(reduceprofit(profit, child));
                    //Console.WriteLine(child);
                    //Console.WriteLine(reduceprofit(profit, child).ToStringFull());
                    //Console.WriteLine(AssignmentValue(reduceprofit(profit, child), child.Assignment));

                    if (child.Assignment != null)
                    {
                        frontier.Add(AssignmentValue(profit, child.Assignment), child);
                    }
                }
            }
        }