コード例 #1
0
 /// <summary>
 /// If neighbour has line of sight to currents parent and skipping current is cheaper, skips current node and sets neighbour cost / parent depending on whether current is used
 /// </summary>
 /// <param name="current"></param>
 /// <param name="neighbour"></param>
 /// <param name="settings"></param>
 /// <param name="openNodes"></param>
 private static void UpdateNode(Node current, Node neighbour, PathfindingSettings settings, BucketList <Node> openNodes)
 {
     if (LineOfSight(current.parent, neighbour))
     {
         var costSkippingCurrent = current.parent.cost + settings.CostIncrease(current.parent.pos, neighbour.pos);
         if (costSkippingCurrent < neighbour.cost)
         {
             if (openNodes.Contains(neighbour))
             {
                 openNodes.Remove(neighbour);
             }
             neighbour.cost   = costSkippingCurrent;
             neighbour.parent = current.parent;
             openNodes.Add(neighbour);
         }
     }
     else
     {
         var costUsingCurrent = current.cost + settings.CostIncrease(current.pos, neighbour.pos);
         if (costUsingCurrent < neighbour.cost)
         {
             if (openNodes.Contains(neighbour))
             {
                 openNodes.Remove(neighbour);
             }
             neighbour.cost   = costUsingCurrent;
             neighbour.parent = current;
             openNodes.Add(neighbour);
         }
     }
 }
コード例 #2
0
        public static void Main()
        {
            var normalList = new NormalList <int>();
            var bucketList = new BucketList <int>();

            for (int i = 0; i < 1000000; i++)
            {
                normalList.Add(i);
                bucketList.Add(i);
            }

            MeasureTime(() =>
            {
                for (int i = 0; i < 400000; i++)
                {
                    normalList.Remove(0);
                }
            }, "normal list removing");

            MeasureTime(() =>
            {
                for (int i = 0; i < 400000; i++)
                {
                    bucketList.Remove(0);
                }
            }, "bucket list removing");
        }
コード例 #3
0
 private void ActionEvent(Goods goods)
 {
     if (goods.ButtonContent == ButtonAction.Buy)
     {
         var bucketGoods = new Goods
         {
             Id            = goods.Id,
             Name          = goods.Name,
             Cost          = goods.Cost,
             Description   = goods.Description,
             Image         = goods.Image,
             ButtonContent = ButtonAction.Remove
         };
         bucketGoods.ActionEvent += () => ActionEvent(bucketGoods);
         BucketList.Add(bucketGoods);
     }
     else if (goods.ButtonContent == ButtonAction.Remove)
     {
         // ReSharper disable once EventUnsubscriptionViaAnonymousDelegate
         goods.ActionEvent -= () => ActionEvent(goods);
         BucketList.Remove(goods);
     }
 }
コード例 #4
0
        /// <summary>
        /// Tries to find a path from start to goal node using settings
        /// </summary>
        /// <param name="start">Start node</param>
        /// <param name="goal">Goal node</param>
        /// <param name="settings">PathfindingSettings (which heuristics to use etc)</param>
        /// <param name="isoLevel">Determines which nodes are considered walkable (iso value > this)</param>
        /// <param name="openNodes">Nodes that were still open after algorithm finished</param>
        /// <param name="closedNodes">Nodes that were fully explored after algorithm finished</param>
        /// <param name="maxIterations">Max number of loop iterations, prevents infinite loops</param>
        /// <param name="nodeCount">Approximate total node count, determines start capacity of path stack</param>
        /// <returns></returns>
        public static Stack <Vector3> FindPath(Node start, Node goal, PathfindingSettings settings, float isoLevel, out BucketList <Node> openNodes, out HashSet <Node> closedNodes, int maxIterations = 50000, int nodeCount = 1000)
        {
            NodesGenerator.CostHeuristicBalance = settings.greediness;
            int neighbourChecks = 0;

            int numIterations = 0;

            //euclidean distance from start to end
            float distance = Vector3.Distance(start.pos, goal.pos);

            //full length of path
            float pathLength = 0;

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            if (settings.benchmark)
            {
                sw.Start();
            }

            var             startCapacity = nodeCount / 100;
            Stack <Vector3> path          = new Stack <Vector3>(startCapacity);

            openNodes = new BucketList <Node>(distance / 100, Mathf.Min(settings.Heuristic(start.pos, goal.pos) * settings.greediness, settings.CostIncrease(start.pos, goal.pos) * (1 - settings.greediness)));
            //openNodes = new MinHeap<Node>(startCapacity * 10);

            closedNodes = new HashSet <Node>();

            Node current = null;

            start.cost      = 0;
            start.parent    = start;
            start.heuristic = settings.Heuristic(start.pos, goal.pos);
            openNodes.Add(start);
            while (openNodes.Count != 0 && !closedNodes.Contains(goal))
            {
                if (++numIterations == maxIterations)
                {
                    break;
                }

                current = openNodes.ExtractMin();

                closedNodes.Add(current);

                foreach (var neighbour in current.neighbours)
                {
                    neighbourChecks++;
                    if (neighbour.isoValue <= isoLevel)
                    {
                        continue;
                    }
                    if (closedNodes.Contains(neighbour))
                    {
                        continue;
                    }
                    var newCost = current.cost + settings.CostIncrease(current.pos, neighbour.pos);
                    if (openNodes.Contains(neighbour))
                    {
                        if (newCost >= neighbour.cost)
                        {
                            continue;
                        }
                        openNodes.Remove(neighbour);
                    }
                    neighbour.parent    = current;
                    neighbour.heuristic = settings.Heuristic(neighbour.pos, goal.pos);
                    neighbour.cost      = newCost;

                    openNodes.Add(neighbour);
                }
            }

            if (!closedNodes.Contains(goal))
            {
                Debug.Log("no goal, " + numIterations + " iterations, closed: " + closedNodes.Count + ", opened: " + openNodes.Count);
                return(path);
            }

            path.Push(goal.pos);
            Node temp = goal.parent;

            while (temp != null)
            {
                pathLength += Vector3.Distance(path.Peek(), temp.pos);
                path.Push(temp.pos);
                if (temp == start)
                {
                    break;
                }
                temp = temp.parent;
            }

            if (settings.benchmark)
            {
                sw.Stop();
                Debug.Log("A*, Heuristic: " + settings.heuristic + ", Cost increase: " + settings.costIncrease + ", Path length: " + pathLength * 100 / distance + "%, ms: " + sw.Elapsed.TotalMilliseconds + ", closed: " + closedNodes.Count + ", opened: " + openNodes.Count + ", Neighbour checks: " + neighbourChecks);
            }

            return(path);
        }
