/// <summary> /// Copy constructor creates a copy of a given network graph /// </summary> public NetworkGraph(NetworkGraph otherGraph) { AsNodes = new Dictionary <UInt32, AsNode>(); EdgeCount = 0; BfsTreeDepth = 0; foreach (AsNode node in otherGraph.GetAllNodes()) { foreach (AsNode neighbor in node.GetAllNeighbors()) { AddEdge(node.NodeNum, neighbor.NodeNum, node.GetRelationshipTypeOfNeighbor(neighbor)); } } }
/// <summary> /// Copy constructor creates a copy of a given network graph /// </summary> public NetworkGraph(NetworkGraph otherGraph) { AsNodes = new Dictionary<UInt32, AsNode>(); EdgeCount = 0; BfsTreeDepth = 0; foreach (AsNode node in otherGraph.GetAllNodes()) { foreach (AsNode neighbor in node.GetAllNeighbors()) { AddEdge(node.NodeNum, neighbor.NodeNum, node.GetRelationshipTypeOfNeighbor(neighbor)); } } }
/// <summary> /// Extension method on the NetworkGraph class that performs a [modified] BFS on the /// specified graph from the specified source ndoe. The allowedRelationships specifies /// which edges may be traversed during the BFS. /// This algorithm breaks ties by picking the node with the lower node number. /// This algorithm allows you to execute multiple BFS iterations on a single graph, with the /// constraint that any previous BFS trees created in a prior BFS run will not be modified (only /// added to). /// If limitedDiscovery is true, the BFS will only find new nodes that are 1 edge away from any existing /// BFS tree. /// If includeSibling is true, then ties are broken by first taking non-siblings over siblings. /// /// Modified by PGill Oct. 2010 to take in references to the Best, BucketTable and ChosenPaths sets. The function /// was also modified to populate these for our new sims. /// </summary> public static void ExecuteBfs(NetworkGraph graph, List <UInt32> srcNodeNums, bool limitedDiscovery, bool includeSibling, RelationshipType allowedRelationships, ref List <UInt32>[] Best, ref List <UInt32>[] BestNew, ref List <UInt32>[][] BucketTable, ref List <UInt32>[] ChosenPath, ref UInt32[] ChosenParent, ref byte[] L, ref byte[] BestRelation) { Destination utility = new Destination(); // Initialize some stuff... Queue <AsNode> nodeQueue = new Queue <AsNode>(graph.NodeCount); graph.BfsTreeNodeCount = 0; // "Visit" the source nodes foreach (UInt32 srcNodeNum in srcNodeNums) { AsNode currentNode = graph.GetNode(srcNodeNum); currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; currentNode.BfsDepth = 0; nodeQueue.Enqueue(currentNode); graph.BfsTreeNodeCount++; //init the destination's path to itself ChosenPath[srcNodeNum] = new List <UInt32>(); ChosenPath[srcNodeNum].Add(srcNodeNum); Best[srcNodeNum] = new List <UInt32>(); Best[srcNodeNum].Add(srcNodeNum); //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { BucketTable[0][Destination._CUSTOMERCOLUMN] = new List <UInt32>(); BucketTable[0][Destination._CUSTOMERCOLUMN].Add(srcNodeNum); } } // While there's still nodes to be examined... while (nodeQueue.Count > 0) { // Dequeue a node to examine. Iterate through all of its neighbors of the specified type (plus // existing BFS children) and visit them. AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(allowedRelationships | RelationshipType.BfsParentOf).Distinct()) { bool addedtoBest = false; // If this is the first time we've see this node, mark it and possibly enqueue it for later examination if (oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.UnseenInCurrentRun) { // Case 1: oppositeNode is a newly discovered node, also unseen in any previous BFS runs if (oppositeNode.PriorBfsStatus == NodePriorBfsStatus.NotDiscoveredInPriorBfs) { oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; oppositeNode.BfsDepth = currentNode.BfsDepth + 1; oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; if (!oppositeNode.isStub() || !OnlyNonStubs) { L[oppositeNode.NodeNum] = (byte)oppositeNode.BfsDepth; /*** add this node to the buckettable and update its chosen path, parent and BFS depth***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._CUSTOMERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._PROVIDERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] == null) { BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] = new List <UInt32>(); } BestRelation[oppositeNode.NodeNum] = Destination._PEERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } /*** update this node's Best set ***/ if (Best[oppositeNode.NodeNum] == null) { Best[oppositeNode.NodeNum] = new List <UInt32>(); } Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; if (BestNew[oppositeNode.NodeNum] == null) { BestNew[oppositeNode.NodeNum] = new List <UInt32>(); } UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } BestNew[oppositeNode.NodeNum].Add(encoded); } // If we want to continue discovering past this newly found node, enqueue it if (!limitedDiscovery) { nodeQueue.Enqueue(oppositeNode); } } // Case 2: oppositeNode was found in a prior BFS run, and the path to oppositeNode went through currentNode else if (oppositeNode.BfsParentNode == currentNode) { // Don't need to do any marking of the opposite node because it's already in the BFS tree. // Just enqueue it so we can continue our BFS from that node at some later time. oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; nodeQueue.Enqueue(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; // Sanity check... the depth should be the same, right? if (oppositeNode.BfsDepth != currentNode.BfsDepth + 1) { throw new Exception("Unexpected BFS depth during BFS re-run"); } } // Case 3: oppositeNode was found in a prior BFS run, and the path to oppositeNode did NOT go through currentNode // No action necessary. We can't process oppositeNode now because we aren't allow to follow this edge. // Eventually we will hit the already-existing edge that's part of a prior BFS run, and we'll enter Case 2 above. } // We've seen this node before... else { // Did we find an alternate route to the opposite node? // We cannot change the route if this node was found in a prior BFS run. // This is where tie-breaking happens... if ((oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.SeenInCurrentRun) && (oppositeNode.BfsDepth == (currentNode.BfsDepth + 1)) && (oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { // This is an alternate route... break the tie //note that current node is a potential parent of opposite node here. //equivalent to current node being one of the nodes in the tiebreak set //Console.WriteLine("Ties Breaker"); //UPDATED CONDITION TO DEAL WITH HASH FLAG if ((Hash && NewRouteWinsTieBreak(currentNode, oppositeNode, includeSibling)) || (!Hash && NewRouteWinsTieBreakOriginal(currentNode, oppositeNode, includeSibling))) { // Tie-break algorithm says we have a new, better route to this node. // We need to switch the route through the current node instead. oppositeNode.BfsParentNode.RemoveBfsChild(oppositeNode); oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); if (!oppositeNode.isStub() || !OnlyNonStubs) { /*** update chosen parent***/ ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; /*** update its chosen path ***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } } } /*** NEED TO UPDATE BEST SET WHETHER OR NOT THIS WINS THE TIE BREAK!! **/ if (!oppositeNode.isStub() || !OnlyNonStubs) { Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); addedtoBest = true; } } } if ((Best[oppositeNode.NodeNum] != null))// && addedtoBest)// && //(oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { if (BestNew[oppositeNode.NodeNum] == null) { BestNew[oppositeNode.NodeNum] = new List <UInt32>(); } UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } UInt32 encoded0 = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); UInt32 encoded1 = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); UInt32 encoded2 = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); if (!((BestNew[oppositeNode.NodeNum].Exists(element => element == encoded0)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded1)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded2)))) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //Console.WriteLine("encoded = " + encoded); if (encoded != 0) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //if ((((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) && oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.ProcessedInCurrentRun)) //{ // Console.Write("Rel: " + allowedRelationships + " & Node status: " + oppositeNode.InProcessBfsStatus + "\n"); //} //else { BestNew[oppositeNode.NodeNum].Add(encoded); } } } } } // Update the in-process BFS status currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.ProcessedInCurrentRun; } // Finished the BFS... lock the discovered nodes into the BFS tree foreach (AsNode node in graph.GetAllNodes()) { // FYI In limitedDiscovery mode, some nodes may have been left in the SeenInCurrentRun state // (instead of ProcessedInCurrentRun). if (node.InProcessBfsStatus != NodeInProcessBfsStatus.UnseenInCurrentRun) { node.PriorBfsStatus = NodePriorBfsStatus.DiscoveredInPriorBfs; } node.InProcessBfsStatus = NodeInProcessBfsStatus.UnseenInCurrentRun; } }
/// <summary> /// Extension method on the NetworkGraph class that performs a [modified] BFS on the /// specified graph from the specified source ndoe. The allowedRelationships specifies /// which edges may be traversed during the BFS. /// This algorithm breaks ties by picking the node with the lower node number. /// This algorithm allows you to execute multiple BFS iterations on a single graph, with the /// constraint that any previous BFS trees created in a prior BFS run will not be modified (only /// added to). /// If limitedDiscovery is true, the BFS will only find new nodes that are 1 edge away from any existing /// BFS tree. /// If includeSibling is true, then ties are broken by first taking non-siblings over siblings. /// /// Modified by PGill Oct. 2010 to take in references to the Best, BucketTable and ChosenPaths sets. The function /// was also modified to populate these for our new sims. /// </summary> public static void ExecuteBfs(NetworkGraph graph, List<UInt32> srcNodeNums, bool limitedDiscovery, bool includeSibling, RelationshipType allowedRelationships, ref List<UInt32>[] Best, ref List<UInt32>[] BestNew, ref List<UInt32>[][] BucketTable, ref List<UInt32>[] ChosenPath, ref UInt32[] ChosenParent, ref byte[] L, ref byte[] BestRelation) { Destination utility = new Destination(); // Initialize some stuff... Queue<AsNode> nodeQueue = new Queue<AsNode>(graph.NodeCount); graph.BfsTreeNodeCount = 0; // "Visit" the source nodes foreach (UInt32 srcNodeNum in srcNodeNums) { AsNode currentNode = graph.GetNode(srcNodeNum); currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; currentNode.BfsDepth = 0; nodeQueue.Enqueue(currentNode); graph.BfsTreeNodeCount++; //init the destination's path to itself ChosenPath[srcNodeNum] = new List<UInt32>(); ChosenPath[srcNodeNum].Add(srcNodeNum); Best[srcNodeNum] = new List<UInt32>(); Best[srcNodeNum].Add(srcNodeNum); //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships==RelationshipType.NullRelationship) { BucketTable[0][ Destination._CUSTOMERCOLUMN] = new List<UInt32>(); BucketTable[0][ Destination._CUSTOMERCOLUMN].Add(srcNodeNum); } } // While there's still nodes to be examined... while (nodeQueue.Count > 0) { // Dequeue a node to examine. Iterate through all of its neighbors of the specified type (plus // existing BFS children) and visit them. AsNode currentNode = nodeQueue.Dequeue(); foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(allowedRelationships | RelationshipType.BfsParentOf).Distinct()) { bool addedtoBest = false; // If this is the first time we've see this node, mark it and possibly enqueue it for later examination if (oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.UnseenInCurrentRun) { // Case 1: oppositeNode is a newly discovered node, also unseen in any previous BFS runs if (oppositeNode.PriorBfsStatus == NodePriorBfsStatus.NotDiscoveredInPriorBfs) { oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; oppositeNode.BfsDepth = currentNode.BfsDepth + 1; oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; if (!oppositeNode.isStub() || !OnlyNonStubs) { L[oppositeNode.NodeNum] = (byte)oppositeNode.BfsDepth; /*** add this node to the buckettable and update its chosen path, parent and BFS depth***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._CUSTOMERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._PROVIDERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); } //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5 else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) { //init this spot in the bucket table (if needed) if (BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] == null) BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] = new List<UInt32>(); BestRelation[oppositeNode.NodeNum] = Destination._PEERCOLUMN; BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN].Add(oppositeNode.NodeNum); utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } /*** update this node's Best set ***/ if (Best[oppositeNode.NodeNum] == null) Best[oppositeNode.NodeNum] = new List<UInt32>(); Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; if (BestNew[oppositeNode.NodeNum] == null) BestNew[oppositeNode.NodeNum] = new List<UInt32>(); UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } BestNew[oppositeNode.NodeNum].Add(encoded); } // If we want to continue discovering past this newly found node, enqueue it if (!limitedDiscovery) { nodeQueue.Enqueue(oppositeNode); } } // Case 2: oppositeNode was found in a prior BFS run, and the path to oppositeNode went through currentNode else if (oppositeNode.BfsParentNode == currentNode) { // Don't need to do any marking of the opposite node because it's already in the BFS tree. // Just enqueue it so we can continue our BFS from that node at some later time. oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun; nodeQueue.Enqueue(oppositeNode); graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth); graph.BfsTreeNodeCount++; // Sanity check... the depth should be the same, right? if (oppositeNode.BfsDepth != currentNode.BfsDepth + 1) { throw new Exception("Unexpected BFS depth during BFS re-run"); } } // Case 3: oppositeNode was found in a prior BFS run, and the path to oppositeNode did NOT go through currentNode // No action necessary. We can't process oppositeNode now because we aren't allow to follow this edge. // Eventually we will hit the already-existing edge that's part of a prior BFS run, and we'll enter Case 2 above. } // We've seen this node before... else { // Did we find an alternate route to the opposite node? // We cannot change the route if this node was found in a prior BFS run. // This is where tie-breaking happens... if ((oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.SeenInCurrentRun) && (oppositeNode.BfsDepth == (currentNode.BfsDepth + 1)) && (oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { // This is an alternate route... break the tie //note that current node is a potential parent of opposite node here. //equivalent to current node being one of the nodes in the tiebreak set //Console.WriteLine("Ties Breaker"); //UPDATED CONDITION TO DEAL WITH HASH FLAG if ((Hash && NewRouteWinsTieBreak(currentNode, oppositeNode, includeSibling)) || (!Hash && NewRouteWinsTieBreakOriginal(currentNode, oppositeNode, includeSibling))) { // Tie-break algorithm says we have a new, better route to this node. // We need to switch the route through the current node instead. oppositeNode.BfsParentNode.RemoveBfsChild(oppositeNode); oppositeNode.BfsParentNode = currentNode; currentNode.AddBfsChild(oppositeNode); if (!oppositeNode.isStub() || !OnlyNonStubs) { /*** update chosen parent***/ ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum; /*** update its chosen path ***/ //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath); //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath); //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf) utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath); } } /*** NEED TO UPDATE BEST SET WHETHER OR NOT THIS WINS THE TIE BREAK!! **/ if (!oppositeNode.isStub() || !OnlyNonStubs) { Best[oppositeNode.NodeNum].Add(currentNode.NodeNum); addedtoBest = true; } } } if ((Best[oppositeNode.NodeNum] != null))// && addedtoBest)// && //(oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs)) { if (BestNew[oppositeNode.NodeNum] == null) BestNew[oppositeNode.NodeNum] = new List<UInt32>(); UInt32 encoded = 0; UInt32 NodeNumx = currentNode.NodeNum; if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo) { encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship) { encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); } else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf) { encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); } UInt32 encoded0 = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN); UInt32 encoded1 = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN); UInt32 encoded2 = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN); if (!((BestNew[oppositeNode.NodeNum].Exists(element => element == encoded0)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded1)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded2)))) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //Console.WriteLine("encoded = " + encoded); if (encoded != 0) { //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7))); //if ((((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) && oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.ProcessedInCurrentRun)) //{ // Console.Write("Rel: " + allowedRelationships + " & Node status: " + oppositeNode.InProcessBfsStatus + "\n"); //} //else { BestNew[oppositeNode.NodeNum].Add(encoded); } } } } } // Update the in-process BFS status currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.ProcessedInCurrentRun; } // Finished the BFS... lock the discovered nodes into the BFS tree foreach (AsNode node in graph.GetAllNodes()) { // FYI In limitedDiscovery mode, some nodes may have been left in the SeenInCurrentRun state // (instead of ProcessedInCurrentRun). if (node.InProcessBfsStatus != NodeInProcessBfsStatus.UnseenInCurrentRun) { node.PriorBfsStatus = NodePriorBfsStatus.DiscoveredInPriorBfs; } node.InProcessBfsStatus = NodeInProcessBfsStatus.UnseenInCurrentRun; } }
public void CLI(bool script) { bool debug = false; bool decoy_sim = false; string resp; List<Destination> d = new List<Destination>(); NetworkGraph g = new NetworkGraph(); Worker w = new Worker(); bool[] S = new bool[Constants._numASNs]; for (int i = 0; i < S.Length; i++) S[i] = false; GlobalState globalState = new GlobalState(); globalState.S = S; StreamReader input = new StreamReader( Console.OpenStandardInput()); if (script) { Console.WriteLine("You have selected to run a script, please enter the file name:"); string scriptfile = Console.ReadLine(); if (!File.Exists(scriptfile)) Console.WriteLine("script file: " + scriptfile + " did not exist, entering interactive mode"); else input = new StreamReader(scriptfile); } globalState.W = new UInt16[Constants._numASNs]; for (int i = 0; i < globalState.W.Length; i++) globalState.W[i] = 1; Console.WriteLine("Welcome to the testing interface: (type help for help) Haseeb Mac"); bool exitNow = false; //Automatcally load Cyclops_caida.txt if (decoy_sim) { String load = "inputfile decoy/Cyclops_poison.txt"; initGraph(ref g, load); globalState.nonStubs = g.getNonStubs(); Console.WriteLine("Cyclops_poison.txt Loaded!"); } else { String load = "inputfile Cyclops_caida_new.txt"; initGraph(ref g, load); globalState.nonStubs = g.getNonStubs(); Console.WriteLine("Cyclops_caida_new.txt Loaded!"); } //DEBUG if (debug) { String debugC = "analysepathfile test.txt"; analysePathfile (ref g, debugC); exitNow = true; } else if (decoy_sim) { string dst; using (StreamReader reader = new StreamReader("decoy/helper.txt")) { dst = reader.ReadLine(); } String decoyC = "all_path_info " + dst; all_path_info(ref d, ref g, decoyC); exitNow = true; } while(!exitNow) { if (input.EndOfStream) { input.Close(); input = new StreamReader(Console.OpenStandardInput()); Console.WriteLine("script has ended, now in interactive mode"); } Console.Write(">>"); string command = input.ReadLine().ToLower(); if (command.IndexOf ("input") == 0) { initGraph (ref g, command); globalState.nonStubs = g.getNonStubs (); } else if (command.IndexOf ("destination") == 0) { if (command.IndexOf ("all") < 0) { Destination newD = new Destination (); if (initDestination (ref g, ref newD, command)) { d.Add (newD); Console.WriteLine ("initialized and added " + newD.destination); } } else { IEnumerable<AsNode> allASes = g.GetAllNodes (); foreach (AsNode AS in allASes) { Destination newD = new Destination (); if (initDestination (ref g, ref newD, "destination " + AS.NodeNum)) { d.Add (newD); Console.WriteLine ("initialized and added " + newD.destination); } } } } else if (command.IndexOf ("resultsexplorer") == 0) { ResultsExplorer res = new ResultsExplorer (); res.ResultsInterface (); } else if (command.IndexOf ("setstate") == 0) initS (ref globalState.S, command); else if (command.IndexOf ("addedges") == 0) addEdges (command, ref g); else if (command.IndexOf ("getlink") == 0) getLink (command, ref g); else if (command.IndexOf ("flipallu") == 0) flipallU (ref d, ref g, ref globalState, command); else if (command.IndexOf ("printstate") == 0) printState (ref globalState.S, command); else if (command.IndexOf ("printsecp") == 0) printSecP (ref d, command); else if (command.IndexOf ("getl") == 0) getL (ref d, command); else if (command.IndexOf ("getw") == 0) getW (ref globalState.W, command); else if (command.IndexOf ("printw") == 0) printWeight (ref globalState.W, command); else if (command.IndexOf ("setw") == 0) setW (ref globalState.W, command); else if (command.IndexOf ("getbestnew") == 0) getBestNew (ref d, command); else if (command.IndexOf ("getbest") == 0) getBest (ref d, command); else if (command.IndexOf ("all_path_info") == 0) all_path_info (ref d, ref g, command); else if (command.IndexOf ("getpath") == 0) getPath (ref d, ref g, command); else if (command.IndexOf ("analysepathfile") == 0) analysePathfile (ref g, command); else if (command.IndexOf ("analysepath") == 0) analysePath (ref g, command); else if (command.IndexOf ("serialise") == 0) serialisePathArrays (ref g, command); else if (command.IndexOf ("getallpathsoflength") == 0) getAllPathsoflength (ref d, ref g, command); else if (command.IndexOf ("getallpathsto") == 0) getAllPathsTo (ref d, ref g, command); else if (command.IndexOf ("getallpaths") == 0) getAllPaths (ref d, ref g, command); else if (command.IndexOf("getsecp") == 0) getSecP(ref d, command); else if (command.IndexOf("getutility") == 0) getUtility(ref d, command); else if (command.IndexOf("onlynonstubs") == 0) SimulatorLibrary.setOnlyStubs(true); else if (command.IndexOf("notonlynonstubs") == 0) SimulatorLibrary.setOnlyStubs(false); else if (command.IndexOf("iterateall") == 0) iterateAll(ref d, ref g, ref globalState, command); else if (command.IndexOf("iterate") == 0) iterate(ref d, ref globalState, command); else if (command.IndexOf("not") == 0) computeNotN(ref d, ref globalState, ref w, command); else if (command.IndexOf("wgetsecp") == 0) getWorkerSecP(ref w, command); else if (command.IndexOf("checkpath") == 0) checkPath(command); else if (command.IndexOf("initglobalstate") == 0) initGlobalState(command, ref g, ref globalState); else if (command.IndexOf("wgetpath") == 0) getWorkerPath(ref w, command); else if (command.IndexOf("wgetparent") == 0) getWorkerParent(ref w, command); else if (command.IndexOf("printbuckettable") == 0) printBucketTable(ref d, command); else if (command.IndexOf("compareu") == 0) compareU(ref d, ref globalState, ref g, command); else if (command.IndexOf("flipu") == 0) flipU(ref d, ref g, ref globalState, command); else if (command.IndexOf("getnonstubs") == 0) printnonstubs(ref g); else if (command.IndexOf("getstubs") == 0) printstubs(ref g); else if (command.IndexOf("turnonstubs") == 0) turnOnStubs(ref g, ref globalState.S); else if (command.IndexOf("getcustomers") == 0) getcustomers(ref g, command); else if (command.IndexOf("getpeers") == 0) getpeers(ref g, command); else if (command.IndexOf("getproviders") == 0) getproviders(ref g, command); else if (command.IndexOf("gets") == 0) //must be tested for after getsecp getS(ref globalState.S, command); else if (command.IndexOf("sets") == 0) //this must be tested for *after* the test for setstate setS(ref globalState.S, command); else if (command.IndexOf("computehash") == 0) computeHash(command); else if (command.IndexOf("setutilitycomputation") == 0) setUtilityComputation(command); else if (command.IndexOf("numberon") == 0) numberOn(ref globalState.S); else if (command.IndexOf("getaveragebest") == 0) getAverageBest(command, ref d); else if (command.IndexOf("nodeswithnopath") == 0) nodesWithNoPath(command, ref d, ref g); else if (command.IndexOf("traversedod") == 0) DoDAnaly.traverseDoD(g); else if (command.IndexOf("clear") == 0) { Console.WriteLine("clearing state of graph, destination, S and worker."); g = new NetworkGraph(); for (int i = 0; i < S.Length; i++) S[i] = false; d = new List<Destination>(); w = new Worker(); } else if (command.IndexOf("help") == 0) help(); else if (command.IndexOf("list") == 0) { Console.WriteLine("printing current directory contents:"); string[] dirContents = Directory.GetFiles("."); foreach (string s in dirContents) Console.WriteLine(s); } else if (command.IndexOf("exit") == 0) exitNow = true; Console.Write(">>"); } input.Close(); }
private bool nodesWithNoPath(string command, ref List<Destination> destinations,ref NetworkGraph g) { string[] parameters = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); if (parameters.Length < 2) { Console.WriteLine("error: usage averagebest [destination]"); return false; } UInt32 ASN; if (!UInt32.TryParse(parameters[1], out ASN)) { Console.WriteLine("error: invalid destination ASN"); return false; } foreach (Destination d in destinations) { if (d.destination == ASN) { Int32 numWithNoPath=0; IEnumerable<AsNode> allNodes = g.GetAllNodes(); foreach (AsNode AS in allNodes) { if (d.Best[AS.NodeNum] == null) numWithNoPath++; } Console.WriteLine(numWithNoPath + " nodes have no path to destination " + d.destination); } } Console.WriteLine("error could not find AS " + ASN + " in the list of destinations"); return false; }
private bool initGraph(ref NetworkGraph g,string command) { g = new NetworkGraph(); string resp; if (command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length > 1) resp = command.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)[1]; else { Console.WriteLine("Please enter a file name or \"testgraph\" to use the graph from the routing tree algorithm figure in the Sigcomm 2010 paper"); resp = Console.ReadLine().ToLower(); } if (resp == "testgraph") { Console.WriteLine("loading test graph ..."); g = getTestGraph(); Console.WriteLine("done."); return true; } else { if (File.Exists(resp)) { InputFileReader iFR = new InputFileReader(resp, g); iFR.ProcessFile(); Int32 p2pEdges = 0; Int32 c2pEdges = 0; foreach(var ASNode in g.GetAllNodes()) { p2pEdges += ASNode.GetNeighborTypeCount(RelationshipType.PeerOf); c2pEdges += ASNode.GetNeighborTypeCount(RelationshipType.CustomerOf); c2pEdges += ASNode.GetNeighborTypeCount(RelationshipType.ProviderTo); } Console.WriteLine("read in the graph it has " + g.NodeCount + " nodes and " + g.EdgeCount + " edges"); Console.WriteLine("P2P: " + p2pEdges + " C2P: " + c2pEdges); return true; } else { Console.WriteLine("that file does not exist. Going back to main menu now."); return false; } } }