def coreExecution(inputG_swaps, inputG_interactions, soddi): # Check that the data types of the contents are valid checkExtractedContents(inputG_swaps, inputG_interactions, soddi) # Map each node to a number (index in list) which will be used to identify it afterwards ids = idNodes(inputG_swaps) adaptedG_swapsEdges, adaptedG_interactionsEdges, adaptedSODDI = adaptNodeNamesToIDs( ids, inputG_interactions, inputG_swaps, soddi) # Create the actual graphs and check them G_swaps = nx.Graph() G_swaps.add_nodes_from(range(len(ids))) G_swaps.add_edges_from(adaptedG_swapsEdges) checkingG_swaps(G_swaps) G_interactions = nx.DiGraph() G_interactions.add_nodes_from(range(len(ids))) G_interactions.add_edges_from(adaptedG_interactionsEdges) checkingG_interactions(G_interactions) # Check SODDI checkingSODDI(adaptedSODDI, len(ids)) # From this point on, we are ready to manipulate the graphs as we wish newG_swaps, newG_interactions, allSwapSteps = swapsRequired( G_swaps, G_interactions, adaptedSODDI) # Rename every node in allSwapSteps to the original names renamedAllSwapSteps = revertAllSwapStepsNames(allSwapSteps, ids) totalSwaps = len([x for x in renamedAllSwapSteps if type(x) is tuple]) print("SODDI: " + str(soddi)) print("Swap steps: " + str(renamedAllSwapSteps)) print("Total number of swaps required: " + str(totalSwaps)) return totalSwaps, renamedAllSwapSteps, ids
def test_SODDIInvalidSelfInteractions(self): # Test that an exception is thrown when there is a desired interaction in SODDI of a node with itself G_interactions = nx.DiGraph() G_interactions.add_nodes_from([0, 1, 2, 3]) # There is no node 4, since there are only 4 nodes going from 0 to 3 soddi = [(1, 1)] with self.assertRaises(Exception, msg=CONST_SODDIInvalidSelfInteractions): checkingSODDI(soddi, len(list(G_interactions.nodes)))
def test_SODDIIntegersWithinRange(self): # Test that an exception is thrown when the ints in SODDI are not within range G_interactions = nx.DiGraph() G_interactions.add_nodes_from([0, 1, 2, 3]) # There is no node 4, since there are only 4 nodes going from 0 to 3 soddi = [(2, 4)] with self.assertRaises(Exception, msg=CONST_SODDINodesOutOfRange): checkingSODDI(soddi, len(list(G_interactions.nodes))) # There is no node -1, since there are labelled from 0 to the number of nodes - 1 soddi = [(2, -1)] with self.assertRaises(Exception, msg=CONST_SODDINodesOutOfRange): checkingSODDI(soddi, len(list(G_interactions.nodes)))
def test_SODDIInputType(self): # Test that an exception is thrown when SODDI is not a list of tuples of ints G_interactions = nx.DiGraph() G_interactions.add_nodes_from([0, 1, 2, 3]) # Checking for soddi not being a list soddi = "#" with self.assertRaises(Exception, msg=CONST_SODDIbadFormat): checkingSODDI(soddi, len(list(G_interactions.nodes))) # Checking for soddi not being a list of tuples soddi = [42] with self.assertRaises(Exception, msg=CONST_SODDIbadFormat): checkingSODDI(soddi, len(list(G_interactions.nodes))) # Checking for soddi not being a list of tuples of ints soddi = [("#", 2.5)] with self.assertRaises(Exception, msg=CONST_SODDIbadFormat): checkingSODDI(soddi, len(list(G_interactions.nodes)))
def randomInput(): for i in range(rounds): #################################################### # INPUT 1: Graph representing real swappable nodes # #################################################### G_swaps = G_preSwaps = None connected = False planar = False print("Searching for connected graph...") while not (connected and planar): G_swaps = G_preSwaps = nx.erdos_renyi_graph( numberOfNodes, edgeCreationProbabilitySwaps, directed=False) connected = nx.is_connected(G_preSwaps) planar = nx.check_planarity(G_preSwaps) print("\nConnected graph found!") drawOriginalGSwap(G_preSwaps) ################################################################ # INPUT 2: Graph representing direct interaction possibilities # ################################################################ G_interactions = nx.DiGraph() G_interactions.add_nodes_from(range( numberOfNodes)) # G_interactions has the same nodes as G_swaps def createRandomGInteractions(G_interactions): if randomInteractionGraph: hasOneEdge = False while not hasOneEdge: for x in range(random.randint(0, round(numberOfNodes * 2))): if random.uniform(0, 1) < 0.5: firstNode = random.randint(0, numberOfNodes - 1) secondNode = random.randint(0, numberOfNodes - 1) while firstNode == secondNode: # Avoid edges from node to itself firstNode = random.randint( 0, numberOfNodes - 1) secondNode = random.randint( 0, numberOfNodes - 1) if not G_interactions.has_edge( firstNode, secondNode): G_interactions.add_edge(firstNode, secondNode) else: firstNode = random.randint(0, numberOfNodes - 1) secondNode = random.randint(0, numberOfNodes - 1) while firstNode == secondNode: # Avoid edges from node to itself firstNode = random.randint( 0, numberOfNodes - 1) secondNode = random.randint( 0, numberOfNodes - 1) if G_interactions.has_edge(firstNode, secondNode): G_interactions.remove_edge( firstNode, secondNode) hasOneEdge = G_interactions.edges createRandomGInteractions(G_interactions) print("Edges in G_swaps:") print([e for e in G_swaps.edges]) print() print("Edges in G_interactions:") print([e for e in G_interactions.edges]) print() print("G_interactions isolates: " + str(list(nx.isolates(G_interactions))) + "\n") drawGInteractions(G_interactions) ############################################################ # INPUT 3: Sequence of desired direct interactions (SODDI) # ############################################################ # Just a simple tuple of tuples which represents which nodes we want interaction between and in what order soddi = [ valid_interaction for valid_interaction in ( (random.randrange(numberOfNodes), random.randrange(numberOfNodes)) for i in range(random.randint(*nInteractions))) if valid_interaction[0] != valid_interaction[1] ] print("SODDI: ") print(soddi) ############################################################################################# # END OF INPUTS # ############################################################################################# """ We must check that the inputs are valid. Here are the requirements: 1) G_swaps must be an undirected connected graph of nodes labelled 0 to (nodes-1) 2) G_interactions must have the same nodes as G_swaps, it must have at least one edge somewhere and no node may have an edge pointing to itself 3) SODDI must be a list of tuples, with each tuple containing a pair of numbers, and each number must correspond to one node. No tuple may have both numbers be the same """ # Checking requirement 1 checkingG_swaps(G_swaps) # Checking requirement 2 checkingG_interactions(G_interactions) # Checking requirement 3 checkingSODDI(soddi, len(list(G_swaps.nodes))) # Now that we have checked the inputs, we want to evaluate what is the minimum number of swaps required to achieve # all of the desired interactions # First, we want to measure how many swaps are necessary with the initial configuration newG_swaps, newG_interactions, swaps = swapsRequired( G_swaps, G_interactions, soddi) drawNewGSwaps(newG_swaps)