Algorithm 我怎样才能找到一种使边数最小化的方法?

Algorithm 我怎样才能找到一种使边数最小化的方法?,algorithm,graph,graph-algorithm,Algorithm,Graph,Graph Algorithm,我正在考虑一种算法来解决以下问题: 由顶点和边组成的给定图 有N个客户希望从一个顶点移动到另一个顶点。 每个客户需求都需要一条有向边来连接两个顶点 问题是如何找到满足所有客户要求的最小边数 有一个简单的例子: 客户1希望从顶点a移动到顶点b 客户2希望从顶点b移动到顶点c 客户3希望从顶点a移动到顶点c 最简单的方法是为每个客户提供优势: 边1:顶点a->顶点b 边2:顶点b->顶点c 边3:顶点a->顶点c 但实际上只需要两条边(即边1和边2)即可满足三个客户需求 如果客户数量很大,如

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

由顶点和边组成的给定图

有N个客户希望从一个顶点移动到另一个顶点。 每个客户需求都需要一条有向边来连接两个顶点

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

有一个简单的例子:

  • 客户1希望从顶点a移动到顶点b
  • 客户2希望从顶点b移动到顶点c
  • 客户3希望从顶点a移动到顶点c
最简单的方法是为每个客户提供优势:

  • 边1:顶点a->顶点b
  • 边2:顶点b->顶点c
  • 边3:顶点a->顶点c
但实际上只需要两条边(即边1和边2)即可满足三个客户需求

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


有解决这个问题的算法吗?

您可以将问题建模为一个混合整数程序。您可以为“使用弧a->b”和“客户c使用弧a->b”定义二进制变量,并将要求写为线性不等式。如果你的图形不是太大,你可以在合理的时间内用一个混合整数程序求解器(CPLEX,GUROBI,但网上也有免费的替代方案)来求解这些模型


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

如果你有N个顶点,你总是可以用N条(有向)边构造一个解决方案。只需创建一个有向循环V_1->V_2->V_3->…->V_N->V_1。从每个顶点V_a到每个其他顶点V_b的有向路径不能有较少的边(因为有向树必然包含一片叶子)。如果叶是->叶,则叶是不可访问的(如果边缘从叶向外),或者叶是接收器(无法连接到其他任何东西)。

无需使用任何新算法。您可以使用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; 

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

可以使用不相交集数据结构


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

对于查找有向图的MST,您可以使用


请注意,您正在为所有边指定权重1。

是的,图形中的每条边都是有向边!这是我的错,我应该强调给定的图是有向图,这是一个传递归约问题。我很确定你的意思是“每个客户需求都需要一条连接两个顶点的有向路径”。如果你真的是指“有向边”,那么这个问题很简单,你的示例问题的答案需要所有3条边。实际上,我只想最小化边的数目,并确保可达性不变。传递约简可能不是答案。如果我们有像a->b,a->c,b->d,c->d这样的客户需求,那么传递归约保持所有客户弧,而三个弧a->b,b->c,c->d产生同样多的连通性。如果我们只能建立一些客户所要求的弧,那么我们就不需要传递约简,而是需要一个最小等价子图(如果有循环,则很难找到NP)。
while (num_edges--)
    if root(vertex_a) != root(vertex_b)
    count++
    union(vertex_a,vertex_B)