Python类中最短路径图的实现

时间:2019-06-01 15:39:26

标签: python class undirected-graph

  

嗨!我是Python的新手,到目前为止,我一直在努力解决与Python中最短路径算法实现有关的问题。

     

我希望解决一些有关在给定人员中找到最短路径(图形问题)的任务,最后找到一个将所有人员联系在一起的普通人。

到目前为止,我已经做了类似的事情:

import itertools

class centralperson():

def initialization(self,N,data,a,b,c):
    self.data = data
    self.N = N
    self.a = a
    self.b = b
    self.c = c
    self.list_of_values = [self.a,self.b,self.c]
    self.list_of_paths = []
    self.common_person = []

def makeGraph(self):

    # Create dict with empty list for each key
    graph = {key: [] for key in range(self.N)}
    self.graph = graph

    for key in self.graph:
        for x in self.data:
            if key in x:

                x = x.copy()
                x.remove(key)
                self.graph[key].extend(x)

def find_path(self,start, end):
    path = []
    path = path + [start]
    if start == end:
        return path
    if start not in self.graph.keys():
        raise ValueError('No such key in graph!')
    for node in self.graph[start]:
        if node not in path:
            newpath = self.find_path(self.graph, node, end, path)
            if newpath: return newpath
    return self.list_of_paths.append(path)


def findPaths(self):

    for pair in itertools.combinations(self.list_of_values, r=5):
        self.find_path(*pair)


def commonperson(self):

    list_of_lens = {}
    commonalities = set(self.list_of_paths[0]) & set(self.list_of_paths[1]) & set(self.list_of_paths[2])
    for i in self.list_of_values:
        list_of_lens[i] = (len(self.graph[i]))

    if len(commonalities)>1 or len(commonalities)<1:
        for k,v in list_of_lens.items():
            if v==1 and self.graph[k][0] in commonalities:
                output = self.graph[k]
                self.common_person.append(output)
    else:
        output = list(commonalities)
        self.common_person.append(output)
    return 

def printo(self):

    #return(self.common_person[0])
    return(self.list_of_paths,self.list_of_values)
  

每个功能和输入的说明:

     

N->唯一节点数

     

a,b,c->一些任意选择的节点以在其中找到共同的节点

     

初始化->仅初始化我们在其他方法中使用的全局变量,并存储输出列表

     

makeGraph->根据输入创建邻接表。

     

find_path->查找两个给定节点之间的路径(回溯递归)

     

findPaths->预期会在此处为A,B,C的每种组合调用find_path,即A-> B,A-> C,B-> C

     

普通人->希望从list_of_paths列表的输出中找到普通人

     

printo->打印此普通人

通常,当我分别运行每个功能时,它会起作用(我认为)。但是,当我尝试制作一个庞大的类时,它不起作用:(

我认为问题在于此递归函数find_path。应该在给定的两个人之间找到一条路径,并将结果路径与所有路径一起添加到列表中。但是,由于我有3个不同的人,所以find_path是只有两个参数的递归函数。

因此,我需要找到所有连接它们的路径(3条路径)并将其附加到更大的列表list_of_paths中。我创建了一个def findPaths来使用itertools.combinations并在for循环校准函数find_path中使用该函数的start和end参数的每个组合,但似乎不起作用。

您能帮我吗?另外我也不知道如何一次运行所有def functions,因为老实说我不想单独运行该类的所有实例...我想要的版本是:

  

向类提供输入,即:N,data,a,b,c,其中N是唯一节点的数量,数据只是分配了网络的列表的列表,而A,B,C是我的个人。

     

获取输出:这是这3个人中的一个普通人,(我计划将其存储在common_person列表中。

2 个答案:

答案 0 :(得分:0)

类中的代码应缩进 ,即:

class centralperson:
    def __init__(self, ...):
        ...

    def makeGraph(self, ...):
        ...

代替

class centralperson:
def __init__(self, ...):
    ...

def makeGraph(self, ...):
    ...

尝试搜索“ python class examples”。我希望这会有所帮助!

在解决此问题之前尝试使用更简单的类也是有用的。

答案 1 :(得分:0)

itertools.combinations(self.list_of_values, r=5)

返回一个空列表,因为self.list_of_values只有3个元素,您不能从中选择5个。

也许你是说:

itertools.combinations(self.list_of_values, r=2)