简体   繁体   English

在图中找到最短的三角形

[英]Find shortest triangle in a graph

I have a set of points and need to select an optimal subset of 3 of them, where the criterion is a linear sum of some properties of the points, and some properties of pairs of the points.我有一组点,需要 select 其中 3 个的最佳子集,其中标准是点的某些属性和点对的某些属性的线性和。

In Python, this is quite easy using itertools.combinations :在 Python 中,使用itertools.combinations非常容易:

all_points = combinations(points, 3)
costs = []
for i, (p1, p2, p3) in enumerate(all_points):
    costs.append((p1.weight + p2.weight + p3.weight
                  + pair_weight(p1, p2) + pair_weight(p1, p3) + pair_weight(p2, p3),
                 i))
costs.sort()
best = all_points[costs[0][1]]

The problem is that this is a brute force solution, requiring to enumerate all possible combinations of 3 points, which is O(n^3) in the number of points and therefore easily leads to a very large number of evaluations to perform.问题在于这是一个蛮力解决方案,需要枚举 3 个点的所有可能组合,点数为 O(n^3),因此很容易导致需要执行非常大量的评估。 I have been trying to research whether there is a more efficient way to do this, perhaps taking advantage of the linearity of the cost function.我一直在尝试研究是否有更有效的方法来做到这一点,或许可以利用成本 function 的线性。

I have tried turning this into a networkx graph featuring node and edge weights.我试过将其转换为具有节点和边权重的networkx图。 However, I have not yet found an algorithm in that toolkit that can calculate the "shortest triangle", particularly one that considers both edge and node weights.但是,我还没有在该工具包中找到可以计算“最短三角形”的算法,尤其是同时考虑边和节点权重的算法。 (Shortest path algorithms tend to only consider edge weights for example.) (例如,最短路径算法往往只考虑边权重。)

There are functions to enumerate all cliques, and then I can select 3-cliques, and calculate the cost, but this is also brute force and therefore not better than doing it with combinations as above.有枚举所有集团的功能,然后我可以 select 3 集团,并计算成本,但这也是蛮力,因此并不比用上面的combinations更好。

Are there any other algorithms I can look at?我可以看看其他算法吗?

By the way, if I do not have the edge weights, it is easy to just sort the nodes by their node-weight and choose the first three.顺便说一句,如果我没有边权重,很容易按节点权重对节点进行排序并选择前三个。 So it is really the paired costs that add complexity to this problem.因此,实际上是成对成本增加了这个问题的复杂性。 I am wondering if somehow I can just list all pairs and find the top-k of those that form triangles, or something better?我想知道我是否可以以某种方式列出所有对并找到形成三角形的那些对的前 k 个,或者更好的东西? At least if I could efficiently enumerate top candidates and stop the enumeration on some heuristic, it might be better than the brute force approach.至少,如果我能够有效地枚举最佳候选人并停止某些启发式的枚举,它可能比蛮力方法更好。

From now on, I will use n as the number of nodes and m as the number of edges.从现在开始,我将使用n作为节点数, m作为边数。 If your graph is fully connected, then m is just n choose 2. I'll also disregard node weights, because as the comments to your initial post have noted, the node weights can be absorbed into the edges they're connected to.如果您的图是完全连接的,那么m只是n选择 2。我也会忽略节点权重,因为正如您对初始帖子的评论所指出的那样,节点权重可以吸收到它们所连接的边中。

Your algorithm is O(n^3) ;你的算法是O(n^3) it's hopefully not too hard to see why: You iterate over every possible triplet of nodes.希望不难看出原因:您遍历每个可能的节点三元组。 However, it is possible to iterate over every triangle in a graph in O(m sqrt(m)) :但是,可以在O(m sqrt(m))中迭代图中的每个三角形:

for every node u:
    for every node v adjacent to u:
        if degree(u) < degree(v): continue;
        for every node w adjacent to v:
            if degree(v) < degree(w): continue;
            if u is not connected to w: continue;
            // <u,v,w> is a triangle!

The proof for this algorithm's runtime of O(m sqrt(m)) is nontrivial, so I'll direct you here: https://cs.stanford.edu/~rishig/courses/ref/l1.pdf该算法的O(m sqrt(m))运行时间的证明非常重要,因此我将在此处指导您: https://cs.stanford.edu/~rishig/courses/ref/l1.pdf

If your graph is fully connected, then you've gotta stick with the O(n^3) , I think.如果你的图是完全连接的,那么我认为你必须坚持使用O(n^3) There might be some early-pruning ideas you can do but they won't lead to a significant speedup, probably 2x at very best.您可能有一些早期修剪的想法,但它们不会带来显着的加速,最多可能是 2 倍。

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

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