'Generating a random dictionary and coloring associated graph

I would like to generate a random dictionary starting from an array with 5 elements. That dictionary would represent a planar graph. How can i generate a random dictionary that is a planar graph whose values and keys are the 5 elements of the array? This is what I tried:

q = [0, 1, 2, 3, 4]
d = {i: sample([j for j in q if i != j], randrange(1, len(q) - 1))
     for i in q}

Here is an example of the graph it generates:

{0: [1], 1: [4, 3], 2: [4], 3: [4], 4: [0, 2]}

As you can see, the problem is that it is not creating a proper adjacency matrix (3 is connected with 1 but 1 is not in its adjancey matrix) Some of you suggested me an already asked question, but the answer to that question is pretty complex as it generates a very big planar graph, the thing I’m trying to do here is a simple code that generate a small planar graph with 5 vertices. Keep in mind that the planarity of the graph can always be checked with checkplanarity from networkx, more on that here, the issue I need to solve is the adjacency of the matrix.

the reason I'm doing this is to then color the generated graph with four colors using the following function named coloring, and the matrix problem prevents me from coloring it proprely so that same colors never touch. To feed the function coloring with the created graph I do the following:

def coloring(adj, V):
    result = [-1] * V
    result[0] = 0
    available = [False] * V
    # add values to adj matrices
    for y in range(0, V):
        for x in adj[y]:
            if y not in adj[x]:
                adj[x].append(y)

    for u in range(1, V):
        for i in adj[u]:
            if (result[i] != -1):
                available[result[i]] = True
        cr = 0
        while cr < V:
            if (available[cr] == False):
                break

            cr += 1

        result[u] = cr

        for i in adj[u]:
            if (result[i] != -1):
                available[result[i]] = False

    for u in range(V):
        print("Vertex", u, " --->  Color", result[u])

To feed the function coloring with the created graph d I do the following:

coloring([node for node in d.values()], 5)


Solution 1:[1]

With a slight modification to your code, you can symmetrize your graph:

import random
random.seed(0)

q = [0, 1, 2, 3, 4]
d = {i: set(random.sample([j for j in q if i != j], random.randrange(1, len(q) - 1)))
     for i in q}

Now symmetrize:

for node in d:
    for link_target in d[node]:
        d[link_target].add(node)

This way nodes are not connected to themselves, just as in your code. You still have to verify whether the graph is planar.

Set the number of edges

If you wish to fix the number of edges to k, here's what you can do:

  1. generate a triangular matrix with zeros in the diagonal, using zeros (false) and ones (true) to represent connectivity between edges. You can do it by random shuffling k ones and N*(N-1)/2 zeros and distributing them onto non-diagonal places of the triangular matrix.
  2. add the transpose of the matrix to itself
  3. convert the matrix to the dictionary format you prefer.

Note: you still have to confirm whether the graph is planar.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1