Я знаю, что этот вопрос задавался десятки раз раньше, но я пытался следовать нескольким различным руководствам и не могу понять, почему мой конкретный алгоритм не работает.
Вот код:
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
#The reason we went with this algorithm instad of filling a matrix with random int from 0,1 to begin with is because this is always a simple graph, while
#the other approach almost never makes one. So, rather than checking and fixing those graphs, we thought this would be faster and easier
def makeGraph(order):
p = .5 #represents the probability of an edge being created between any 2 verticies, if less than .4 its almost never connected for values 10+.
g = nx.erdos_renyi_graph(order, p) #generates the graph, verticies are 0-order, edges are ordered pairs of these numbers
return g
def Hamiltonian(matrix, order, path, currentVertex):
while(True):
if(currentVertex >= order):
print("There is no H cycle")
return
checkVertex(matrix, order, path, currentVertex)
if(path[currentVertex] == 0):
print("There is no H cycle")
return
if(currentVertex == (order-1) and matrix[path[currentVertex]][0] == 1):
path.append(0)
print("Hamiltonian found, path is:", path)
break
else:
Hamiltonian(matrix, order, path, currentVertex + 1)
return
def checkVertex(matrix, order, path, currentVertex):
i=1
while(True):
path[currentVertex] = ((path[currentVertex]+i)%order)
if(path[currentVertex] == 0):
return
if(matrix[path[currentVertex-1]][path[currentVertex]] == 1):
for j in range (0, currentVertex+1):
if(j != currentVertex and path[j] == path[currentVertex]):
path[currentVertex] = 0
i+=1
break
if(j == currentVertex):
return
else:
path[currentVertex] = 0
i+=1
#IN = input("Enter the number of desired vertices: ") #get input for number of verticies
#order = int(IN) #make input string an int
#TODO remove hard coded order
order = 10
graph = makeGraph(order) #make the graph
#TODO remove printing of edges/nodes
#print("Number of nodes: ", graph.nodes)
print("Edges: ", graph.edges)
#init matrix filled with 0's for conversion
matrix = np.random.randint(0,1,(order,order))
#makes a pretty picture of the graph, great for finding cycles visually
#nx.draw(graph, with_labels=True)
#plt.show()
#convert ordered pairs into adj matrix for easier calculation
for i in range (0, order):
for j in range (0, order):
e = (i,j)
if(graph.edges.__contains__(e)):
matrix[i][j] = 1 #if there is an edge between vertex i and vertex j, append the matrix to have a 1 in the ith column jth row
path = [0] * (order) #init list to have n 0's
currentVertex = 1 #start the current vertex at 1
#matrix = [[0,0,1,0,1],[0,0,0,1,1],[1,0,0,1,1],[0,1,1,0,0],[1,1,1,0,0]] #for testing, known cycle
Hamiltonian(matrix, order, path, currentVertex)
Похоже, что этот алгоритм работает примерно половину времени. Я думаю, что моя проблема в том, что я неправильно отслеживаю (или даже вообще не знаю, как это сделать), то есть, как только алгоритм достигает точки, где он не может продолжать, он не работает. 't go назад и попробуйте что-нибудь еще.
Как я могу это реализовать? Может ли кто-то указать мне на ресурс, который может мне это объяснить?
Спасибо!