Find an hamiltonian path inside the Petersen subgraph

送分小仙女□ 提交于 2019-12-11 07:44:39

问题


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:

  • Graph of Petersen: https://en.wikipedia.org/wiki/Petersen_graph
  • Hypohamiltonian graph: https://en.wikipedia.org/wiki/Hypohamiltonian_graph

Any idea of how you can make the comments?

Thank you very much.


回答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]}

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)



来源:https://stackoverflow.com/questions/50178527/find-an-hamiltonian-path-inside-the-petersen-subgraph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!