如何找到最小化边数的方法?

时间:2014-09-18 06:42:15

标签: algorithm graph graph-algorithm

我正在考虑一种解决以下问题的算法:

  

由顶点和边组成的给定图形。

     

有N个客户想要从顶点行进到另一个顶点。   每个客户需求都需要一个有向边来连接两个顶点。

     

问题是如何找到满足所有客户要求的最小边数?

有一个简单的例子:

  • 客户1想要从顶点a行进到顶点b。
  • 客户2想要从顶点b行进到顶点c。
  • 客户3想要从顶点a行进到顶点c。

最简单的方法是为每位客户提供优势:

  • 边缘1:顶点a - > vertex b
  • 边缘2:顶点b - > vertex c
  • 边缘3:顶点a - > vertex c

但实际上只需要2个边缘(即边缘1和边缘2)来满足三个客户要求。

如果客户数量很大,如何找到最小边缘以满足所有客户要求?

有没有算法来解决这个问题?

5 个答案:

答案 0 :(得分:0)

您可以将问题建模为混合整数程序。您可以为" arc a->定义二进制变量。 b用于"和"客户c使用arc a - > B"并将要求记为线性不等式。如果您的图形不是太大,您可以通过混合整数程序求解器(CPLEX,GUROBI,但在网络上也有免费的替代方案)在合理的时间内解决此类模型。

我知道如果您不熟悉线性编程,这个解决方案需要一些工作,但它保证在有限时间内找到最佳解决方案,您可以为(例如)1000个客户和1000个弧解决它。

答案 1 :(得分:0)

如果您有N个顶点,则始终可以构造具有N(有向)边的解。只需创建一个有向循环V_1 - > V_2 - > V_3 - > ... - > V_N - > V_1。你永远不会有从每个顶点V_a到具有较少边缘的每个其他顶点V_b的定向路径(因为你有一个必须包含叶子的有向树)。叶子是不可达的(如果边缘从叶子出来)或叶子是一个接收器(不能连接到其他任何东西)如果边缘是 - >叶子。

答案 2 :(得分:0)

无需使用任何新算法。您可以使用BFS / DFS算法。

Find if there exists any path between source and destination.
   if !true
      add a direct edge between source and destination
      count++;
return count; 

这里的关键部分是循环遍历图形,而不是循环通过新添加的边。

答案 3 :(得分:0)

您可以使用Disjoint set data structure。

https://en.wikipedia.org/wiki/Disjoint-set_data_structure

while (num_edges--)
    if root(vertex_a) != root(vertex_b)
    count++
    union(vertex_a,vertex_B)

答案 4 :(得分:0)

如果我想到无向边的相同问题,我们要寻找的是原始图的minimum spanning tree(MST)(由所有边构成)。简要说明是,对于每个边E(v1 - > v2),如果存在从v1到v2的第二条路径,则存在一个循环,并且对于每个现有循环,存在我们可以省略的边。

要查找有向图的MST,您可以使用Chu–Liu/Edmonds' algorithm

请注意,您要为所有边缘指定权重1。