冯·科赫猜想

转载自:https://mp.weixin.qq.com/s/BnSalO-hEPI-E7jmL2Pqnw

给定具有n节点的树(因此有n-1边)。找到一种方法,从枚举节点1到n,因此,从边1到边n-1以这样的方式,对于每个边k其节点号的差等于k。推测这总是可能的。

这是一个例子,可以很清楚地说明这一点:

我们的任务

我们的代码将以一棵树作为输入,我们可以采用所需的格式,但是对于测试用例,我们将通过它们的弧和它们的节点列表来提供树。

例如,这是图片中树的输入:

[d-a,a-g,b-c,e-f,b-e,a-b]

 

您的代码必须返回带有编号的节点树。您可以返回更多图形输出,但是我将为测试用例提供这种输出:

[a/1,b/5,c/2,d/3,e/4|_8892]

 

测试用例:

1、[a-b,b-c,c-d,c-e]  => [a/1,b/5,c/2,d/3,e/4|_8892]

2、[d-a,a-g,b-c,e-f,b-e,a-b] => [a/1,b/5,d/6,g/7,c/2,e/3,f/4|_9492]

3、[g-a,i-a,a-h,b-a,k-d,c-d,m-q,p-n,q-n,e-q,e-c,f-c,c-a] => [a/1,b/2,c/12,g/11,h/13,i/14,d/3,e/4,f/5,k/8,q/10,m/6,n/7,p/9|_12486]

下面是具体的程序:

程序文件名:p7_03.pl

:- ensure_loaded('../Graphs/p6_01').  

% 程序文件见:图 练习1

:- ensure_loaded('../Graphs/p6_04').  % is_tree

% 程序文件见:图 练习3

% vonkoch(G,Enum) :- 可以如Enum中所述枚举图G的节点。枚举是X/K对的列表,其中X是节点,K是对应的数字。 

 

vonkoch(Graph,Enum) :- 

is_tree(Graph),  % 做太多工作之前先检查一下!

Graph = graph(Ns,_),

length(Ns,N),

human_gterm(Hs,Graph),

vonkoch(Hs,N,Enum).

 

vonkoch([IsolatedNode],1,[IsolatedNode/1|_]).  % 特殊情况

vonkoch(EdgeList,N,Enum) :-

range(1,N,NodeNumberList), 

N1 is N-1,range(1,N1,EdgeNumberList),

bind(EdgeList,NodeNumberList,EdgeNumberList,Enum).

 

% 该树作为边列表给出;例如 [d-a,a-g,b-c,e-f,b-e,a-b].

% 我们的问题是找到节点(a,b,c,...)与整数1..N之间的双射,这与上面提到的条件兼容。为了构造这个双射,我们使用一个开放式列表Enum;然后我们扫描给定的边列表。

 

bind([],_,_,_) :- !.

bind([V1-V2|Es],NodeNumbers,EdgeNumbers,Enum) :-

bind_node(V1,K1,NodeNumbers,NodeNumbers1,Enum), 

bind_node(V2,K2,NodeNumbers1,NodeNumbers2,Enum), 

D is abs(K1-K2), select(D,EdgeNumbers,EdgeNumbers1), 

bind(Es,NodeNumbers2,EdgeNumbers1,Enum).

 

% bind_node(V,K,NodeNumsIn,NodeNumsOut,Enum) :-  

% V/K是列表Enum的元素,并且没有V1 \= V使得V1/K在Enum中,也没有K1 \= K使得V =:= K1在Enum中。如果V获得一个新数字,则从设置的NodeNumsIn中选择它;剩下的就是NodeNumsOut。

% (node,integer,integer-list,integer-list,enumeration)  (+,?,+,-,?)

 

bind_node(V,K,NodeNumbers,NodeNumbers,Enum) :- 

memberchk(V/K1,Enum), number(K1), !, K = K1.

bind_node(V,K,NodeNumbers,NodeNumbers1,Enum) :- 

select(K,NodeNumbers,NodeNumbers1), memberchk(V/K,Enum).

 

% range(A,B,L) :- L是数字A..B的列表

 

range(B,B,[B]) :- !.

range(A,B,[A|L]) :- 

A < B

A1 is A+1, 

range(A1,B,L).

 

% test suite ------------------------------------------------------------

 

test_Von(K) :-

test_tree(K,TH),

write(TH), nl,  

human_gterm(TH,T),

vonkoch(T,Enum),

write(Enum).

      

test_tree(1,[a-b,b-c,c-d,c-e]).

test_tree(2,[d-a,a-g,b-c,e-f,b-e,a-b]).

test_tree(3,[g-a,i-a,a-h,b-a,k-d,c-d,m-q,p-n,q-n,e-q,e-c,f-c,c-a]).

test_tree(4,[a]).

 

测试:

?- consult('p7_03.pl').

true.

 

?- test_Von(1).

[a-b,b-c,c-d,c-e]

[a/1,b/5,c/2,d/3,e/4|_8892]

true .

 

?- test_Von(2).

[d-a,a-g,b-c,e-f,b-e,a-b]

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

true .

 

?- test_Von(3).

[g-a,i-a,a-h,b-a,k-d,c-d,m-q,p-n,q-n,e-q,e-c,f-c,c-a]

[a/1,b/2,c/12,g/11,h/13,i/14,d/3,e/4,f/5,k/8,q/10,m/6,n/7,p/9|_12486]

true .

 

?- test_Von(4).

[a]

[a/1|_8098]

true .

 

?- 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值