簡體   English   中英

功能需要很長時間

[英]Function takes a long time

我目前正在嘗試從節點1獲得唯一路徑的數量..加權有向無環圖的最大長度為N,我已經計算出最大長度,但是我堅持要獲取給定路徑的數量最長長度...

數據輸入如下:

91 120  # Number of nodes, number of edges

1 2 34

1 3 15

2 4 10

....作為權重為34的節點1->節點2,

I input my data using a diction so my dict looks like:
_distance = {}
_distance = {1: [(2, 34), (3, 15)], 2: [(4, 10)], 3: [(4, 17)], 4: [(5, 36), (6, 22)], 5: [(7, 8)],...ect

我已經解決了如何使用以下方法實現路徑的最長長度:

首先,我列出頂點

class Vertice:
    def __init__(self,name,weight=0,visted=False):
        self._n = name
        self._w = weight
        self._visited = visted
        self.pathTo

for i in range(numberOfNodes): # List of vertices (0-n-1)
  _V = Vertice(i) 
  _nodes.append(_V)

接下來,我遍歷字典將每個節點設置為最大權重

        for vert, neighbors in _distance.iteritems():
        _vert = _nodes[vert-1] # Current vertice array starts at 0, so n-1


        for x,y in neighbors:  # neighbores,y = weight of neighbors
            _v = _nodes[x-1]   # Node #1 will be will be array[0]

            if _v._visited == True:
                if _v._w > _vert._w+y:
                    _v._w = _v._w
                else:
                    _v._w = y + _vert._w

            else:

                _v._w = y + _vert._w
                _v._visited = True

完成此操作后,最后一個節點將具有最大權重,因此我可以調用

max = _nodes[-1]._w

以獲得最大重量。 這似乎執行起來很快,即使在更大的數據集上執行,也沒有發現最大長度路徑的麻煩,然后我取最大值並將其運行到此函數中:

#  Start from first node in dictionary, distances is our dict{}
#  Target is the last node in the list of nodes, or the total number of nodes.
numLongestPaths(currentLocation=1,target=_numNodes,distances=_distance,maxlength=max)

def numLongestPaths(currentLocation,maxlength, target, sum=0, distances={}):


    _count = 0

    if currentLocation == target:
        if sum == maxlength:
                _count += 1

    else:
        for vert, weight in distances[currentLocation]:
            newSum = sum + weight
            currentLocation = vert
            _count += numLongestPaths(currentLocation,maxlength,target,newSum,distances)

    return _count

我只是簡單地檢查一下是否到達當前節點,如果當前總和是最大值,如果沒有,將其加一。

這對於輸入(例如8個節點,最長路徑為20,找到3條路徑)立即起作用,對於輸入(例如100個節點,最長長度為149,並且只有該長度的唯一路徑),但是當我嘗試做一個數據集時擁有91個節點,例如最長路徑1338和唯一路徑數為32,該函數占用的時間非常長,但運行起來很慢。

有人可以給我一些提示,告訴我我的函數有什么問題,導致它花很長時間從1..N中查找長度為X的路徑數嗎? 我假設它獲得了指數級的運行時間,但是我不確定如何解決它

謝謝您的幫助!

編輯:好的,我對此進行了過度思考,並以錯誤的方式進行處理,我重新構造了方法,現在的代碼如下:

# BEGIN SEARCH.
    for vert, neighbors in _distance.iteritems():
        _vert = _nodes[vert-1] # Current vertice array starts at 0, so n-1


        for x,y in neighbors:  # neighbores

            _v = _nodes[x-1]   # Node #1 will be will be array[0]

            if _v._visited == True:
                if _v._w > _vert._w+y:
                    _v._w = _v._w
                elif _v._w == _vert._w+y:
                        _v.pathsTo += _vert.pathsTo
                else:
                    _v.pathsTo = _vert.pathsTo
                    _v._w = y + _vert._w

            else:

                _v._w = y + _vert._w
                _v.pathsTo = max(_vert.pathsTo, _v.pathsTo + 1)
                _v._visited = True

我在Vertice類中添加了一個pathsTo變量,該變量將保留最大長度為MAX的唯一路徑

您的numLongestPaths速度很慢,因為您要遞歸地嘗試所有可能的路徑,並且其中的指數可能會成倍增加。 找到一種避免numLongestPaths計算任何節點的numLongestPaths的方法。

同樣,您原始的_w計算也被破壞了,因為當它計算節點的_w值時,它不會做任何事情來確保自己依賴的其他_w值已經被計算出來。 您將需要避免使用未初始化的值。 拓撲排序可能有用,盡管聽起來頂點標簽可能已經按照拓撲排序順序進行了分配。

除了@ user2357112的答案,這里還有兩個其他建議

語言

如果您希望此代碼盡可能高效,我建議使用C。Python是一種很棒的腳本語言,但是與編譯后的替代品相比確實很慢

數據結構

節點以有序的方式命名,因此您可以使用列表而不是字典來優化代碼。

_distance = [[] for i in range(_length)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM