コード例 #1
0
 protected ArrowGraphBuilderBase(
     Graph <T, TActivity, TEvent> graph,
     Func <T> edgeIdGenerator,
     Func <T> nodeIdGenerator,
     Func <T, TEvent> eventGenerator)
     : base(graph, edgeIdGenerator, nodeIdGenerator, eventGenerator)
 {
     // Check Start and End nodes.
     if (StartNodes.Count() == 1)
     {
         StartNode = StartNodes.First();
     }
     else
     {
         throw new ArgumentException(Properties.Resources.ArrowGraphContainsMoreThanOneStartNode);
     }
     if (EndNodes.Count() == 1)
     {
         EndNode = EndNodes.First();
     }
     else
     {
         throw new ArgumentException(Properties.Resources.ArrowGraphContainsMoreThanOneEndNode);
     }
 }
コード例 #2
0
        public override bool TransitiveReduction()
        {
            IDictionary <T, HashSet <T> > ancestorNodesLookup = GetAncestorNodesLookup();

            if (ancestorNodesLookup is null)
            {
                return(false);
            }
            foreach (T endNodeId in EndNodes.Select(x => x.Id))
            {
                RemoveRedundantIncomingEdges(endNodeId, ancestorNodesLookup);
            }
            return(true);
        }
コード例 #3
0
        public override bool TransitiveReduction()
        {
            // For Arrow Graphs only dummy edges need to be reduced.
            IDictionary <T, HashSet <T> > ancestorNodesLookup = GetAncestorNodesLookup();

            if (ancestorNodesLookup is null)
            {
                return(false);
            }
            foreach (T endNodeId in EndNodes.Select(x => x.Id))
            {
                RemoveRedundantIncomingDummyEdges(endNodeId, ancestorNodesLookup);
            }
            return(true);
        }
コード例 #4
0
        public IDictionary <T, HashSet <T> > GetAncestorNodesLookup()
        {
            if (!AllDependenciesSatisfied)
            {
                return(null);
            }
            IList <CircularDependency <T> > circularDependencies = FindStrongCircularDependencies();

            if (circularDependencies.Any())
            {
                return(null);
            }
            var nodeIdAncestorLookup = new Dictionary <T, HashSet <T> >();

            foreach (T endNodeId in EndNodes.Select(x => x.Id))
            {
                HashSet <T> totalAncestorNodes = GetAncestorNodes(endNodeId, nodeIdAncestorLookup);
                nodeIdAncestorLookup.Add(endNodeId, totalAncestorNodes);
            }
            return(nodeIdAncestorLookup);
        }
コード例 #5
0
 public VertexGraphBuilder(
     Graph <T, IEvent <T>, TActivity> graph,
     Func <T> edgeIdGenerator,
     Func <T> nodeIdGenerator)
     : base(
         graph,
         edgeIdGenerator,
         nodeIdGenerator,
         s_EventGenerator)
 {
     if (NormalNodes.Any())
     {
         // Check Start and End nodes.
         if (!StartNodes.Any())
         {
             throw new ArgumentException(Properties.Resources.VertexGraphCannotContainNormalNodesWithoutAnyStartNodes);
         }
         if (!EndNodes.Any())
         {
             throw new ArgumentException(Properties.Resources.VertexGraphCannotContainNormalNodesWithoutAnyEndNodes);
         }
     }
 }
コード例 #6
0
        /// <summary>
        /// スタートからゴールたちまでの最善経路を計算する
        /// </summary>
        /// <param name="team"></param>
        /// <param name="point"></param>
        /// <param name="Cost"></param>
        /// <param name="HeuristicCost">推定コスト</param>
        /// <param name="directionMode">false:4方位   true:8方位</param>
        public void Search(Func <Node, double> Cost, Func <Node, double> HeuristicCost)
        {
            Point p = new Point(StartNode.Point);

            Node child, parent;

            //ノードの大きさ
            int Height = Nodes.GetLength(0);
            int Width  = Nodes.GetLength(1);

            //初期設定
            //Nodesのノードに自分がいる座標を保持させる
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    Nodes[j, i].Point = new Point(i, j);
                }
            }


            //スタートノードに関する設定
            StartNode.Status = NodeStatus.Open;
            //コストを0に
            StartNode.Cost = 0;
            //推定コスト算出
            StartNode.HeuristicCost = HeuristicCost(StartNode);
            //総コスト
            StartNode.TotalCost = StartNode.Cost + StartNode.HeuristicCost;
            //親ノードなし
            StartNode.Parent = null;
            //初手なのでカウントは0
            StartNode.Turn = 0;
            //初手なので必ず成功とする
            StartNode.SuccessProbability = 1;


            //未探索ノード保持(コストが昇順でソートされるようにする)
            List <Node> openedNode = new List <Node>();

            parent = StartNode;
            //エンドノードに到達するまで無限ループ
            while (EndNodes.All((node) => node != parent))
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        //周りのセルの場所を取得
                        p = new Point(parent.Point.X + i, parent.Point.Y + j);

                        //pが配列を溢れないか
                        if (!(p.X < 0 || p.Y < 0 || p.X >= Width || p.Y >= Height) && !(i == 0 && j == 0))
                        {
                            child = Nodes[p.Y, p.X];
                            //周りのセルの状態が未探索である場合(周りのセルがゴール地点である場合もある)
                            if (child.Status == NodeStatus.None)
                            {
                                //子ノードをOpenに
                                child.Status = NodeStatus.Open;
                                //親ノードの指定
                                child.Parent = parent;

                                //いま何ターン目かを設定
                                child.Turn = parent.Turn + 1;

                                //そのセルの実コストと推定コスト、総コストを計算
                                child.Cost          = Cost(child) + parent.Cost;
                                child.HeuristicCost = HeuristicCost(child);
                                child.TotalCost     = child.Cost + child.HeuristicCost;

                                //childよりコストが高くなる位置を取得
                                var index = openedNode.FindIndex((node) => child.TotalCost < node.TotalCost);

                                //コストで昇順にソート
                                if (index < 0) //自分よりコストが高くなるノードがない->一番うしろにノードを挿入
                                {
                                    openedNode.Insert(openedNode.Count, child);
                                }
                                else
                                {
                                    openedNode.Insert(index, child);
                                }
                            }
                        }
                    }
                }

                //親ノードの状態をClosedに
                parent.Status = NodeStatus.Closed;

                //最もコストが低いノードを取り出して次の親ノードとする
                if (openedNode.Any())
                {
                    parent = openedNode.First();
                }
                else
                {   //ノードがない場合==移動ができない場合なので、諦める
                    break;
                }
                //取り出したノードをリストから消去する
                openedNode.RemoveAt(0);
            }

            //parentを辿って、最善経路を取得
            BestWayNodes = new List <Node>();
            //スタートのセルまで続行
            while (parent != StartNode)
            {
                //先頭にノードを追加
                BestWayNodes.Insert(0, parent);
                //parentの親ノードに移動
                parent = parent.Parent;
            }
            //方向のみを取り出す
            BestWayPoints = BestWayNodes.Select((node) => node.Point).ToList();
        }