1

I am starting to work with IDE Jupyter && Python 3.6 and a question has arisen. I have to draw through the IDE, a Hamiltonian path in the Petersen subgraph, but I do not know how to do it.

I show information about said graph:

Any idea of how you can make the comments?

Thank you very much.

JuMoGar
  • 1,608
  • 1
  • 11
  • 38
  • Do you also need to compute the Hamiltonian path or you already have it and only need to make a pretty picture? – Aechlys May 05 '18 at 11:17
  • @Aechlys I also also need to compute the Hamiltonian path in the Petersen subgraph, I do not know how to do this – JuMoGar May 05 '18 at 11:24

1 Answers1

1

To compute the Hamiltonian graph in Petersen graph we can use the solution from this answer

petersen = {1: [2,5,6], 2: [3,1,7], 3: [4,2,8], 4: [5,3,9], 5: [1,4,10],
        6: [1,8,9], 7:[2,9,10], 8: [3,10,6], 9: [4,6,7], 10: [5,7,8]}

Petersen graph

I've forgotten whether or not Petersen graphs are isomorphic to any of their vertex permutations so I will assume they are not. Therefore, instead of searching for pairs of vertices which form the ends of the path we will add two new vertices connected to every vertex of the original graph. So if a Hamiltonian path exists in the original graph, it will exist in this extended graph -- just cut off the two extra vertices (-1) and (-2).

# Add two new vertices (-1) and (-2)
for k in petersen:
    petersen[k].append(-1)
    petersen[k].append(-2)
petersen[-1] = list(range(1,11))
petersen[-2] = list(range(1,11))

Now we can apply the algorithm from the post:

def find_all_paths(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return [path]
    if not start in graph:
        return []
    paths = []
    for node in graph[start]:
        if node not in path:
            newpaths = find_all_paths(graph, node, end, path)
            for newpath in newpaths:
                paths.append(newpath)
    return paths
for path in find_all_paths(petersen, -1, -2):
if len(path) == len(petersen):
    print(path[1:-1])
[1, 2, 3, 4, 5, 10, 7, 9, 6, 8]
[1, 2, 3, 4, 5, 10, 8, 6, 9, 7]
[1, 2, 3, 8, 6, 9, 4, 5, 10, 7]
[1, 2, 3, 8, 6, 9, 7, 10, 5, 4]
[1, 2, 7, 9, 6, 8, 3, 4, 5, 10]
[1, 2, 7, 9, 6, 8, 10, 5, 4, 3]
            ...

Since this algorithm returns list of ALL paths between given vertices we will filter them only to Hamiltonian paths and cut off the extra vertices.

Surely, this can be more efficient, but I leave the optimizations to either you or someone else. For such a small graph as Petersen it works quickly enough in my opinion.

DRAWING

We randomly choose one path and store it in ham_path variable.

import random
ham_paths = [path[1:-1] for path in find_all_paths(petersen, -1, -2) 
         if len(path) == len(petersen)]
ham_path = random.choice(ham_paths)

Then we will use the networkx package to draw the graph and the chosen path.

import networkx
g = networkx.Graph()
for k, vs in petersen.items():
    for v in vs:
        if v in [-1, -2] or k in [-1, -2]:
            continue
        if abs(ham_path.index(k) - ham_path.index(v)) == 1:
            g.add_edge(k,v, color='red', width=1.5)
        else:
            g.add_edge(k,v, color='black', width=0.5)

We create a networkx graph, and each edge that is in Hamiltonian path will be colored red and bold. On the other hand, every other edge will be thinner and black. We also do not want the extra vertices in our drawing.

pos = networkx.circular_layout(g)
edges = g.edges()
colors = [g[u][v]['color'] for u,v in edges]
widths = [g[u][v]['width'] for u,v in edges]
networkx.draw(g, pos, edges=edges, edge_color=colors, width=widths)

Hamiltonian path

Aechlys
  • 1,198
  • 6
  • 15
  • Thank you so much for your answer. I have tryed code and I get an error: `name 'find_all_paths' is not defined`. Also, I have two question in reference to the code: 1- This draws too the path? 2- Paths getted by `print(path[1:-1])` are the Hamiltonian path in the Petersen subgraph? – JuMoGar May 05 '18 at 12:02
  • You have to copy `find_all_paths` from the link to the answer (first sentence of my answer). As to the two answers: (1) No, I'm working on that one. Almost finished. Will update answer soon. (2) Yes. – Aechlys May 05 '18 at 12:06
  • Yes, I did that, right. Also, now I get error: `'dict' object has no attribute 'has_key'`. I have searching this inside the code an no appear nothing about `has_key`. Have you any idea about it? – JuMoGar May 05 '18 at 12:07
  • Oh yes, I forgot about that. The `has_key` has been removed from Python 3.x so simply replace all `graph.has_key(key)` with `key in graph`. I'm sorry about that. I might include the snippet from the other answer. – Aechlys May 05 '18 at 12:08
  • Oh, ok, perfect. Thank you again for your help. I will try your updated answer and I will tell you if all is OK and select it :) – JuMoGar May 05 '18 at 12:08
  • There, the drawing part is also include. However, the positioning of the nodes might not be as pretty. – Aechlys May 05 '18 at 12:23
  • Oh, this is now all working, it is great. I have added to your code: `import networkx` and `ham_path = [8, 3, 4, 5, 10, 7, 2, 1, 6, 9];` and works fine. I recommend you add this both lines to your code for doing it an MCVE, it will gets more UpVotes. Thank you so much again for all your help. – JuMoGar May 05 '18 at 12:27
  • @ Aechlys I have created other post asking for reorder vertex to show them like Petersen's graph. If you know how do it and you want answer it, I will be happy to select you as the best answer again. Link to the post: https://stackoverflow.com/questions/50190974/reorder-vertex-of-a-graph-it-should-be-ordered-like-petersen-graph#50190974 – JuMoGar May 05 '18 at 16:29
  • @ Aechlys I have two last ask... (1)What means `k` and `vs` inside loops? (2) what exactly do `path[1:-1]`?. I will be very grateful if you can answer it too – JuMoGar May 05 '18 at 17:32
  • 1
    (1) We loop through the dictionary `petersen`'s pairs of (key, values). The key `k` is the value before the colon `:` and the values `vs` is the list consisting of ID values. (2) path[1:-1] returns a sublist of list `path` starting with element at position 1 (second element) and all the way to the end except the last element `-1`. – Aechlys May 05 '18 at 17:37
  • Ok! Thank you again @ Aechlys – JuMoGar May 05 '18 at 17:44