Structural Imbalance in a Social Network

This example solves a structural-imbalance problem, similar to the Leap demo and Jupyter Notebook, to demonstrate using Leap’s hybrid solver service on a problem of arbitrary structure and size.

Social networks map relationships between people or organizations onto graphs, with the people/organizations as nodes and relationships as edges; for example, Facebook friends form a social network. Signed social networks map both friendly and hostile relationships by assigning to edges either positive or negative values. Such networks are said to be structurally balanced when they can be cleanly divided into two sets, with each set containing only friends, and all relations between these sets are hostile. The measure of structural imbalance or frustration for a signed social network, when it cannot be cleanly divided, is the minimum number of edges that violate the social rule, “the enemy of my friend is my enemy.”

image

Juliet’s new love of Romeo introduces imbalance into the social network of Verona. Green edges represent friendly relationships (Juliet & Romeo and Juliet & Lord Capulet) while red edges represent hostile relationships (Romeo and Lord Capulet). The black vertical line dividing the set with Romeo from the set with Lord Capulet crosses the friendly edge between Juliet and Lord Capulet.

Finding a division that minimizes frustration is an NP-hard graph problem (it can be viewed as an expansion of the well-known maximum cut problem).

Example Requirements

To run the code in this example, the following is required.

If you installed dwave-ocean-sdk and ran dwave setup, your installation should meet these requirements. In D-Wave’s Leap IDE, the default workspace meets these requirements.

Solution Steps

Section How a D-Wave System Solves Problems describes the process of solving problems on the quantum computer in two steps: (1) Formulate the problem as a binary quadratic model (BQM) and (2) Solve the BQM with a D-wave system, classical sampler, or hybrid sampler. In this example, a function in Ocean software handles both steps. Our task is mainly to select the sampler used to solve the problem.

Formulate the Problem

For a social graph, G, this example simply builds a random sparse graph—using the NetworkX random_geometric_graph() function, which places uniformly at random a specified number of nodes, problem_node_count, in a unit cube, joining edges of any two if the distance is below a given radius—and randomly assigns \(0, 1\) signs to represent friendly and hostile relationships.

>>> import networkx as nx
>>> import random
>>> problem_node_count = 300
>>> G = nx.random_geometric_graph(problem_node_count, radius=0.0005*problem_node_count)
>>> G.add_edges_from([(u, v, {'sign': 2*random.randint(0, 1)-1}) for u, v in G.edges])

Solve the Problem by Sampling

As mentioned above, this example uses Ocean’s dwave_networkx function, structural_imbalance(), to create the appropriate BQM to represent the problem graph and return a solution. It requires just the selection of a sampler.

D-Wave’s quantum cloud service provides cloud-based hybrid solvers you can submit arbitrary BQMs to. These solvers, which implement state-of-the-art classical algorithms together with intelligent allocation of the quantum processing unit (QPU) to parts of the problem where it benefits most, are designed to accommodate even very large problems. Leap’s solvers can relieve you of the burden of any current and future development and optimization of hybrid algorithms that best solve your problem.

Ocean software’s dwave-system LeapHybridSampler class enables you to easily incorporate Leap’s hybrid solvers into your application:

>>> from dwave.system import LeapHybridSampler
>>> sampler = LeapHybridSampler()     # doctest: +SKIP

Finally, the returned set of frustrated edges and a bicoloring are counted and printed.

>>> import dwave_networkx as dnx
>>> imbalance, bicoloring = dnx.structural_imbalance(G, sampler)    # doctest: +SKIP
>>> set1 = int(sum(list(bicoloring.values())))        # doctest: +SKIP
>>> print("One set has {} nodes; the other has {} nodes.".format(set1, problem_node_count-set1))  # doctest: +SKIP
>>> print("The network has {} frustrated relationships.".format(len(list(imbalance.keys()))))    # doctest: +SKIP
One set has 143 nodes; the other has 157 nodes.
The network has 904 frustrated relationships.

The graphic below visualizes the result of one such run.

image

One solution found for a 300-node problem. Two circular sets, of blue or yellow nodes, are internally connected by solid green edges representing friendly relationships while red edges representing hostile relationships and dashed green edges representing frustrated relationships are stretched out between these.