Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 网络流算法_Algorithm - Fatal编程技术网

Algorithm 网络流算法

Algorithm 网络流算法,algorithm,Algorithm,我遇到了这样一个问题: 我们得到了一个二部图。例如 A1 B1 A2 B2 A3 B3 A4 这是邻接列表表示法(假设图是双向的) 最终结果应该是,左侧(As)中的所有节点正好有一条传入边,同时-我们需要最小化需要从单个Bs节点中传出的最大边数。在这种情况下,答案是: B3 can connect to A1 B2 can connect to A2, A4 B1 can connect to A3 B1 can connect to A1 B2 can connect to A4 B3 c

我遇到了这样一个问题:

我们得到了一个二部图。例如

A1 B1
A2 B2
A3 B3
A4
这是邻接列表表示法(假设图是双向的)

最终结果应该是,左侧(As)中的所有节点正好有一条传入边,同时-我们需要最小化需要从单个Bs节点中传出的最大边数。在这种情况下,答案是:

B3 can connect to A1
B2 can connect to A2, A4
B1 can connect to A3
B1 can connect to A1
B2 can connect to A4
B3 can connect to A3
B2 can connect to A2
因此,这里需要从单个Bs节点中删除的最大边数是2。我们不能覆盖所有As,同时有一个B节点没有两条边从它出来覆盖As

另一个例子:

A1 B1
A2 B2
A3 B3
A4 B4

B1 -> A1, A2, A3
B2 -> A1, A2, A3, A4
B3 -> A1, A2, A3
B4 -> A1, A2, A3
A1 B1
A2 B2
A3 B3
A4
A5
A6

B1 -> A6
B2 -> A1, A2, A3, A4, A5
B3 -> 
在这种情况下,答案是:

B3 can connect to A1
B2 can connect to A2, A4
B1 can connect to A3
B1 can connect to A1
B2 can connect to A4
B3 can connect to A3
B2 can connect to A2
通过这种方式,我们将一次准确地覆盖所有边界,同时我们将需要离开单个B的最大边数最小化。因此,此处需要从单个Bs节点中删除的最大边数为1

另一个例子:

A1 B1
A2 B2
A3 B3
A4 B4

B1 -> A1, A2, A3
B2 -> A1, A2, A3, A4
B3 -> A1, A2, A3
B4 -> A1, A2, A3
A1 B1
A2 B2
A3 B3
A4
A5
A6

B1 -> A6
B2 -> A1, A2, A3, A4, A5
B3 -> 
在这种情况下,答案为5,即需要从单个Bs中取出的边的最大数量为5。不能再少了

我已经实现了基本的ford fulkerson算法,我知道这也是网络流,但不知道如何与之关联

如果有人能给出一些关于图表的提示,那就太好了


感谢找到一个最佳的解决方案-所有B最多有一个输出边缘(如果存在)很简单:

while there is no coverage:
   set capacity(source,b_k) = increase_size() (for each b_k in B)
   run max flow algorithm on the graph suggested above
return last flow found
  • 将源和接收器添加到图形中。源将有一个输出 容量为1的边指向B列表上的所有顶点
  • 所有
    (B,A)
    边缘的容量为1
  • 所有A都有一个到水槽容量为1的外缘
  • 现在,运行流算法将产生最大数量的 A中每个B只能覆盖一个顶点的顶点 输出边缘(最佳解决方案,如果存在)

编辑:

现在,基于上述想法,并且由于您正试图将最大边数从单个B最小化为a(而不是如我之前所想的那样,将它们的总数最小化),因此最佳解决方案很简单:

while there is no coverage:
   set capacity(source,b_k) = increase_size() (for each b_k in B)
   run max flow algorithm on the graph suggested above
return last flow found

复杂性是
O(E*V*#迭代)
(在这个问题中
f将所有A连接到一个具有容量1边的公共汇聚节点。将所有B连接到一个具有可变容量边的公共源节点
C


在这个图中找到最大网络流量,当不是每个A都被覆盖时增加
C
,否则减少。这意味着使用二进制搜索找到
C
的最佳值。

谢谢你的回复Amit。这就是我的理解-在我构建了我的图之后(现在忽略二进制搜索,我将使用线性:-))-假设有三个Bs,因此震源连接到B1、B2和B3。我应该将震源的边缘容量:B1设置为1-运行最大流量-查看覆盖了多少As-然后将震源的边缘容量:B2设置为1-运行最大流量-查看覆盖了多少As然后震源:B3到1然后震源:B1到2震源:B2到2然后震源:B3到2!是这样吗?如果我有一个图,其中每个B连接到每个a呢?在这种情况下,只要我第一次运行最大流算法,所有a都将被覆盖。但是在这种情况下,答案是1,即每个B只需要连接到1A就可以覆盖所有内容!如果我遗漏了什么,请告诉我。谢谢。@VVV:不,set在第一次迭代中,B的所有边的容量均为1:(源B1),(源B2),(源B3)-在第一次迭代中,所有边都设置为1。在第二次迭代中,所有边都设置为2,在第三次迭代中设置为3,…。@VVV:如果有一个B连接到所有a,如果到该B的流设置为1(按原样),它最多可以覆盖1A。是的,你是对的。我想得不够。即使我们有一个B节点连接到所有节点,就好像从源到B的边权重是1一样,但只能覆盖1A。好的,我将实现这一点,看看它是如何进行的。感谢你的时间和帮助。感谢Evgeny Kluev的时间!你能解释一下你所说的增量是什么意思吗在这里放松容量?如果我有一个图,其中所有B连接到所有a,并且我将C设置为1作为连接源节点到某个B节点的边的1,所有边都将被覆盖。但是,在这种情况下,答案是1,因为每个B只需要连接到1 a。谢谢。因为您已经从amit得到了这个解释,我将只添加一些关于二进制搜索的详细信息。对于第一次迭代,您可以将
C
设置为某个期望值,例如,2。然后应用单面二进制搜索并增加
C
,如下所示:2->4->8->16…一旦覆盖了所有As,您就继续进行常规二进制搜索:8->6->5。或者,您可以跳过单面搜索,将
C
设置为As的数量并执行正常的二进制搜索。