二维顶点子集的拓扑排序

时间:2012-08-16 19:13:40

标签: c# algorithm graph-theory directed-graph directed-acyclic-graphs

我正在用C#4.0编写一个程序,我已将其抽象为以下内容(我提到了这种语言,以便您知道我必须使用哪些库;没有第三方库):


S = { s1, s2, s3, ..., sn }

对于si中的所有sjSi != j,函数f(si, sj){ true, false }的元素。调用此函数f非常昂贵,但应该尽可能少地完成。

如果将T = { t1, t2, t3, ..., tm }设置为S的非空子集,请计算一个序列U = u1, u2, u3, ..., uo,其中包含T的所有元素,以便f(ui, uj) == false为所有对于i < j中的所有f(ui, s') == falseis'S - U。您可以假设存在这样的序列。


虽然这与学校没有任何关系(这是为了工作),但我更喜欢最少的帮助让我找到你能想到的最佳解决方案,所以我可以了解更多:)


提示(我想过的一些东西:)

  1. 您需要至少访问一次每个节点。考虑T = { t }f(t, s') == false的情况s' S - T }和|S| >= 2。在这种情况下,一次就足够了。

  2. 必须计算最小U。该计算可以由以下表示:|S|x|S|邻接矩阵,其条目为

    • ?:我不知道
    • 1:取决于。
    • 0:不依赖。
    • -:我不在乎。
  3. 考虑一下(我正在通过一个例子来看看是否有最佳潜在检查序列的模式来帮助开发算法)。 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。由于abc已经在集合中,因此如果有人依赖它们并不重要,因此-

    由于对称性,

    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 }

    要找到这一点,我们可以通过检查f(b, d)f(c, d)f(e, d)并让它们全部为{{1}来进行3次检查,如果幸运的话}。

    案例2:false

    要找到这个,如果我们运气好的话,我们可以通过检查U = { a, b, c, d, e }f(b, d)并让他们都返回f(a, e)来进行2次检查。

    (我完全没想过这些,但我需要去吃饭。感谢所有人的阅读!)

    案例3:true

    案例4:U = { a, b, c, d }

1 个答案:

答案 0 :(得分:-1)

我所理解的是,您希望所有可以访问的节点从子集T中的任何节点开始...如果这是您的意思,您可以尝试这个...

  1. 使用所有节点填充字典(将节点作为Key并将bool作为值访问(将此值作为false))
  2. 使用子集T中的节点填充队列(当您添加它们时,在字典中搜索它们并将其标记为已访问)
  3. 选择队列中的第一个元素,您可以从中检查节点,搜索是否在字典中访问,如果访问是否跳过,如果没有,则将它们添加到队列并将其设置为访问,删除第一个元素队列
  4. 重复3,直到队列中没有项目
  5. 您可以从t开始访问的节点子集是您在词典中标记的节点

    希望它有所帮助...