我正在用 C# 4.0 编写一个程序,我将其抽象为以下内容(我提到了该语言,以便您知道我必须使用哪些库;没有第三方库):
让S = { s1, s2, s3, ..., sn }.
对于所有si,sj在S, i != j, 函数f(si, sj)是 的一个元素{ true, false }。调用这个函数f非常昂贵,但是应该尽可能少地调用。
给定集合T = { t1, t2, t3, ..., tm }的一个非空子集S,计算一个序列,该序列U = u1, u2, u3, ..., uo包含 的所有元素T,f(ui, uj) == false对于 all i < j,f(ui, s') == false对于 alli和s'in S - U。您可以假设存在这样的序列。
虽然这与学校无关(这是为了工作),但我更希望得到最少的帮助,让我找到你能想到的最佳解决方案,这样我就可以了解更多:)
提示(一些我想过的东西:)
您需要至少访问每个节点一次。在and中 考虑
T = { t }andf(t, s') == false的情况。在这种情况下,一次也足够了。s'S - T|S| >= 2最少
U必须计算。这种计算可以用以下形式表示: 一个|S|x|S|邻接矩阵,其条目为?: 我不知道1: 取决于。0: 不依赖。-: 我不在乎。
考虑一下这一点(我正在通过一个示例来查看是否存在最佳潜在检查序列的模式以帮助开发算法)。 S = { a, b, c, d, e } T = { a, b, c }(由星星表示):
a b c d e
----------------
*a | - - - ? ?
*b | - - - ? ?
*c | - - - ? ?
d | - - - - ?
e | - - - ? -
U = { a, b, c }最初。对角线是-因为f在其操作数相等时未定义。由于a和已经在集合中,b因此c是否有人依赖它们并不重要,因此-.
f(a, d)由于对称性,f(a, e), , f(b, d), f(b, e), f(c, d),f(c, e)都是平等的候选者。假设我们选择f(a, d)它返回 false。我们的表格现在看起来像这样:
a b c d e
----------------
*a | - - - 0 ?
*b | - - - ? ?
*c | - - - ? ?
d | - - - - ?
e | - - - ? -
情况1:U = { a, b, c }
要找出这一点,我们可以通过 3 次检查来做到这一点,如果幸运的话,检查f(b, d), f(c, d)并且f(e, d)让它们都成为false。
案例二:U = { a, b, c, d, e }
要找出这一点,我们可以通过 2 次检查来完成,如果幸运的话,检查f(b, d)并f(a, e)让它们都返回true。
(我还没有完全想好这些,我要去吃饭了。感谢大家阅读!)
案例3:U = { a, b, c, d }
案例4:U = { a, b, c, e }