图 练习 4

转载自:https://mp.weixin.qq.com/s/QHLodTI9LDrapgCtVs1Wng

上一练习中所需文件p6_04.dat的内容:

graph([a, b, c, d, e, f, g, h], [e(a, b), e(a, d), e(b, c), e(b, e), e(c, e), e(d, e), e(d, f), e(d, g), e(e, h), e(f, g), e(g, h)]).

 

5、构造标记图的最小生成树

ms_tree(G,T,S) :- T是图G的最小生成树。S是边值的总和。 Prim的算法。

程序p6_05.pl

1  :- ensure_loaded(p6_01).  %图 练习 1的转换程序

2  :- ensure_loaded(p6_04).  %transfer/3, incident/3, and accept/3

3

4  ms_tree(graph([N|Ns],GraphEdges),graph([N|Ns],TreeEdges),Sum) :- 

5 predsort(compare_edge_values,GraphEdges,GraphEdgesSorted),

6 transfer(Ns,GraphEdgesSorted,TreeEdgesUnsorted),

7 sort(TreeEdgesUnsorted,TreeEdges),

8 edge_sum(TreeEdges,Sum).

9

行注释:

1.  载入图 练习1中程序

2.  载入图 练习3中标题序号为4的程序

3.  空行

4.  GraphEdges是图列表[N|Ns]的最小生成树,Sum是边值的总和

5.  按谓词compare_edge_values规则对列表GraphEdges排序排好序的列表为GraphEdgesSorted

6.  参看图 练习3中’4’

7.  将TreeEdgesUnsorted排序结果放入TreeEdges

8.  计算TreeEdges的边的总和,放入Sum

9.  

 

10 compare_edge_values(Order,e(X1,Y1,V1),e(X2,Y2,V2)) :- 

11 compare(Order,V1+X1+Y1,V2+X2+Y2).

12

13 edge_sum([],0).

14 edge_sum([e(_,_,V)|Es],S) :- 

15 edge_sum(Es,S1), 

16 S is S1 + V. 

17

行注释:

10. 

11. 内置谓词:确定标准项中两个项之间的顺序(Order)。顺序(Order)是<,>或=之一,其含义很明显。

12. 

13. 终止条件

14. 

15. 继续递归

16. S是S1+V

17. 

 

18 test :-  

19 see('p6_05.dat'), 

20 read(G), 

21 seen,

22 human_gterm(H,G),

23 write(H), nl

24 ms_tree(G,T,S),

25 human_gterm(TH,T),

26 write(S), nl,

27 write(TH).

行注释:

18. 

19. 将输入流转到文件’p6_05.dat’

20. 读取的结果放入G

21. 将输入流转回原输入流

22. 参看图 练习1

23. 输出H

24. 将G转为T(最小生成树)S为边值的总和

25. 将T转为TH(与H比较下)

26. 输出S

27. 输出TH

 

内置谓词predsort/3: 排序类似于sort / 2,但通过调用Pred(-Delta,+ E1,+ E2)确定两个项的顺序。该调用必须将Delta与<,>或=中的一个统一。如果使用内置谓词compare / 3,则结果与sort / 2相同。另请参阅keysort / 2。

所需文件p6_05.dat的内容:

graph([a, b, c, d, e, f, g, h], [e(a, b, 5), e(a, d, 3), e(b, c, 2), e(b, e, 4), e(c, e, 6), e(d, e, 7), e(d, f, 4), e(d, g, 3), e(e, h, 5), e(f, g, 4), e(g, h, 1)]).

 

测试:

?- test.

[a-b/5,a-d/3,b-c/2,b-e/4,c-e/6,d-e/7,d-f/4,d-g/3,e-h/5,f-g/4,g-h/1]

22

[a-b/5,a-d/3,b-c/2,b-e/4,d-f/4,d-g/3,g-h/1]

true .

 

 

 

6、同构图

这仅是图的解决方案。为有向图写相应的谓词并不困难

程序p6_06.pl

1  :- ensure_loaded(p6_01).  % conversions

2

% isomorphic(G1,G2) :- 图G1和G2是同构的

 

3  isomorphic(G1,G2) :- 

4 isomorphic(G1,G2,_). 

5

行注释:

1.  载入图 练习1中程序

2.  

3.  

4.  常用编程技巧

5.  

 

% isomorphic(G1,G2,Iso) :- 图G1和G2是同构的。 

% Iso是代表图的节点集之间的双射的列表。它是一个开放式列表,包含每对对应节点的i(X,Y)项

6  isomorphic(graph(Ns1,Es1),graph(Ns2,Es2),Iso) :-

7 append(Es1,Ns1,List1),

