public void TestDFSUnDirectedGraph() { IGraph graph = new Graph(); graph.AddNode(new Node("s")); graph.AddNode(new Node("a")); graph.AddNode(new Node("b")); graph.AddNode(new Node("c")); graph.AddNode(new Node("d")); graph.AddNode(new Node("e")); graph.BuildEdge("s", "a", 0); graph.BuildEdge("s", "b", 0); graph.BuildEdge("a", "c", 0); graph.BuildEdge("a", "b", 0); graph.BuildEdge("b", "d", 0); graph.BuildEdge("c", "e", 0); graph.BuildEdge("c", "d", 0); graph.BuildEdge("d", "e", 0); DepthFirstTraversal dfs = new DepthFirstTraversal(graph, graph.GetNodeByID("s")); TraversalResult tr = dfs.Run(); Assert.Equal("s,a,c,e,d,b", string.Join(",", tr.Nodes.Select(node => node.ID))); }
public void TestDFSDirectedGraph() { INode node1 = new Node("1"); INode node2 = new Node("2"); INode node3 = new Node("3"); INode node4 = new Node("4"); INode node5 = new Node("5"); IGraph graph = new Graph(true); graph.AddNode(node1); graph.AddNode(node2); graph.AddNode(node3); graph.AddNode(node4); graph.AddNode(node5); graph.BuildEdge(node1, node2, 0); graph.BuildEdge(node1, node3, 0); graph.BuildEdge(node2, node4, 0); graph.BuildEdge(node2, node5, 0); DepthFirstTraversal dfs = new DepthFirstTraversal(graph, node1); TraversalResult traversalResult = dfs.Run(); string result = string.Join(",", traversalResult.Nodes.Select(node => node.ID)); Assert.Equal("1,2,4,5,3", result); }
private static TraversalResult TraverseGraph(ControlFlowNode <T> entrypoint) { var result = new TraversalResult(); result.TraversalOrder = new List <ControlFlowNode <T> >(); result.NodeIndices = new Dictionary <ControlFlowNode <T>, int>(); result.NodeParents = new Dictionary <ControlFlowNode <T>, ControlFlowNode <T> >(); var visited = new HashSet <ControlFlowNode <T> >(); var agenda = new Stack <ControlFlowNode <T> >(); agenda.Push(entrypoint); while (agenda.Count > 0) { var currentNode = agenda.Pop(); if (!visited.Add(currentNode)) { continue; } result.NodeIndices[currentNode] = result.TraversalOrder.Count; result.TraversalOrder.Add(currentNode); // Schedule the "normal" successors. foreach (var successor in currentNode.GetSuccessors()) { Schedule(currentNode, successor); } // If we are in a protected region of an exception handler, then the node can technically // transfer control to any of the handler blocks. These are not encoded in the graph explicitly, // so we need to manually schedule these. if (currentNode.GetParentExceptionHandler() is { } parentEh && currentNode.IsInRegion(parentEh.ProtectedRegion)) { for (int i = 0; i < parentEh.Handlers.Count; i++) { Schedule(currentNode, parentEh.Handlers[i].GetEntrypoint()); } } } void Schedule(ControlFlowNode <T> origin, ControlFlowNode <T> successor) { agenda.Push(successor); if (!result.NodeParents.ContainsKey(successor)) { result.NodeParents[successor] = origin; } } return(result); }
/// <summary> /// Deletes data at the position in the Linked List /// </summary> /// <param name="pos">the position of the node to remove, if left empty will remove the last Node</param> public void Delete(int pos = 0) { if (pos > 0) { TraversalResult result = Traverse(pos); result.PreviousNode.NextNode = result.NextNode; result.NextNode.PreviousNode = result.PreviousNode; } else { if (CurrentNode == HeadNode) { CurrentNode = null; } CurrentNode = CurrentNode.PreviousNode; CurrentNode.NextNode = null; } }
/// <summary> /// Inserts data into the Linked List /// </summary> /// <typeparam name="T">The Type of the Data To insert</typeparam> /// <param name="obj">The Data To Insert</param> /// <param name="pos">The Position to Insert the Data at. if left empty will insert to the end of the list</param> public void Insert(T obj, int pos = 0) { if (pos > 0) { TraversalResult result = Traverse(pos); MilkNode nodeToInsert = new MilkNode(result.PreviousNode, obj, result.CurrentNode); result.PreviousNode.NextNode = nodeToInsert; result.CurrentNode.PreviousNode = nodeToInsert; } else { MilkNode nodeToInsert = new MilkNode(CurrentNode, obj, null); if (HeadNode == null) { HeadNode = nodeToInsert; } else { CurrentNode.NextNode = nodeToInsert; } CurrentNode = nodeToInsert; } }
public override void Trace(RayBuffer rayBuffer) { //if (rayBuffer.RaysInitialized == 0) //{ // Debugger.Break(); //} var raysArg = rayBuffer.RaysInfo; var raysHandle = GCHandle.Alloc(raysArg, GCHandleType.Pinned); uint size = lowLatency ? (uint)(Math.Sqrt(RayBuffer.RayBufferSize / 8)) : (uint)(Math.Sqrt(RayBuffer.RayBufferSize)); trav.SetRayData(rayBuffer.RaysInfo); trav.Traverse(); var result = new TraversalResult[rayBuffer.RaysInfo.Length]; var coords = new Vector2[rayBuffer.RaysInfo.Length]; trav.GetResults(result); trav.GetBaryCentricOutput(coords); rayBuffer.rayHits = result.Select((rh, i) => new RayHit { Distance = rh.T, Index = (uint)rh.T, U = coords[i].X, V = coords[i].Y, }).ToArray(); rayBuffer.traced = true; raysHandle.Free(); }