【问题标题】:Spanning Trees in Answer Set Programming答案集编程中的生成树
【发布时间】:2021-12-11 11:42:03
【问题描述】:

对于下面描述的无向图,我试图获取其生成树,然后将其叶子与内部节点分开。你能帮我写代码吗?

运行代码后我期望看到的是:

答案 1:spanTree(1,2)、spanTree(2,3)、spanTree(3,4)、leaf(1)、leaf(4)、internal(2)、internal(3)。

答案 2:spanTree(1,2)、spanTree(1,3)、spanTree(3,4)、leaf(2)、leaf(4)、internal(1)、internal(3)。

% undirected graph
edge(1,2).
edge(2,3).
edge(1,3).
edge(3,4).
vertex(X):- edge(X,Y).
vertex(X):- edge(Y,X).

%find spanning trees
spanTree(X,Y):- edge(X,Y).
spanTree(X,Y):- edge(Y,X).

start(1).

reached(X):-start(X).
reached(X):-reached(Y), spanTree(Y,X).
    
:-spanTree(X,Y), start(Y).
:-spanTree(X,Y), spanTree(X1,Y), X != X1.
:-vertex(X), not reached(X).

% degree of vertex
degree(X,D) :- vertex(X),D=#count {Y :spanTree(X,Y)}.

% leaves and internal vertices
{leaf(X):- spanTree(X,_),degree(X,D), D=1}:- vertex(X).
{internal(X):- spanTree(X,_),degree(X,D), D>1}:- vertex(X).

【问题讨论】:

    标签: graph logic-programming answer-set-programming spanning-tree


    【解决方案1】:

    除非必要,否则我会避免计数。我在开始时镜像边缘以实现无向图,并且猜测 spanTree 也很重要。我在这里做了一个捷径:不是说,一条边可能是一个跨树边,当“构建”时我说:对于每个节点(根节点除外),选择一个进入边作为跨树边。
    到达的部分几乎是复制和粘贴(这里做得很好),但我省略了前两个约束,因为它们已经被覆盖了。
    内部/叶子分类也可以简化。派生内部节点很容易,不作为内部节点可以覆盖叶子。

    edge(1,2). edge(2,3). edge(1,3). edge(3,4).
    % mirror edges
    edge(Y,X) :- edge(X,Y).
    vertex(X) :- edge(_,X).
    
    % every node Y except root has exactly one ingoing edge
    { spanTree(X,Y) : edge(X,Y) } == 1:- vertex(Y), not root(Y).
    
    root(1).
    reached(X) :- root(X).
    reached(X) :- reached(Y), spanTree(Y,X).
        
    :- vertex(X), not reached(X).
    
    % an internal node has an outgoing edge
    internal(X) :- spanTree(X,_).
    % a vertex which is not an internal is a leaf
    leaf(X) :- vertex(X), not internal(X).
    
    #show spanTree/2.
    #show leaf/1.
    #show internal/1.
    

    输出

    Answer: 1
    internal(3) leaf(2) leaf(4) internal(1) spanTree(3,2) spanTree(1,3) spanTree(3,4)
    Answer: 2
    internal(3) leaf(2) leaf(4) internal(1) spanTree(1,2) spanTree(1,3) spanTree(3,4)
    Answer: 3
    internal(3) leaf(4) internal(1) spanTree(1,2) internal(2) spanTree(2,3) spanTree(3,4)
    SATISFIABLE
    

    【讨论】:

    • 非常感谢.. 是的,这似乎效果更好.. 我不明白为什么“答案 3”中的顶点“1”是内部的而不是叶子..(它在生成树中的度数是1) @杜达
    • @john_b ... 1 是根。除非没有其他节点,否则它永远不是叶子。
    • 据我了解,叶子是没有子节点的节点。
    • 哦是的..你是对的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    相关资源
    最近更新 更多