繁体   English   中英

通过连接的节点查找最长的非重复路径

[英]Finding longest non-repeating path through connected nodes

我已经为此工作了几天,但没有成功。 基本上,我有一堆节点以2D矩阵排列。 每个节点都有四个邻居,除了矩阵的边和角上的节点分别有3个和2个邻居。 想象一下在矩形区域中并排放置的一堆正方形纸牌-该项目实际上是在模拟一种纸牌/棋盘游戏。

每个节点可能会或可能不会连接到它周围的节点。 每个节点都有一个函数(get_connections()),该函数将立即返回与其连接的节点(因此将返回0至4个节点)。 每个节点还具有“索引”属性,其中包含其在电路板矩阵上的位置(例如“ 1,4”->第1行,第4行)。 我要尝试做的是找到给定特定“开始”节点的连接节点的最长非重复路径。

我上传了几张图片,这些图片应该可以很好地说明我要执行的操作:

www.necessarygames.com/junk/10-days-problem-01.jpg
(来源: essentialgames.com

www.necessarygames.com/junk/10-days-problem-02.jpg
(来源: essentialgames.com

在两个图像中,突出显示的红牌应该是包含最左上角牌的已连接牌的最长路径。 但是,您都可以在两个图像中看到应该去的路径中的几张纸牌已被忽略(第一幅图像中为罗马尼亚和马尔多瓦,第二幅图像中为希腊和土耳其)

给定起始节点/卡,这是我当前正在使用的递归函数,用于查找最长路径:

def get_longest_trip(self, board, processed_connections = list(), 
                     processed_countries = list()):
    #Append this country to the processed countries list,
    #so we don't re-double over it
    processed_countries.append(self)
    possible_trips = dict()
    if self.get_connections(board):
        for i, card in enumerate(self.get_connections(board)):
            if card not in processed_countries:
                processed_connections.append((self, card))
                possible_trips[i] = card.get_longest_trip(board, 
                                                          processed_connections, 
                                                          processed_countries)
        if possible_trips:       
            longest_trip = []
            for i, trip in possible_trips.iteritems(): 
                trip_length = len(trip)
                if trip_length > len(longest_trip):
                    longest_trip = trip
            longest_trip.append(self)         
            return longest_trip
        else:
            print
            card_list = []
            card_list.append(self)
            return card_list
    else:
        #If no connections from start_card, just return the start card 
        #as the longest trip
        card_list = []
        card_list.append(board.start_card)
        return card_list

这里的问题与处理国家列表有关:如果查看我的第一个屏幕截图,您会看到发生的事情是当乌克兰走近时,它查看了最长路径的两个可能选择(马尔代夫-罗马尼亚或土耳其) ,保加利亚),看到他们都是平等的,便毫不犹豫地选择了一个。 现在匈牙利来了,它不能尝试通过罗马尼亚(实际上是最长的路径)建立一条道路,因为罗马尼亚已经被乌克兰添加到了处理国家列表中。

非常感谢您的帮助。 如果您能找到我的解决方案(递归与否),我很乐意向您捐款。

我已将完整的源代码(需要Python 2.6,Pygame 1.9)上传到:

http://www.necessarygames.com/junk/planes_trains.zip

相关代码位于src / main.py中,所有代码均已设置为可以运行。

您知道循环图中的最长路径问题是NP难的吗?

...罗马尼亚已被罗马尼亚添加到处理国家列表中。

为每个图形路径使用单独的processed_countries列表。 他们说一个代码示例值一千个单词,所以我对您的代码做了一些改动(未经测试):

def get_longest_trip(self, board, processed_countries = list()):
    # see https://stackoverflow.com/questions/576988/python-specific-antipatterns-and-bad-practices/577198#577198
    processed_countries = list(processed_countries)
    processed_countries.append(self)

    longest_trip = list()
    if self.get_connections(board):
        possible_trips = list()
        for card in self.get_connections(board):
            if card not in processed_countries:
                possible_trips.append(card.get_longest_trip(board, 
                                                            processed_countries))
        if possible_trips:
            longest_trip = max(possible_trips, key=len)
            longest_trip.append(self)

    if not longest_trip:
        longest_trip.append(self)
    return longest_trip

不相关的事项:

Traceback (most recent call last):
  File "main.py", line 1171, in <module>
    main()
  File "main.py", line 1162, in main
    interface = Interface(continent, screen, ev_manager)    
  File "main.py", line 72, in __init__
    self.deck = Deck(ev_manager, continent)
  File "main.py", line 125, in __init__
    self.rebuild(continent)  
  File "main.py", line 148, in rebuild
    self.stack.append(CountryCard(country, self.ev_manager))
  File "main.py", line 1093, in __init__
    Card.__init__(self, COUNTRY, country.name, country.image, country.color, ev_manager)  
  File "main.py", line 693, in __init__
    self.set_text(text)
  File "main.py", line 721, in set_text
    self.rendered_text = self.render_text_rec(text)  
  File "main.py", line 817, in render_text_rec
    return render_textrect(text, self.font, text_rect, self.text_color, self.text_bgcolor, 1)       
  File "/home/vasi/Desktop/Planes and Trains/src/textrect.py", line 47, in render_textrect
    raise TextRectException, "The word " + word + " is too long to fit in the rect passed."
textrect.TextRectException: The word Montenegro is too long to fit in the rect passed.

您的源程序包中有16个不同的bak文件。 十六。 Sixteeeen。 考虑一下并开始使用版本控制。

蛮力法:

  1. 创建一个深度优先的连接列表。 商店清单L及其长度T。

  2. 对于此列表的每个连接:

    • 推整个图
    • 删除连接。
    • 创建一个深度优先的连接列表。
    • 如果list的长度大于T:将T设置为length并将list设置为L,则递归调用2。
    • 流行整个图。
    • 返回

这应该为连接这些节点的所有可能方式创建一种洪水填充样式的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM