【问题标题】:Largest empty subgraph of an undirected graph in SWI PrologSWI Prolog中无向图的最大空子图
【发布时间】:2021-02-21 12:17:24
【问题描述】:

给出一个无向图。求图的内部稳定性数。这意味着找到最大空子图的幂。 (空子图是一个没有由边直接连接的顶点)。

我设置了边和顶点。我正在显示一个未连接边缘的顶点列表。

接下来我该怎么做?

reb(a,1,2).   % (* 1 ---a--- 2 ---b--- 3 ---d--- 4 ---e--- 6  *)
reb(b,2,3).   % (*  \_________c_______/                   /   *)
reb(c,1,3).   % (*                      7 ---g--- 5 ---f-*    *)
reb(d,3,4).                             
reb(e,4,6).
reb(f,5,6).
reb(g,5,7).

ver(1).   % (* empty subgraphs here are                   *)
ver(2).   % (*  145, 146, 147, 245, 246, 247, 35, 36, ... *)
ver(3).   % (* the length of the largest of them is 3     *)
ver(4).   
ver(5).
ver(6).
ver(7).

edge(A, B) :- reb(_,A,B) ; reb(_,B,A).

nonadjacency(A, B) :-
    ver(A), ver(B), \+(edge(A,B)).

do(L) :-
    findall( (A,B), nonadjacency (A,B), L), write(L), nl.

dfs(From, To, _, [edge(From, To)]) :-
    edge(From, To).

dfs(From, To, VisitedNodes, [(From, X) | TailPath]) :- 
    edge(From, X), 
    not(member(X, VisitedNode)),
    dfs(X, To, [From | VisitedNodes], TailPath).

【问题讨论】:

  • 我把“最”改成了“最大”,希望没问题。 (您可能已经从俄语中的某个术语翻译过来了)。 ----您的图没有未连接的子图,所有 7 个顶点都是连接的——如果我们将连通性视为 reb/3 关系的对称传递闭包。即 1--2--3--4--6--5--7。还是不是这样?你能告诉我们你的情况下的未连接子图吗?只是结果,而不是代码。
  • 这里的空子图是145、146、147、245、246、247、35、36、37,其中最大的长度是3
  • 为什么不是 167?它不会也被认为是“空子图”吗? “空子图”是否可以定义为“原始图的顶点集,使得原始图中没有边直接连接该集合中的任何顶点”? (只是想理解这个问题)
  • 是的,167,也是一个空子图
  • 我的 SWI-Prolog 在第 23 行报告语法错误,因为 nonadjacency (A,B) 中的空间非法,并且由于第 30 行的 VisitedNode 拼写错误,导致严重的单例变量警告。请更新问题.

标签: graph prolog undirected-graph


【解决方案1】:

与其自己努力构建非连接(你称之为“空”)子图,不如让 Prolog 为我们努力,构建一个最大的子集 not “非空”,即连接:

empty_subgraph(       E, M ) :-
    findall( X, ver(X), Vertices),
    subset( Vertices, E ),
    \+ is_connected(  E ),
    length(           E, M ).

is_connected(  E ) :-
    select( A, E, N ), 
    select( B,    N, _),
    \+ \+ ( reb(_,A,B) ; reb(_,B,A) ).   % an edge exists

使用select/3

剩下的就是枚举Vertices的子集,从大到小。

简单的代码行不通:

subset( S, S).
subset( S, X) :- select(_, S, N), subset( N, X).

你明白为什么吗?

。 . .

。 . .

答案是,Prolog 的深度优先搜索策略。为了在较短的子集之前获得较大的子集,我们需要广度优先搜索。必须自己编写代码:

subset( S, X) :- XS = [S|T], bfs_subsets(XS,T), member(X,XS).

bfs_subsets( [[] | _], []  ) :- !.
bfs_subsets( [[_]| _], [[]]) :- !.
bfs_subsets( [S  | T],   Q ) :-
    findall( N, select(_, S, N), NS ),
    append( NS,       Z, Q ),
    bfs_subsets(   T, Z ).

有很多多余的答案,但它们的产生顺序是我们想要的。先正确,后效率!生成的第一个答案将是最长的空子图中的一个,我们不在乎是哪一个。

70 ?- empty_subgraph( E, M ).
E = [3, 6, 7],
M = 3 ;
E = [3, 6, 7],
M = 3 ;
E = [2, 6, 7],
M = 3 ;
E = [2, 6, 7],
M = 3 ;
E = [2, 4, 7],
M = 3 ;
.......

欢迎您找到一种方法来消除重复项,或者更好的是,首先不要产生任何重复项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多