8 append(Es2,Ns2,List2),

9 isomo(List1,List2,Iso).

10

% isomo(List1,List2,Iso) :- List1和List2表示的图是同构的。 

行注释:

6.  

7.  内置谓词

8.  内置谓词

9.  List1和List2表示的图是同构的

10. 

 

11 isomo([],[],_) :- !.

12 isomo([X|Xrest],Ys,Iso) :- 

13 select(Y,Ys,Yrest),

14 iso(X,Y,Iso),

15 isomo(Xrest,Yrest,Iso).

行注释:

11. 终止条件

12. 

13. 内置谓词,Yrest是删除列表Ys中元素Y的列表。

14. X与Y的边对应或同为鼓励顶点

15. 

 

% iso(E1,E2,Iso) :- 一个图中的边E1对应于另一图中的边E2。请注意,边是无向的。

% iso(N1,N2,Iso) :- 匹配孤立的顶点.

 

16 iso(E1,E2,Iso) :- 

17 edge(E1,X1,Y1), 

18 edge(E2,X2,Y2), 

19 bind(X1,X2,Iso), 

20 bind(Y1,Y2,Iso).

21 iso(E1,E2,Iso) :- 

22 edge(E1,X1,Y1), 

23 edge(E2,X2,Y2), 

24 bind(X1,Y2,Iso), 

25 bind(Y1,X2,Iso).

26 iso(N1,N2,Iso) :-

27 \+ edge(N1,_,_),

28 \+ edge(N2,_,_),     % 孤立的顶点

29 bind(N1,N2,Iso).

30

行注释:

16. 

17. E1是X1,Y1的边

18. E2是X2,Y2的边

19. 将X1绑定到X2作为双射Iso的一部分

20. 将Y1绑定到Y2作为双射Iso的一部分

21. 

22. E1是X1,Y1的边

23. E2是X2,Y2的边

24. 将X1绑定到Y2作为双射Iso的一部分

25. 将Y1绑定到X2作为双射Iso的一部分

26. 

27. N1不是边

28. N2不是边

29. 将N1绑定到N2作为双射Iso的一部分(孤立顶点)

30. 

 

 

31 edge(e(X,Y),X,Y).

32 edge(e(X,Y,_),X,Y).

33

% bind(X,Y,Iso) :- 可以将X绑定到Y作为双射Iso的一部分;即项i(X,Y)已经在Iso列表中,或者可以在不违反规则的情况下将其添加到其中。请注意,如果将i(X,Y)添加到Iso,则bind(X,Y,Iso)可确保X和Y都是“新的”。

 

34 bind(X,Y,Iso) :- 

35 memberchk(i(X,Y0),Iso), 

36 nonvar(Y0), 

37 !, 

38 Y = Y0.

39 bind(X,Y,Iso) :- 

40 memberchk(i(X0,Y),Iso), 

41 X = X0.

42

行注释:

31. 无标识边

32. 有标识边

33. 空行

34. 

35. 项i(X,Y0)在Iso中

36. Y0不是变量

37. 截断

38. 将Y0绑定到Y

39. 

40. 项i(X0,Y)在Iso中

41. 将X0绑定到X

42. 

 

43 test(1) :-

44 human_gterm([f-e,e-d,e-g,c-e,c-b,a-b,c-d,beta],G1),

45 human_gterm([6-3,6-4,3-4,alfa,4-5,7-4,6-2,1-2],G2),

46 isomorphic(G1,G2,Iso), write(Iso).

47 test(2) :-

48 human_gterm([f-e,e-d,e-g,c-e,c-b,a-b,c-d,beta],G1),

49 human_gterm([6-3,6-4,3-4,4-5,7-4,6-2,1],G2),

50 isomorphic(G1,G2,Iso), write(Iso).

51 test(3) :-

52 human_gterm([a-b,c-d,e,d-f],G1),

53 human_gterm([1-2,1-3,5,4-6],G2),

54 isomorphic(G1,G2,Iso), write(Iso).

行注释:

43. 测试1

44. 将参数1转为G1

45. 将参数1转为G2

46. 验证同构

47. 测试2

48. 将参数1转为G1

49. 将参数1转为G2

50. 验证同构

51. 测试3

52. 将参数1转为G1

53. 将参数1转为G2

54. 验证同构

?- test(1).

[i(a,1),i(b,2),i(c,6),i(d,3),i(e,4),i(f,5),i(g,7),i(beta,alfa)|_21202]

true .

 

?- test(2).

false.

 

?- test(3).

[i(a,4),i(b,6),i(c,2),i(d,1),i(f,3),i(e,5)|_1556]

true .

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值