コード例 #5
0
        public override void CalculateLoss(SimulationMsg cdlMsg, bool bDebug)
        {
            if (bDebug)
            {
                cdlMsg.SendMessage(string.Format("Calculate Loss TermNode: intId={0}, begin {1}", this.m_intId, this.CalcState));
            }

            //aggregate losses from children
            for (int cIdx = 0; cIdx < this.m_vChildNode.Count; ++cIdx)
            {
                TermNode child = (TermNode)this.m_vChildNode[cIdx];
                child.CalculateLoss(cdlMsg, bDebug);

                if (bDebug)
                {
                    cdlMsg.SendMessage(string.Format("For TermNode: intId={0} initial {1}, Adding Child TermNode: intId={2}, {3}",
                                                     this.m_intId, this.m_calcState, child.IntId, child.CalcState));
                }
            }


            if (BucketList != null)
            {
                List <int> overlapBuckets = new List <int>();
                for (int b0 = 0; b0 < bucketList.Count; b0++)
                {
                    List <int> bucket = bucketList[b0];
                    for (int b1 = 0; b1 < bucket.Count - 1; b1++)
                    {
                        for (int b2 = 1; b2 < bucket.Count; b2++)
                        {
                            if (IsOverlap(bucket[b1], bucket[b2]))
                            {
                                if (!overlapBuckets.Contains(b0))
                                {
                                    overlapBuckets.Add(b0);
                                }
                            }
                        }
                    }
                }

                foreach (int ob in overlapBuckets)
                {
                    BucketList.Remove(bucketList[ob]);
                }

                int         b = 0;
                CalcState[] calcStateArray = new CalcState[BucketList.Count];

                foreach (List <int> bucket in BucketList)
                {
                    calcStateArray[b]   = new CalcState();
                    calcStateArray[b].X = 0;
                    calcStateArray[b].S = 0;
                    calcStateArray[b].D = 0;

                    foreach (int intId in bucket)
                    {
                        if (MapIntIdToNode.ContainsKey(intId))
                        {
                            TermNode  tn  = MapIntIdToNode[intId];
                            _Schedule sar = tn.Subject.Schedule;
                            foreach (RiskItem riskItem in sar.SetSchedule)
                            {
                                calcStateArray[b].X += riskItem.CalcState.X;
                                calcStateArray[b].S += riskItem.CalcState.S;
                                calcStateArray[b].D += riskItem.CalcState.D;
                            }
                        }
                        else if (MapIntIdToRit.ContainsKey(intId))
                        {
                            RiskItem ri = MapIntIdToRit[intId];
                            calcStateArray[b].X += ri.CalcState.X;
                            calcStateArray[b].S += ri.CalcState.S;
                            calcStateArray[b].D += ri.CalcState.D;
                        }
                    }

                    foreach (TermObject termObj in this.m_sortTermObj)
                    {
                        termObj.ApplyTermObject(calcStateArray[b]);
                    }

                    b++;
                }

                this.m_calcState = FindWinningBucket(calcStateArray, BucketList);
            }
            else
            {
                _Schedule sar = this.m_subject.Schedule;
                foreach (RiskItem riskItem in sar.SetSchedule)
                {
                    this.m_calcState.X += riskItem.CalcState.X;
                    this.m_calcState.S += riskItem.CalcState.S;
                    this.m_calcState.D += riskItem.CalcState.D;
                }

                //apply term objects to the term node..
                foreach (TermObject termObj in this.m_sortTermObj)
                {
                    termObj.ApplyTermObject(this.m_calcState);
                }
            }


            if (bDebug)
            {
                cdlMsg.SendMessage(string.Format("Calculate Loss TermNode: intId={0}, final {1}", this.m_intId, this.CalcState));
            }
        }