//--------------------------- UpdateGraphFromBrush ---------------------------- // // given a brush and a node index, this method updates the graph appropriately // (by removing/adding nodes or changing the costs of the node's edges) //----------------------------------------------------------------------------- public void UpdateGraphFromBrush(int brush, int CellIndex) { //set the terrain type in the terrain index m_TerrainType[CellIndex] = brush; //if current brush is an obstacle then this node must be removed //from the graph if (brush == (int)brush_type.obstacle) { m_Graph.RemoveNode(CellIndex); } else { //make the node active again if it is currently inactive if (!m_Graph.isNodePresent(CellIndex)) { int y = CellIndex / m_iCellsY; int x = CellIndex - (y * m_iCellsY); m_Graph.AddNode(new NavGraphNode(CellIndex, new Vector2D(x * m_dCellWidth + m_dCellWidth / 2.0, y * m_dCellHeight + m_dCellHeight / 2.0))); SparseGraph.Helper_AddAllNeighboursToGridNode(m_Graph, y, x, m_iCellsX, m_iCellsY); } //set the edge costs in the graph SparseGraph.Helper_WeightNavGraphNodeEdges(m_Graph, CellIndex, GetTerrainCost((brush_type)brush)); } }
public override void Create() { Graph = new SparseGraph(false); for (int i = 0; i < World.Instance.Waypoints.Count; i++) { var node = new Node(i) { Position = new Vector2(World.Instance.Waypoints[i].x, World.Instance.Waypoints[i].z) }; Graph.AddNode(node); //AddNodeObject(node, node.Position); } for (int fromIndex = 0; fromIndex < Graph.NumNodes; fromIndex++) { Node fromNode = Graph.GetNode(fromIndex); for (int toIndex = 0; toIndex < Graph.NumNodes; toIndex++) { Node toNode = Graph.GetNode(toIndex); if (IsPathObstructed(fromNode.Position, toNode.Position)) { continue; } var edge = new Edge( fromIndex, toIndex, (fromNode.Position - toNode.Position).magnitude); Graph.AddEdge(edge); //AddEdgeObject(edge, fromNode.Position, toNode.Position); } } }
public BaseGraphSearchAlgo(SparseGraph graph, int source, int target) { m_Graph = graph; m_iSource = source; m_iTarget = target; m_bFound = false; }
public void Init(SparseGraph graph, int source, int target) { this.Clear(); m_Graph = graph; m_iSource = source; m_iTarget = target; m_bFound = false; m_Visited.Capacity = m_Graph.NumNodes(); m_Route.Capacity = m_Graph.NumNodes(); for (int i = 0; i < m_Graph.NumNodes(); i++) { //Debug.Log(m_Graph.NumNodes() + " : " + i); //chamto test m_Visited.Add((int)Aid.unvisited); m_Route.Add((int)Aid.no_parent_assigned); //m_Visited[i] = (int)Aid.unvisited; //m_Route[i] = (int)Aid.no_parent_assigned; } m_bFound = Search(); }
public void ResetGraph() { Graph = new SparseGraph <UnityNode, UnityEdge>(false); VisitedNodes = new List <UnityNode>(); Width = TileWidth * NumTilesX; Height = TileHeight * NumTilesY; float MidX = TileWidth / 2; float MidY = TileHeight / 2; for (int Row = 0; Row < NumTilesY; ++Row) { for (int Col = 0; Col < NumTilesX; ++Col) { var NodeIndex = Graph.AddNode(new UnityNode(Graph.GetNextFreeNodeIndex(), new Vector3(MidX + (Col * TileWidth), 0, MidY + (Row * TileWidth)))); Graph.Edges.Insert(NodeIndex, new List <UnityEdge>()); } } for (int Row = 0; Row < NumTilesY; ++Row) { for (int Col = 0; Col < NumTilesX; ++Col) { AddAllNeighborsToGridNode(Row, Col, NumTilesX, NumTilesY); } } }
public void OnAfterDeserialize() { if (SerializedGraph == null) { return; } var StopWatch = new System.Diagnostics.Stopwatch(); StopWatch.Start(); BinaryFormatter bf = new BinaryFormatter(); using (MemoryStream ms = new MemoryStream(SerializedGraph)) { Graph = (SparseGraph <UnityNode, UnityEdge>)bf.Deserialize(ms); foreach (var Node in Graph.Nodes) { Node.OnAfterDeserialize(); } } StopWatch.Stop(); // Debug.Log("OnAfterDeserialize: " + StopWatch.Elapsed); }
public void CreateGraph() { mNavGraph = new SparseGraph<NavGraphNode, GraphEdge> (mRow * mColumn); mNavGraph.BDrawMap = mBDrawMap; Vector3 nodeposition = new Vector3 (); int nextindex = 0; //SparseGraph nodes data for (int rw = 0; rw < mRow; rw++) { for (int col = 0; col < mColumn; col++) { nodeposition = new Vector3 (rw, 0.0f, col); nextindex = mNavGraph.NextFreeNodeIndex; mNavGraph.AddNode (new NavGraphNode (nextindex, nodeposition, 0.0f, false)); } } //SparseGraph edges data for (int rw = 0; rw < mRow; rw++) { for (int col = 0; col < mColumn; col++) { CreateAllNeighboursToGridNode(rw, col, mRow, mColumn); } } mTotalNodes = mNavGraph.NumNodes(); mTotalEdges = mNavGraph.NumEdges (); }
public void InitialiseGraph(int CellsUp, int CellsAcross, int pWidth, int pHeight) { m_iCellsX = CellsAcross; m_iCellsY = CellsUp; m_icxClient = pWidth; m_icyClient = pHeight; //initialize the terrain vector with normal terrain int numNodes = CellsUp * CellsAcross; m_TerrainType = new List <int>(numNodes); for (int i = 0; i < numNodes; i++) { m_TerrainType.Add((int)brush_type.normal); } m_Path = new List <int>(); m_SubTree = new List <NavGraphEdge>(); m_dCellWidth = (double)m_icxClient / (double)CellsAcross; m_dCellHeight = (double)m_icyClient / (double)CellsUp; //create the graph m_Graph = new SparseGraph(false);//not a digraph SparseGraph.Helper_CreateGrid(m_Graph, m_icxClient, m_icyClient, CellsUp, CellsAcross); m_CurrentAlgorithm = algorithm_type.none; m_dTimeTaken = 0; }
public PathSearchResult(SparseGraph <TNode, TEdge> graph, int fromId) { Graph = graph; From = graph[fromId]; Distance = new TVal[Graph.NodesCnt]; Ancestors = new TEdge[Graph.NodesCnt]; HasNegativeCycle = null; }
public void ComponentTest() { string fileName = @"Graph\testG1.txt"; var g1 = new SparseGraph <double>(13, false); var gr1 = new ReadGraph <double>(g1, fileName); var component1 = new Component <double>(g1); Console.WriteLine(component1.Count()); }
public GraphSearch(SparseGraph mGraph, Dictionary <int, NodeVisitType> mVisitedNodes, Dictionary <int, int> mRoute, int sourceNodeIndex, int targetNodeIndex) { m_graph = mGraph; m_visitedNodes = mVisitedNodes; m_route = mRoute; this.sourceNodeIndex = sourceNodeIndex; this.targetNodeIndex = targetNodeIndex; this.isFound = DFSSearch(); }
public double Calculate(SparseGraph <UnityNode, UnityEdge> Graph, int Node1, int Node2) { var UnityNode1 = Graph.GetNode(Node1); var UnityNode2 = Graph.GetNode(Node2); var Pos1 = UnityNode1.Position; var Pos2 = UnityNode2.Position; return(Vector3.Distance(Pos1, Pos2)); }
private GraphEdge[] ParentEdges; // Stores the edge leading to each node. Used for distance and to track parent node connections. #endregion Fields #region Constructors public AStarPlanner(SparseGraph graph) { this.Graph = graph; OpenList = new List<GraphNode>(); ClosedList = new List<GraphNode>(); int allNodesCount = graph.GetAllNodesCount(); FCosts = new double[allNodesCount]; GCosts = new double[allNodesCount]; ParentEdges = new GraphEdge[allNodesCount]; }
public void ShortestPathTest() { string fileName = @"Graph\testG2.txt"; var g1 = new SparseGraph <double>(7, false); var gr1 = new ReadGraph <double>(g1, fileName); g1.Show(); var path = new ShortestPath <double>(g1, 0); Console.WriteLine("BFS: "); path.ShowPath(6); }
public void ReadGraphTest() { string fileName = @"Graph\testG1.txt"; var g1 = new SparseGraph <double>(13, false); var rg1 = new ReadGraph <double>(g1, fileName); g1.Show(); var g2 = new DenseGraph <double>(13, false); var rg2 = new ReadGraph <double>(g2, fileName); g2.Show(); }
private void CreateGraph() { graph = new SparseGraph(false); var objects = FindObjectsOfType <ObjectNode>().OrderBy(x => x.index).ToArray(); foreach (var o in objects) { graph.AddNode(new GraphNode(o.index)); } foreach (var o in objects) { foreach (var n in o.Connects) { graph.AddEdge(new GraphEdge(o.index, n.index, Vector2.Distance(o.transform.position, n.transform.position))); } } }
public Graph_SearchDFS(SparseGraph graph, int source, int target) : base(graph, source, target) { int numNodes = m_Graph.NumNodes(); m_Visited = new List<int>(numNodes); m_Route = new List<int>(numNodes); for (int i = 0; i < numNodes; i++) { m_Visited.Add((int)NodeState.unvisited); m_Route.Add((int)NodeState.no_parent_assigned); } m_SpanningTree = new List<NavGraphEdge>(); m_bFound = Search(); }
public SparseGraph <GraphNode, GraphEdge> GetMST() { // essentially, make a new graph with the spanning tree list SparseGraph <GraphNode, GraphEdge> g = new SparseGraph <GraphNode, GraphEdge>(); foreach (GraphNode n in graph.Nodes) { g.AddNode(new GraphNode(g.nextNodeIndex)); } //add all the edges from the other spanning tree foreach (GraphEdge e in spanningTree) { g.AddDoubleEdge(new GraphEdge(e.from, e.to, e.cost)); } return(g); }
public SearchAStar(SparseGraph<NavGraphNode, GraphEdge> graph , int source , int target , bool isignorewall , float strickdistance , float hcostpercentage , bool drawexplorepath , float explorepathremaintime) { mGraph = graph; mPQ = new PriorityQueue<int, float>((int)Mathf.Sqrt(mGraph.NumNodes())); mGCosts = new List<float>(graph.NumNodes()); mFCosts = new List<Pair<int, float>>(graph.NumNodes()); mShortestPathTree = new List<GraphEdge>(graph.NumNodes()); mSearchFrontier = new List<GraphEdge>(graph.NumNodes()); //Init G cost and F cost and Cost value for (int i = 0; i < graph.NumNodes(); i++) { mGCosts.Add(0.0f); mFCosts.Add(new Pair<int, float>(i, 0.0f)); mShortestPathTree.Add(new GraphEdge()); mSearchFrontier.Add(new GraphEdge()); } mISource = source; mITarget = target; mOriginalTarget = target; Assert.IsTrue(hcostpercentage >= 0); mHCostPercentage = hcostpercentage; mBDrawExplorePath = drawexplorepath; mExplorePathRemainTime = explorepathremaintime; mAStarPathInfo = new PathInfo(); mIsIgnoreWall = isignorewall; mStrickDistance = strickdistance; //Search(mStrickDistance, mIsIgnoreWall); //GeneratePathToTargetInfo(); }
/// <summary> /// Finds negative cycle /// </summary> /// <param name="searchResult">Search result returned by <code>CalculateShortestPaths</code> method</param> /// <returns></returns> public static Path <TNode, TEdge, TVal> GetNegativeCycle <TVal>(SparseGraph <TNode, TEdge> graph, PathLogic <TEdge, TVal> pathLogic, PathSearchResult <TNode, TEdge, TVal> searchResult) { var lastNodeId = -1; foreach (var edge in graph.Edges) { if (pathLogic.E(searchResult.Distance[edge.From.Id], pathLogic.UnreachableValue)) { continue; } var newDist = pathLogic.Relax(searchResult.Distance[edge.From.Id], edge); if (pathLogic.Gt(searchResult.Distance[edge.To.Id], newDist)) { searchResult.Distance[edge.To.Id] = newDist; searchResult.Ancestors[edge.To.Id] = edge; lastNodeId = edge.To.Id; } } if (lastNodeId == -1) { return(null); } var visited = new bool[graph.NodesCnt]; for (; !visited[lastNodeId]; lastNodeId = searchResult.Ancestors[lastNodeId].From.Id) { visited[lastNodeId] = true; } var pathEdges = new List <TEdge> { searchResult.Ancestors[lastNodeId] }; for (var nodeId = searchResult.Ancestors[lastNodeId].From.Id; nodeId != lastNodeId; nodeId = searchResult.Ancestors[nodeId].From.Id) { pathEdges.Add(searchResult.Ancestors[nodeId]); } pathEdges.Reverse(); return(new Path <TNode, TEdge, TVal>(graph, pathLogic.ZeroValue, pathEdges)); }
static void Main(string[] args) { string fileName = @"Graph\testG1.txt"; var g1 = new SparseGraph <double>(8, false); var gr1 = new ReadGraph <double>(g1, fileName); g1.Show(); // test Kruskal Console.WriteLine("Test Kruskal: "); var kruskalMST = new KruskalMST <double>(g1); var mst = kruskalMST.MSTEdges; foreach (var edge in mst) { Console.WriteLine(edge); } Console.WriteLine("The MST weight is: " + kruskalMST.MSTWeight); }
public void TestPrimMST() { string fileName = @"Graph\testG1.txt"; var g1 = new SparseGraph <double>(8, false); var gr1 = new ReadGraph <double>(g1, fileName); g1.Show(); // test prim Console.WriteLine("Test Prim MST: "); var primMST = new PrimMST <double>(g1); var mst = primMST.MSTEdges; foreach (var edge in mst) { Console.WriteLine(edge); } Console.WriteLine("The MST weight is: " + primMST.MSTWeight); }
public void TestLazyPrimMST() { string fileName = @"Graph\testG1.txt"; var g1 = new SparseGraph <double>(8, false); var gr1 = new ReadGraph <double>(g1, fileName); g1.Show(); // test lazy prim Console.WriteLine("Test Lazy Prim MST: "); var pq = new MinHeap <Edge <double> >(); var lazyPrimMST = new LazyPrimMST <double>(g1, pq); var mst = lazyPrimMST.MSTEdges; foreach (var edge in mst) { Console.WriteLine(edge); } Console.WriteLine("The MST weight is: " + lazyPrimMST.MSTWeight); }
public PathFinder() { m_bShowGraph = false; m_bShowTiles = true; m_dCellWidth = 0; m_dCellHeight = 0; m_iCellsX = 0; m_iCellsY = 0; m_dTimeTaken = 0.0; m_CurrentTerrainBrush = brush_type.normal; m_iSourceCell = -1; m_iTargetCell = -1; m_icxClient = 0; m_icyClient = 0; m_dCostToTarget = 0.0; m_Graph = null; m_ThickBlack = new Pen(Color.Black, 2); m_ThickBlue = new Pen(Color.Blue, 2); m_font = new Font("Arial", 8, FontStyle.Regular); }
private static bool ExecutePhase <TVal>(SparseGraph <TNode, TEdge> graph, PathLogic <TEdge, TVal> pathLogic, PathSearchResult <TNode, TEdge, TVal> res) { var anyAction = false; foreach (var edge in graph.Edges) { if (pathLogic.E(res.Distance[edge.From.Id], pathLogic.UnreachableValue)) { continue; } var newDist = pathLogic.Relax(res.Distance[edge.From.Id], edge); if (pathLogic.Gt(res.Distance[edge.To.Id], newDist) && !res.IsAncestor(edge.From.Id, edge.To.Id)) { res.Distance[edge.To.Id] = newDist; res.Ancestors[edge.To.Id] = edge; anyAction = true; } } return(anyAction); }
private void _populate() { FillObstaclesWithArray(GetFunPlayField()); graph = GraphGenerator.FloodFill(world: this, startPosition: new Vector2D(50f, 50f)); GraphGenerator.SetNearestItems(this); Lion l1 = new Lion(new Vector2D(60f, 60f), this); Lion l2 = new Lion(new Vector2D(120, 100f), this); Gazelle g1 = new Gazelle(new Vector2D(200f, 200f), this); Gazelle g2 = new Gazelle(new Vector2D(250f, 250f), this); Gazelle g3 = new Gazelle(new Vector2D(300f, 300f), this); Entities.AddRange(new List <MovingEntity>() { g1, l1, g2, g3, l2 }); }
public void Load(Stream stream) { Graph = new SparseGraph <GraphNode, GraphEdge>(false); var lines = LoadLines(stream); foreach (var line in lines) { var nodes = line.Split(','); var from = int.Parse(nodes[0]); var node = new GraphNode(); if (Graph.AddNode(node) != from) { throw new ArgumentException("Invalid source data: new node does not match graph index."); } for (var i = 1; i < nodes.Length; i++) { var to = int.Parse(nodes[i]); Graph.AddEdge(new GraphEdge(from, to)); } } }
private void LoadGraph(IReadOnlyCollection <string> lines) { Width = CalculateLongestLine(lines); Height = lines.Count; Graph = new SparseGraph <GraphGridNode, GraphEdge>(false); Map = new GraphGridNode[Width, Height]; var y = 0; foreach (var line in lines) { var x = 0; foreach (var tileChar in line) { var node = _nodeFactory.CreateNode(x, y, tileChar.ToString()); Graph.AddNode(node); Map[x, y] = node; if (tileChar == '@') { Source = node; } else if (tileChar == 'X') { Destination = node; } x++; } y++; } CreateEdges(); }
/// <summary> /// This adds the relation to the output /// </summary> /// <param name="name">The name of the relation</param> /// <param name="rel"></param> void addRelation(string name, SparseGraph<ZObject> rel) { // Make a normal version of the relation spec var spec = new Dictionary<object,object>(); foreach (var item in rel.SuccessorTable) { add((ZObject)item.Key); var L = new List<object[]>(); foreach (var edge in item.Value) { add(edge.sink); add(edge.gate); L.Add(new object[]{edge.sink.name,null==edge.gate?null:edge.gate.name}); } spec[item.Key.name] = L; } // Add that to the relations table var cb = new Dictionary<string,object>(); cb["derive"]=rel.immediate; if (spec.Count > 0) cb["spec"]=spec; relations[name] = cb; }
public override void Create() { Graph = new SparseGraph(false); for (int row = 0; row < rows; row++) { for (int column = 0; column < columns; column++) { var nodePosition = new Vector2( column * cellWidth - cellWidth * (columns - 1) / 2, row * cellHeight - cellHeight * (rows - 1) / 2); var node = new Node(row * columns + column) { Position = nodePosition }; int nodeIndex = Graph.AddNode(node); if (IsPointInObstacle(nodePosition)) { Graph.GetNode(nodeIndex).Index = Node.INVALID_NODE_INDEX; } else { //AddNodeObject(node, nodePosition); } } } for (int nodeIndex = 0; nodeIndex < Graph.NumNodes; nodeIndex++) { if (!Graph.IsNodePresent(nodeIndex)) { continue; } Node node = Graph.GetNode(nodeIndex); int rightIndex = nodeIndex + 1; if (rightIndex % columns != 0 && Graph.IsNodePresent(rightIndex)) { Node rightNode = Graph.GetNode(rightIndex); if (!IsPathObstructed(node.Position, rightNode.Position)) { var rightEdge = new Edge(nodeIndex, rightIndex, cellWidth); Graph.AddEdge(rightEdge); //AddEdgeObject(rightEdge, node.Position, rightNode.Position); } } int downIndex = nodeIndex + columns; if (downIndex < Graph.NumNodes && Graph.IsNodePresent(downIndex)) { Node downNode = Graph.GetNode(downIndex); if (!IsPathObstructed(node.Position, downNode.Position)) { var downEdge = new Edge(nodeIndex, downIndex, cellHeight); Graph.AddEdge(downEdge); //AddEdgeObject(downEdge, node.Position, downNode.Position); } } if (!useDiagonals) { continue; } int diagIndex = nodeIndex + columns + 1; if (diagIndex < Graph.NumNodes && diagIndex % columns != 0 && Graph.IsNodePresent(diagIndex)) { Node diagNode = Graph.GetNode(diagIndex); if (!IsPathObstructed(node.Position, diagNode.Position)) { var diagEdge = new Edge(nodeIndex, diagIndex, cellDiagonal); Graph.AddEdge(diagEdge); //AddEdgeObject(diagEdge, node.Position, diagNode.Position); } } int backDiagIndex = nodeIndex + columns - 1; if (backDiagIndex < Graph.NumNodes && backDiagIndex % columns != columns - 1 && Graph.IsNodePresent(backDiagIndex)) { Node backDiagNode = Graph.GetNode(backDiagIndex); if (!IsPathObstructed(node.Position, backDiagNode.Position)) { var backDiagEdge = new Edge(nodeIndex, backDiagIndex, cellDiagonal); Graph.AddEdge(backDiagEdge); //AddEdgeObject(backDiagEdge, node.Position, backDiagNode.Position); } } } }
//you can use this function to turn the A* algorithm into Dijkstra's search. //this is because Dijkstra's is equivalent to an A* search using a heuristic //value that is always equal to zero. public static double Dijkstra(SparseGraph G, int nd1, int nd2) { return 0; }
// TODO: I need to set up the allGroundedEntities Dictionary public void SetupGraph() { // SET UP THE GRAPH... if (hasBeenSetup) { return; } // the game objects containing the node graphs GameObject[] nodeGameObjects = GameObject.FindGameObjectsWithTag("Node"); // The nodes in the game world nodeList = new Node[nodeGameObjects.Length]; // initialize the message list dual array messageList = new Message[nodeList.Length][]; for (int i = 0; i < nodeList.Length; i++) { messageList[i] = new Message[nodeList.Length]; } // Initialize the list of messages for (int i = 0; i < nodeList.Length; i++) { for (int j = 0; j < nodeList.Length; j++) { messageList[i][j] = Message.DoNothing; } } // Create the abstract graph using the info scanned from the level G = new SparseGraph <GraphNode, GraphEdge>(); // we'll be adding new nodes to the abstract graph, as well as set the ID's of the nodes in the level for (int i = 0; i < nodeGameObjects.Length; i++) { // set the reference for nodeList[i] nodeList[i] = nodeGameObjects[i].GetComponent <Node>(); // update the node's ID nodeList[i].ID = i; // add the node to the abstract graph G.AddNode(new GraphNode(i)); } // Create the edges in the abstract graph and set the weights // Note that the weights are determined heuristically within the node scripts // Also, set the correct message in the n by n messageList[][] so that later when we have the information that the path // from say, 1 to 2 is to be taken, then the message to send the game character is messageList[1][2] for (int i = 0; i < nodeList.Length; i++) { nodeList[i].SetWeights(); // we need to get the information for the edge weight between nodes and create the edge in the abstract graph // so that we can search it efficiently for a path for (int j = 0; j < nodeList[i].neighbors.Count; j++) { // i is the current node ID // nodeList[i].neighbors[j].ID is the ID of the current neighbor // same with the weight G.AddEdge(new GraphEdge(i, nodeList[i].neighbors[j].ID, nodeList[i].weights[j])); // save the way to traverse this edge in the dual array // This makes it so that you can access the message to get from node u to node v // by looking up messageList[u][v] messageList[nodeList[i].ID][nodeList[i].neighbors[j].ID] = nodeList[i].messages[j]; } } hasBeenSetup = true; }
/// <summary> /// Creates the underlying structures for the relation /// </summary> /// <param name="name">The relation to create</param> void addRelation2(ZObject name) { if (!relations.ContainsKey(name)) relations[ name] = new SparseGraph<ZObject>(true); }
public void Init(int width, int height) { m_sparseGraph = new SparseGraph <NavGraphNode, GraphEdge>(false); m_width = width; m_height = height; }
public DijkstraGraphSearch(SparseGraph mGraph, int mISource, int mITarget) { m_graph = mGraph; m_iSource = mISource; m_iTarget = mITarget; }
// this searchs a graph using the distance between the target node and the // currently considered node as a heuristic. // This search is more commonly known as A* (pronounced Ay-Star) public Graph_SearchAStar(SparseGraph graph, int source, int target, CalculateHeuristic functionCalculate) : base(graph, source, target) { funcPointer = functionCalculate; int numNodes = m_Graph.NumNodes(); m_ShortestPathTree = new List<NavGraphEdge>(numNodes); m_SearchFrontier = new List<NavGraphEdge>(numNodes); m_GCosts = new List<double>(numNodes); m_FCosts = new List<double>(numNodes); for (int i = 0; i < numNodes; i++) { m_ShortestPathTree.Add(null); m_SearchFrontier.Add(null); m_GCosts.Add(0.0); m_FCosts.Add(0.0); } m_bFound = Search(); }
//this uses the euclidian distance but adds in an amount of noise to the //result. You can use this heuristic to provide imperfect paths. This can //be handy if you find that you frequently have lots of agents all following //each other in single file to get from one place to another public static double NoisyEuclidianDistance(SparseGraph G, int nd1, int nd2) { return Vector2D.Vec2DDistance(G.GetNode(nd1).Pos, G.GetNode(nd2).Pos) * Utils.RandInRange(0.9f, 1.1f); }
///<summary> ///heuristic estimate always 0 ///</summary> ///<param name="graph"></param> ///<param name="nd1"></param> ///<param name="nd2"></param> ///<returns></returns> public static float Calculate(SparseGraph graph, int nd1, int nd2) { return 0; }
//calculate the straight line distance from node nd1 to node nd2 public static double EuclidianDistance(SparseGraph G, int nd1, int nd2) { return Vector2D.Vec2DDistance(G.GetNode(nd1).Pos, G.GetNode(nd2).Pos); }
public void InitialiseGraph(int CellsUp, int CellsAcross, int pWidth, int pHeight) { m_iCellsX = CellsAcross; m_iCellsY = CellsUp; m_icxClient = pWidth; m_icyClient = pHeight; //initialize the terrain vector with normal terrain int numNodes = CellsUp * CellsAcross; m_TerrainType = new List<int>(numNodes); for (int i = 0; i < numNodes; i++) { m_TerrainType.Add((int)brush_type.normal); } m_Path = new List<int>(); m_SubTree = new List<NavGraphEdge>(); m_dCellWidth = (double)m_icxClient / (double)CellsAcross; m_dCellHeight = (double)m_icyClient / (double)CellsUp; //create the graph m_Graph = new SparseGraph(false);//not a digraph SparseGraph.Helper_CreateGrid(m_Graph, m_icxClient, m_icyClient, CellsUp, CellsAcross); m_CurrentAlgorithm = algorithm_type.none; m_dTimeTaken = 0; }
void Awake() { mNavGraph = null; mTotalNodes = 0; mTotalEdges = 0; //TimerCounter.CreateInstance().Restart("CreateGraph"); CreateGraph (); //TimerCounter.CreateInstance ().End (); }
public static SearchResult <TNode, TEdge> SearchDijkstra <TNode, TEdge>(this SparseGraph <TNode, TEdge> graph, int source, int target = -1) where TNode : GraphNode where TEdge : GraphEdge, new() { SearchResult <TNode, TEdge> result = new SearchResult <TNode, TEdge> { Source = source, Target = target }; // this array contains the edges that comprise the shortest path tree - // a directed subtree of the graph that encapsulates the best paths from // every node on the SPT to the source node. TEdge[] shortestPathTree = new TEdge[graph.NumNodes]; // this is indexed into by node index and holds the total cost of the best // path found so far to the given node. For example, m_CostToThisNode[5] // will hold the total cost of all the edges that comprise the best path // to node 5, found so far in the search (if node 5 is present and has // been visited) float[] costToThisNode = new float[graph.NumNodes]; // this is an indexed (by node) vector of 'parent' edges leading to nodes // connected to the SPT but that have not been added to the SPT yet. This is // a little like the stack or queue used in BST and DST searches. TEdge[] searchFrontier = new TEdge[graph.NumNodes]; // create an indexed priority queue that sorts smallest to largest // (front to back).Note that the maximum number of elements the iPQ // may contain is N. This is because no node can be represented on the // queue more than once. SimplePriorityQueue <int> pq = new SimplePriorityQueue <int>(); //put the source node on the queue pq.Enqueue(source, 0); //while the queue is not empty while (pq.Count != 0) { // get lowest cost node from the queue. Don't forget, the return value // is a *node index*, not the node itself. This node is the node not already // on the SPT that is the closest to the source node int nextClosestNodeindex = pq.Dequeue(); // move this edge from the frontier to the shortest path tree shortestPathTree[nextClosestNodeindex] = searchFrontier[nextClosestNodeindex]; // if the target has been found exit if (nextClosestNodeindex == target) { result.Found = true; int node = target; result.PathToTarget.Add(node); while (node != source && shortestPathTree[node] != null) { node = shortestPathTree[node].From; result.PathToTarget.Insert(0, node); } return(result); } // now to relax the edges. // for each edge connected to the next closest node foreach (TEdge edge in graph.Edges(nextClosestNodeindex)) { // the total cost to the node this edge points to is the cost to the // current node plus the cost of the edge connecting them. float newCost = costToThisNode[nextClosestNodeindex] + (float)edge.Cost; // if this edge has never been on the frontier make a note of the cost // to get to the node it points to, then add the edge to the frontier // and the destination node to the PQ. if (searchFrontier[edge.To] == null) { costToThisNode[edge.To] = newCost; pq.Enqueue(edge.To, newCost); searchFrontier[edge.To] = edge; } // else test to see if the cost to reach the destination node via the // current node is cheaper than the cheapest cost found so far. If // this path is cheaper, we assign the new cost to the destination // node, update its entry in the PQ to reflect the change and add the // edge to the frontier else if (newCost < costToThisNode[edge.To] && shortestPathTree[edge.To] == null) { costToThisNode[edge.To] = newCost; //because the cost is less than it was previously, the PQ must be //re-sorted to account for this. pq.UpdatePriority(edge.To, newCost); searchFrontier[edge.To] = edge; } } } return(result); }
/// <summary> /// This reconstructs the relations table /// </summary> /// <returns>The relations table</returns> internal Dictionary<ZObject, object> Relations() { // Link the relations structures var r2 = new Dictionary<ZObject,object>(); foreach (var I in relations) { var v = I.Value; // If it's an array, it's a relation 1 if (v is IList) { // Go thru, get the objects and populate a dictionary var d = new Dictionary<ZObject, ZObject>(); foreach (var item in (IList) v) { var obj = (ZObject) objects[item]; d[obj] = obj; } // there, done r2[(ZObject) objects[I.Key]] = d; } // If it's a dictionary it's a relation 2 else if (v is Dictionary<string,object>) { var d = (Dictionary<string,object>)v; // each key is an array of arrays... // First get the immediate vs derived bool immediate = false; object b; if (d.TryGetValue("derive", out b) && b is bool) immediate = !(bool)b; // Next get the values var n = new SparseGraph<ZObject>(immediate); object val; if (d.TryGetValue("spec", out val)) { var d2 = (Dictionary<string,object>)val; foreach (var edges in d2) { var src = (ZObject)objects[edges.Key]; foreach (var edge in (IList)edges.Value) { // Get the nodes for the sink and gate var tuple = (IList) edge; var sink = (ZObject) objects[tuple[0]]; ZObject gate = null; if (tuple.Count > 1 && null != tuple[1]) gate = (ZObject) objects[tuple[1]]; // add them n.After(src, new Edge<ZObject>(sink, gate)); } } } // Add the relation to the table r2[(ZObject) objects[I.Key]] = n; } } // Return the relations return r2; }
//this uses the euclidian distance but adds in an amount of noise to the //result. You can use this heuristic to provide imperfect paths. This can //be handy if you find that you frequently have lots of agents all following //each other in single file to get from one place to another public static double NoisyEuclidianDistance(SparseGraph G, int nd1, int nd2) { return(Vector2D.Vec2DDistance(G.GetNode(nd1).Pos, G.GetNode(nd2).Pos) * Utils.RandInRange(0.9f, 1.1f)); }
// Use this for initialization void Start() { mPathFinder = FindObjectOfType (typeof(PathFinder)) as PathFinder; Debug.Assert (mPathFinder != null); mNavGraph = mPathFinder.NavGraph; mAstarSearch = new SearchAStar(mNavGraph, mSourceCellIndex, mTargetCellIndex, mIgnoreWall, mStrickDistance, mHCostPercentage, mBDrawExplorePath, mExplorePathRemainTime); Debug.Assert(mNavGraph != null); }
//calculate the straight line distance from node nd1 to node nd2 public static double EuclidianDistance(SparseGraph G, int nd1, int nd2) { return(Vector2D.Vec2DDistance(G.GetNode(nd1).Pos, G.GetNode(nd2).Pos)); }
public Graph_SearchDijkstra(SparseGraph graph, int source, int target) : base(graph, source, target) { int numNodes = m_Graph.NumNodes(); m_ShortestPathTree = new List<NavGraphEdge>(numNodes); m_SearchFrontier = new List<NavGraphEdge>(numNodes); m_CostToThisNode = new List<double>(numNodes); for (int i = 0; i < numNodes; i++) { m_ShortestPathTree.Add(null); m_SearchFrontier.Add(null); m_CostToThisNode.Add(0); } m_bFound = Search(); }
//you can use this function to turn the A* algorithm into Dijkstra's search. //this is because Dijkstra's is equivalent to an A* search using a heuristic //value that is always equal to zero. public static double Dijkstra(SparseGraph G, int nd1, int nd2) { return(0); }
public static float Calculate(SparseGraph<NavGraphNode, GraphEdge> g, int nd1, int nd2) { //Manhattan distance heuritic //Vector2 v1 = Utility.ConvertIndexToRC (nd1); //Vector2 v2 = Utility.ConvertIndexToRC (nd2); //float dis = v1.x - v2.x + v1.y - v2.y; //Debug.Log("dis = " + dis); //return dis; //Caculation distance takes much time return Vector3.Distance(g.Nodes[nd1].Position, g.Nodes[nd2].Position); }
///<summary> ///calculate the straight line distance from node nd1 to node nd2 ///</summary> ///<param name="graph"></param> ///<param name="nd1"></param> ///<param name="nd2"></param> ///<returns></returns> public static float Calculate(SparseGraph graph, int nd1, int nd2) { return (graph.GetNode(nd1).Position - graph.GetNode(nd2).Position).Length(); }