Python 寻找数据帧中两点之间具有最高平均边值的路径的有效方法?

Python 寻找数据帧中两点之间具有最高平均边值的路径的有效方法?,python,pandas,numpy,graph,networkx,Python,Pandas,Numpy,Graph,Networkx,请原谅这个问题看似混乱的措辞。这是我想做的 给定数据帧df Fruit1 Fruit2 Weight orange apple 0.2 orange grape 0.4 orange pineapple 0.6 orange banana 0.8 apple grape 0.9 apple pineapple 0.3 apple banana 0.2 g

请原谅这个问题看似混乱的措辞。这是我想做的

给定数据帧df

Fruit1     Fruit2      Weight
orange     apple       0.2
orange     grape       0.4
orange     pineapple   0.6
orange     banana      0.8
apple      grape       0.9
apple      pineapple   0.3
apple      banana      0.2
grape      pineapple   0.1
pineapple  banana      0.8
以及对允许的最大路径长度的约束,L

我希望返回具有最高平均路径的数据帧(即点/路径长度之间所有边的总和为最大值),其中边由权重列表示,前提是它不超过长度L

用一个例子来说明我所说的最高平均路径:

假设我们只有4个点A、B、C和D。我们感兴趣的是找到A和D之间的最高平均路径

在L=3的情况下,最高平均路径为max((A->D)/1,(A->B+B->D)/2,(A->C+C->D)/2,(A->B+B->C+C->D)/3,(A->C+C->B+B->D)/3)

对于L=2,它将是最大值((A->D)/1,(A->B+B->D)/2,(A->C+C->D)/2)

对于df,对于L=2,我们会得到

Fruit1     Fruit2      Weight   MaxAvgPath(L=2)
orange     apple       0.2       [orange, grape, apple]  
orange     grape       0.4       [orange, apple, grape]
orange     pineapple   0.6       [orange, banana, pineapple]
orange     banana      0.8       [orange, banana]
apple      grape       0.9       [apple, grape]
apple      pineapple   0.3       [apple, grape, pineapple]
apple      banana      0.2       [apple, pineapple, banana] 
grape      pineapple   0.1       [grape, orange, pineapple]
grape      banana      0.1       [grape, apple, banana]
pineapple  banana      0.8       [pineapple, banana]

注意:此边集包含的行仅足以表示整个网络。例如,虽然(橙色,苹果)存在,(苹果,橙色)不存在,因为(苹果,橙色)的重量是相同的。但是,如果包含这些内容有助于创建解决方案,请随意使用它们,并在最终输出中忽略它们。镜像对的返回路径应等于原始对的返回路径。

感谢您的澄清,因此您要求的是图中每对节点之间成本最高/(边数)的路径,其中路径限制在连接边的上限。最长路径问题是np难问题,因此只有在有限制的情况下才有可能得到有效的解 (见附件)。我认为你们对边缘连接的限制人为地加强了一条长度为L的最长路径,所以可以把它降到指数级

networkx模块可以通过深度优先搜索找到简单路径,我们可以通过手动求和权重和排序对路径进行排序。我们可以对每对节点执行此操作,并将其作为新系列添加到数据帧中

import pandas
import networkx

# Create a graph from the dataframe
G = networkx.from_pandas_dataframe(path_frame, 'Fruit1', 'Fruit2', 'Weight')

# Find the longest path between source and target up to length L
def maxpath_cond(G, source, target, edge_attr, L=None):
    #Use networkx simple paths function which uses a depth first search
    paths = networkx.simple_paths.all_simple_paths(G,source, target, L)
    # Calculate and sort the costs of the path
    costs = [(pathcost(G, pth, edge_attr), pth) for pth in paths]
    return sorted(costs, key=lambda x:x[0], reverse=True)

def pathcost(G,path, edge_attr):
    lp = len(path)-1
    return sum(G[path[n]][path[n+1]][edge_attr] for n in range(lp))/lp
#Iterate through the dataframe and create a new series made up of long paths
mxs = []
for n in range(len(path_frame)):
    src, targ = path_frame.loc[n]['Fruit1'], path_frame.loc[n]['Fruit2']
    mxl = maxpath_cond(G, src, targ, 'Weight', 2)[0]
    mxs.append( mxl[1])

print(path_frame.assign(MaxAvgPath=mxs))
哪些产出:

      Fruit1     Fruit2  Weight                   MaxAvgPath
0     orange      apple     0.2       [orange, grape, apple]
1     orange      grape     0.4       [orange, apple, grape]
2     orange  pineapple     0.6  [orange, banana, pineapple]
3     orange     banana     0.8             [orange, banana]
4      apple      grape     0.9               [apple, grape]
5      apple  pineapple     0.3    [apple, grape, pineapple]
6      apple     banana     0.2   [apple, pineapple, banana]
7      grape  pineapple     0.1    [grape, apple, pineapple]
8  pineapple     banana     0.8          [pineapple, banana]

真的不能这样对待熊猫。使用其他类似BFS或Dijkstra的alg…当然,不涉及pandas操作的解决方案也会起作用,只要我能轻松地将它们恢复到pandas数据帧。此外,如果存在频繁的子模式,像BFS这样的东西不是一个简单的解决方案吗?