Esempio n. 1
0
 public void AddNeighbor(HungarianNode Node, double Weight, bool Bidirectional = true)
 {
     _Neighbors[((HungarianNode)Node).ID] = Weight;
     if (Bidirectional)
     {
         Node.AddNeighbor(this, Weight, false);
     }
 }
Esempio n. 2
0
 private void AddToTree(HungarianNode From, HungarianNode To)
 {
     To.Mark   = true;
     To.Parent = From;
     foreach (HungarianNode Node in _Right)
     {
         if (To.Potential + Node.Potential - To.GetWeight(Node) < Node.Slack)
         {
             Node.Slack     = To.Potential + Node.Potential - To.GetWeight(Node);
             Node.SlackNode = To;
         }
     }
 }
Esempio n. 3
0
        private void Augment(Queue <HungarianNode> Queue)
        {
            HungarianNode Root = null;

            foreach (HungarianNode Node in _Left)
            {
                if (Node.Match == null)
                {
                    Queue.Enqueue(Node);
                    Node.Parent = null;
                    Node.Mark   = true;
                    Root        = Node;
                }
            }

            foreach (HungarianNode Node in _Right)
            {
                Node.Slack     = Root.Potential + Node.Potential - Root.GetWeight(Node);
                Node.SlackNode = Root;
            }

            KeyValuePair <HungarianNode, HungarianNode> Exposed = ExposePath(Queue);

            if (Exposed.Value == null)
            {
                UpdateLabels();
                Exposed = ImproveLabeling(Queue);
            }
            if (Exposed.Value != null)
            {
                _Rounds++;
                HungarianNode CurrentRight = Exposed.Value;
                HungarianNode CurrentLeft  = Exposed.Key;
                while (CurrentLeft != null && CurrentRight != null)
                {
                    HungarianNode TempRight = CurrentLeft.Match;
                    CurrentRight.Match = CurrentLeft;
                    CurrentLeft.Match  = CurrentRight;
                    CurrentRight       = TempRight;
                    CurrentLeft        = CurrentLeft.Parent;
                }
            }
        }
Esempio n. 4
0
        public MaxCostAssignment(IEnumerable <T> Left, IEnumerable <K> Right, Func <T, K, double> DistanceFunction, Func <T, IEnumerable <K> > LeftNeighbors, Func <K, IEnumerable <T> > RightNeighbors)
        {
            int NumLeft  = Left.Count();
            int NumRight = Right.Count();

            _Left  = new HungarianNode[NumLeft];
            _Right = new HungarianNode[NumRight];

            int LeftID = 0;

            foreach (T L in Left)
            {
                HungarianNode H = new HungarianNode(L, LeftID, NumRight);
                _Left[LeftID++] = H;
                _Nodes.Add(L, H);
            }
            int RightID = 0;

            foreach (K R in Right)
            {
                HungarianNode H = new HungarianNode(R, RightID, NumLeft);
                foreach (T N in RightNeighbors(R))
                {
                    H.AddNeighbor(_Nodes[N], DistanceFunction(N, R));
                }
                _Right[RightID++] = H;
                _Nodes.Add(R, H);
            }
            foreach (T L in Left)
            {
                foreach (K N in LeftNeighbors(L))
                {
                    _Nodes[L].AddNeighbor(_Nodes[N], DistanceFunction(L, N));
                }
            }

            Assign();
        }
Esempio n. 5
0
 private KeyValuePair <HungarianNode, HungarianNode> ExposePath(Queue <HungarianNode> Queue)
 {
     while (Queue.Count > 0)
     {
         HungarianNode Current = Queue.Dequeue();
         foreach (HungarianNode Node in _Right)
         {
             if (Math.Abs(Current.GetWeight(Node) - Current.Potential - Node.Potential) < _EPSILON && !Node.Mark)
             {
                 if (Node.Match == null)
                 {
                     return(new KeyValuePair <HungarianNode, HungarianNode>(Current, Node));
                 }
                 else
                 {
                     Node.Mark = true;
                     Queue.Enqueue(Node);
                     AddToTree(Node, Current);
                 }
             }
         }
     }
     return(new KeyValuePair <HungarianNode, HungarianNode>(null, null));
 }
Esempio n. 6
0
 public double GetWeight(HungarianNode Node)
 {
     return(_Neighbors[Node.ID]);
 }