我需要一些帮助来找到这个问题的Java算法:
让A类和B类之间有链接。
现在我有下表:
Table with links between A and B
X表示An和Bn之间存在链接
现在的问题是我如何找到最小的B组来“击中”所有A的 例如,如果我为贪婪算法实现它,它将需要B3,因为它具有到A的最多链接,然后搜索其他来填充其余的。这会给我一套3 B。但我需要一个算法来取B4和B5,因为它是最小的集合。
我想问你的问题是,这个问题的优秀算法是什么?针对这类问题,是否存在“流行”算法?我认为这就像是一个Hitting-Set问题,但是我无法从中获得图形表示。搜索这个问题也很难,因为我不知道名称或类似技术术语的东西。
提前感谢您的帮助。
答案 0 :(得分:0)
问题是NP完整,因此没有已知的简单(确切)解决方案可以保证快速。
如果您的示例很小,您可以简单地枚举B
的所有子集,并选择涵盖A
的最小子集。显然,即使在最好的情况下也是如此。
更好的方法是以存在合理解算器的不同形式表达问题。一种这样的形式是整数线性程序。
这是一个代表你的例子的整数线性程序。
Minimize
obj:b1+b2+b3+b4+b5
Subject To
b1+b2+b3+b4 >= 1
b2+b4 >= 1
b3+b5 >= 1
b1+b2+b3+b4 >= 1
b1+b2+b3+b4+b5 >= 1
b3+b4 >= 1
b5 >= 1
Bounds
0 <= b1 <= 1
0 <= b2 <= 1
0 <= b3 <= 1
0 <= b4 <= 1
0 <= b5 <= 1
End
&#34;最小化&#34;子句捕获了您希望尽可能小的解决方案的想法。 i
&#34;主题为&#34;子句约束解决方案以覆盖A[i]
。 (注意:某些约束是重复的,因为在您的示例中,某些A
与B
s的完全相同的集合相邻。
GLPK(或许多其他整数线性程序求解器)可以解决这个问题,甚至更大的例子。还有一些与解算器接口的Java库。
您可以在此处在线运行:http://hgourvest.github.io/glpk.js/
输出结果为:
GLPK Simplex Optimizer, v4.49
7 rows, 5 columns, 20 non-zeros
Preprocessing...
4 rows, 4 columns, 12 non-zeros
Scaling...
A: min|aij| = 1 max|aij| = 1 ratio = 1
Problem data seem to be well scaled
Constructing initial basis...
Size of triangular part = 4
0: obj = 1 infeas = 4 (0)
*1: obj = 2 infeas = 0 (0)
*2: obj = 2 infeas = 0 (0)
OPTIMAL SOLUTION FOUND
{"b1":0,"b2":0,"b3":0,"b4":1,"b5":1}
在最后一行,您可以看到最佳解决方案是b4=b5=1
,对应最小的集{B4, B5}
。
答案 1 :(得分:-1)
你有没有尝试过所有的贪心算法?您需要了解如何将您的命中映射到算法。我认为这个链接会帮助你很多
http://www.geeksforgeeks.org/greedy-algorithms-set-6-dijkstras-shortest-path-algorithm/
尝试使用邻接列表表示