def test_structural_imbalance_basic(self): sampler = ExactSolver() blueteam = ['Alice', 'Bob', 'Carol'] redteam0 = ['Eve'] redteam1 = ['Mallory', 'Trudy'] S = nx.Graph() for p0, p1 in itertools.combinations(blueteam, 2): S.add_edge(p0, p1, sign=1) S.add_edge(*redteam1, sign=1) for p0 in blueteam: for p1 in redteam0: S.add_edge(p0, p1, sign=-1) for p1 in redteam1: S.add_edge(p0, p1, sign=-1) frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors) greenteam = ['Ted'] for p0 in set(S.nodes): for p1 in greenteam: S.add_edge(p0, p1, sign=1) frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors)
def test_structural_imbalance_docstring_example(self): sampler = ExactSolver() S = nx.Graph() S.add_edge('Alice', 'Bob', sign=1) # Alice and Bob are friendly S.add_edge('Alice', 'Eve', sign=-1) # Alice and Eve are hostile S.add_edge('Bob', 'Eve', sign=-1) # Bob and Eve are hostile frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors) self.assertEqual(frustrated_edges, {}) S.add_edge('Ted', 'Bob', sign=1) # Ted is friendly with all S.add_edge('Ted', 'Alice', sign=1) S.add_edge('Ted', 'Eve', sign=1) frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors) self.assertTrue(frustrated_edges == {('Ted', 'Eve'): {'sign': 1}} or frustrated_edges == {('Eve', 'Ted'): {'sign': 1}})
def test_invalid_graph(self): """should throw an error with a graph without sign attribute""" S = nx.Graph() S.add_edge('Alice', 'Bob', sign=1) S.add_edge('Alice', 'Eve', sign=-1) S.add_edge('Bob', 'Eve') # invalid edge with self.assertRaises(ValueError): frustrated_edges, colors = dnx.structural_imbalance(S, ExactSolver())
def test_default_sampler(self): S = nx.Graph() S.add_edge('Alice', 'Bob', sign=1) # Alice and Bob are friendly S.add_edge('Alice', 'Eve', sign=-1) # Alice and Eve are hostile S.add_edge('Bob', 'Eve', sign=-1) # Bob and Eve are hostile dnx.set_default_sampler(ExactSolver()) self.assertIsNot(dnx.get_default_sampler(), None) frustrated_edges, colors = dnx.structural_imbalance(S) dnx.unset_default_sampler() self.assertEqual(dnx.get_default_sampler(), None, "sampler did not unset correctly")
def test_frustrated_hostile_edge(self): """Set up a graph where the frustrated edge should be hostile""" sampler = ExactSolver() S = nx.florentine_families_graph() # set all hostile nx.set_edge_attributes(S, -1, 'sign') # smoke test frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.check_bicolor(colors)
def test_sign_zero(self): """though not documentented, agents with no relation can have sign 0. This is less performant than just not having an edge in most cases.""" sampler = ExactSolver() S = nx.Graph() S.add_edge('Alice', 'Bob', sign=1) # Alice and Bob are friendly S.add_edge('Alice', 'Eve', sign=-1) # Alice and Eve are hostile S.add_edge('Bob', 'Eve', sign=0) # Bob and Eve have no relation frustrated_edges, colors = dnx.structural_imbalance(S, sampler) self.assertEqual(frustrated_edges, {}) # should be no frustration
def main(sampler_type, region, show, inspect): if sampler_type is None: print("No solver selected, defaulting to hybrid") sampler_type = 'hybrid' # get the appropriate signed social network G = global_signed_social_network(region=region) # choose solver and any tuning parameters needed if sampler_type == 'cpu': params = dict(num_reads=100) sampler = SimulatedAnnealingSampler() elif sampler_type == 'hybrid': params = dict() sampler = LeapHybridSampler() elif sampler_type == 'qpu': params = dict( num_reads=100, chain_strength=2.0, ) sampler = dimod.TrackingComposite(EmbeddingComposite(DWaveSampler())) else: raise RuntimeError("unknown solver type") # use the chosen sampler (passing in the parameters) edges, colors = dnx.structural_imbalance( G, sampler, label='Example - Structural Imbalance', **params) if inspect and sampler_type == 'qpu': dwave.inspector.show(sampler.output) print("Found", len(edges), 'violations out of', len(G.edges), 'edges') draw_social_network(G, colors) if show: plt.show() else: filename = 'structural imbalance {} {}.png'.format( sampler_type, region) plt.savefig(filename, facecolor='white') plt.clf()
def main(sampler_type, region, show): if sampler_type is None: print("No solver selected, defaulting to hybrid") sampler_type = 'hybrid' if region == 'global' and sampler_type == 'qpu': print("Given region is too large for the QPU, please choose another " "region or use hybrid.") # get the appropriate signed social network G = global_signed_social_network(region=region) # choose solver and any tuning parameters needed if sampler_type == 'cpu': params = dict(num_reads=100) sampler = SimulatedAnnealingSampler() elif sampler_type == 'hybrid': params = dict() sampler = LeapHybridSampler() elif sampler_type == 'qpu': params = dict( num_reads=100, chain_strength=2.0, ) sampler = EmbeddingComposite(DWaveSampler()) else: raise RuntimeError("unknown solver type") # use the chosen sampler (passing in the parameters) edges, colors = dnx.structural_imbalance(G, sampler, **params) print("Found", len(edges), 'violations out of', len(G.edges), 'edges') draw_social_network(G, colors) if show: plt.show() else: filename = 'stuctural imbalance {} {}.png'.format(sampler_type, region) plt.savefig(filename, facecolor='white', dpi=500) plt.clf()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import networkx as nx import dwave_networkx as dnx import dwave_micro_client_dimod as micro import dwave_qbsolv urlc = 'https://cloud.dwavesys.com/sapi' tokenc = 'SE-bb7f104b4a99cf9a10eeb9637f0806761c9fcedc' solver_namec = 'DW_2000Q_1' structured_samplerc = micro.DWaveSampler(solver_namec, urlc, tokenc) samplerc = micro.EmbeddingComposite(structured_samplerc) samplerq = dwave_qbsolv.QBSolv() cloudsi = dnx.structural_imbalance(G, samplerc , num_reads=10000) qbsolvsi = dnx.structural_imbalance (G, samplerq , solver= samplerc) h = {v: node_values [v] for v in G.nodes } J = {(u, v): eval for u, v in G.edges } response = samplerc.sample_ising (h, J, num_reads=10000)
from dwave.system.samplers import DWaveSampler from dwave.system.composites import EmbeddingComposite sampler = EmbeddingComposite(DWaveSampler( solver={'qpu': True })) # Some accounts need to replace this line with the next: # sampler = EmbeddingComposite(DWaveSampler(solver='paste missing solver name here', token='paste missing API token here')) # ### Solving the Problem # Next, the *structural_imbalance()* algorithm, from Ocean's [dwave_networkx](https://docs.ocean.dwavesys.com/projects/dwave-networkx/en/latest/) extension of the NetworkX graphic package, submits the Ising model we formulated in the previous section to a D-Wave system. It returns a partition of our social network into two colored sets and the frustrated edges. # In[ ]: # Return a good partition (minimal structural imbalance) and its frustrated edges import dwave_networkx as dnx imbalance, bicoloring = dnx.structural_imbalance(G, sampler) # Mark the returned frustrated edges and node set (color) on the graph for edge in G.edges: G.edges[edge]['frustrated'] = edge in imbalance for node in G.nodes: G.nodes[node]['color'] = bicoloring[node] # Print the relationships for the returned partition print('Yellow set: ', [person for (person, color) in bicoloring.items() if (color == 0)]) print('Blue set: ', [person for (person, color) in bicoloring.items() if (color == 1)]) print('\nFrustrated relationships: ', list(imbalance.keys())) # Display the solution using a *draw()* function that represents friendly interactions as green lines, hostile interactions as red lines, and frustration as dashed lines.
def diagramDateRange(directory_name, start, end, graph, sampler, subsolver, subarea=None, subarea_name=None): # Create directories directory_path = os.path.join('Results', directory_name) if not os.path.exists(directory_path): os.makedirs(directory_path) # Write .csv header line csv = open(os.path.join(directory_path, 'Structural Imbalance.csv'), 'w') csv.write( 'year,total groups,total edges,imbalanced edges,structural imbalance') if subarea is not None and subarea_name is not None: csv.write( ',%s groups,%s edges,%s imbalanced edges,%s structural imbalance' % tuple([subarea_name] * 4)) csv.write('\n') for year in range(start, end): # Compute structural imbalance up to and including year filtered_edges = ((u, v) for u, v, a in graph.edges(data=True) if a['event_date'].year <= year) subrange = graph.edge_subgraph(filtered_edges) imbalance, bicoloring = dnx.structural_imbalance(subrange, sampler, solver=subsolver) # Write stats to .csv num_nodes = len(subrange.nodes) num_edges = len(subrange.edges) num_imbalanced = len(imbalance) ratio = num_imbalanced / num_edges csv.write('%s,%s,%s,%s,%s' % (year, num_nodes, num_edges, num_imbalanced, ratio)) if subarea is not None and subarea_name is not None: num_nodes = len( set.intersection(set(subrange.nodes), set(subarea.nodes))) num_edges = len( set.intersection(set(subrange.edges), set(subarea.edges))) num_imbalanced = len( set.intersection(set(imbalance), set(subarea.edges))) if num_edges != 0: ratio = num_imbalanced / num_edges else: ratio = '-' csv.write(',%s,%s,%s,%s' % (num_nodes, num_edges, num_imbalanced, ratio)) csv.write('\n') # Draw graph file_name = 'Structural Imbalance %s.png' % year file_path = os.path.join(directory_path, file_name) sbdemo.draw(file_path, subrange, imbalance, bicoloring) print('output %s' % file_path) csv.close()
sampler = qbsolv.QBSolv() if _sapi: print("Running on the QPU") subsolver = sapi.EmbeddingComposite( sapi.SAPISampler(solver_name, url, token)) else: print("Running classically") subsolver = None # get the graphs Global, Syria, Iraq = maps() # calculate the imbalance of Global imbalance, bicoloring = dnx.structural_imbalance(Global, sampler, solver=subsolver) # draw the Global graph sbdemo.draw('syria_imbalance.png', Global, imbalance, bicoloring) # Images of the structural imbalance in the local Syrian SSN # for years 2010-2016 showing frustrated and unfrustrated edges. diagramDateRange('Syrian Theatre', 2010, 2016 + 1, Syria, sampler, subsolver) # Images of the structural imbalance in the world SSN for # years 2007-2016 showing frustrated and unfrustrated edges. diagramDateRange('World Network', 2007, 2016 + 1, Global, sampler, subsolver, Syria, 'Syria')
from dwave.system import LeapHybridSampler import dwave_networkx as dnx import networkx as nx import random # Create a hybrid solver solver = LeapHybridSampler() # Create a random graph where nodes are connected based on distance and set the weights to 1 or -1 problem_node_count = 30 G = nx.random_geometric_graph(problem_node_count, radius=0.0005 * problem_node_count) G.add_edges_from([(u, v, { 'sign': random.choice((-1, 1)) }) for u, v in G.edges]) imbalance, bicoloring = dnx.structural_imbalance(G, solver) set1 = int(sum(list(bicoloring.values()))) print("One set has {} nodes; the other has {} nodes.".format( set1, problem_node_count - set1)) print("The network has {} frustrated relationships.".format( len(list(imbalance.keys()))))