用SQL解七桥问题

加里宁格勒市中心有一条普雷戈里亚河,该河流穿过城市,并把城市分割成两个岛屿和两片陆地。这片土地在18世纪被称为柯尼斯堡,隶属于普鲁士。在当时,有一个和柯尼斯堡桥有关的问题:如何只把每座桥走一次而穿过整个城市?

下图是柯尼斯堡七座桥的简化图。

这个七桥问题后来被欧拉解决,以下是使用关系数据库来解题的过程。

1. 定义表和插入数据

LAND表
create table land (land varchar2(5),
constraint land_pk primary key (land))

insert into land values('N1');
insert into land values('N2');
insert into land values('N3');
insert into land values('N4');

 

BRIDGE表
create table bridge (bridge varchar2(5),
constraint bridge_pk primary key (bridge))

insert into bridge values('B1');
insert into bridge values('B2');
insert into bridge values('B3');
insert into bridge values('B4');
insert into bridge values('B5');
insert into bridge values('B6');
insert into bridge values('B7');


BRIDGE_LAND表
create table bridge_land (bridge varchar2(5),
land varchar2(5),
constraint b_fk foreign key (bridge) references bridge(bridge),
constraint l_fk foreign key (land) references land(land)
)

insert into bridge_land values('B1','N1');
insert into bridge_land values('B1','N3');
insert into bridge_land values('B2','N1');
insert into bridge_land values('B2','N4');
insert into bridge_land values('B3','N1');
insert into bridge_land values('B3','N3');
insert into bridge_land values('B4','N1');
insert into bridge_land values('B4','N4');
insert into bridge_land values('B5','N1');
insert into bridge_land values('B5','N2');
insert into bridge_land values('B6','N2');
insert into bridge_land values('B6','N3');
insert into bridge_land values('B7','N2');
insert into bridge_land values('B7','N4');

 


2. 用SQL语言写成的解法(比较笨拙的解法)

select t1.land,t2.bridge,t2.land,t3.bridge,t4.land,t5.bridge,t6.land,t7.bridge,t8.land,t9.bridge,t10.land,t11.bridge,t12.land,t13.bridge,t14.land
from bridge_land t1 join bridge_land t2 on (t2.bridge=t1.bridge and t2.land!=t1.land)
                    join bridge_land t3 on (t3.land=t2.land and t3.bridge!=t1.bridge and t3.bridge!=t2.bridge)
                    join bridge_land t4 on (t4.bridge=t3.bridge and t4.land!=t3.land)
                    join bridge_land t5 on (t5.land=t4.land and t5.bridge!=t2.bridge and t5.bridge!=t3.bridge)
                    join bridge_land t6 on (t6.bridge=t5.bridge and t6.land!=t5.land)
                    join bridge_land t7 on (t7.land=t6.land and t7.bridge!=t2.bridge and t7.bridge!=t3.bridge and t7.bridge!=t5.bridge)
                    join bridge_land t8 on (t8.bridge=t7.bridge and t8.land!=t7.land)
                    join bridge_land t9 on (t9.land=t8.land and t9.bridge!=t2.bridge and t9.bridge!=t3.bridge and t9.bridge!=t5.bridge and t9.bridge!=t7.bridge)
                    join bridge_land t10 on (t10.bridge=t9.bridge and t10.land!=t9.land)
                    join bridge_land t11 on (t11.land=t10.land and t11.bridge!=t2.bridge and t11.bridge!=t3.bridge and t11.bridge!=t5.bridge and t11.bridge!=t7.bridge and t11.bridge!=t9.bridge)
                    join bridge_land t12 on (t12.bridge=t11.bridge and t12.land!=t11.land)
                    join bridge_land t13 on (t13.land=t12.land and t13.bridge!=t2.bridge and t13.bridge!=t3.bridge and t13.bridge!=t5.bridge and t13.bridge!=t7.bridge and t13.bridge!=t9.bridge and t13.bridge!=t11.bridge)
                    join bridge_land t14 on (t14.bridge=t13.bridge and t14.land!=t13.land)
order by 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

这个查询没有结果返回,说明不重复的遍历七座桥是无解的。


3. 以下查询求得无重复遍历六座桥的全部欧拉路径
 

select t1.land,t2.bridge,t2.land,t3.bridge,t4.land,t5.bridge,t6.land,t7.bridge,t8.land,t9.bridge,t10.land,t11.bridge,t12.land
from bridge_land t1 join bridge_land t2 on (t2.bridge=t1.bridge and t2.land!=t1.land)
                    join bridge_land t3 on (t3.land=t2.land and t3.bridge!=t1.bridge and t3.bridge!=t2.bridge)
                    join bridge_land t4 on (t4.bridge=t3.bridge and t4.land!=t3.land)
                    join bridge_land t5 on (t5.land=t4.land and t5.bridge!=t2.bridge and t5.bridge!=t3.bridge)
                    join bridge_land t6 on (t6.bridge=t5.bridge and t6.land!=t5.land)
                    join bridge_land t7 on (t7.land=t6.land and t7.bridge!=t2.bridge and t7.bridge!=t3.bridge and t7.bridge!=t5.bridge)
                    join bridge_land t8 on (t8.bridge=t7.bridge and t8.land!=t7.land)
                    join bridge_land t9 on (t9.land=t8.land and t9.bridge!=t2.bridge and t9.bridge!=t3.bridge and t9.bridge!=t5.bridge and t9.bridge!=t7.bridge)
                    join bridge_land t10 on (t10.bridge=t9.bridge and t10.land!=t9.land)
                    join bridge_land t11 on (t11.land=t10.land and t11.bridge!=t2.bridge and t11.bridge!=t3.bridge and t11.bridge!=t5.bridge and t11.bridge!=t7.bridge and t11.bridge!=t9.bridge)
                    join bridge_land t12 on (t12.bridge=t11.bridge and t12.land!=t11.land)
order by 1,2,3,4,5,6,7,8,9,10,11,12,13

可以查出256条结果,即存在256条欧拉路径


4. 以下查询求得不重复遍历六座桥的欧拉环

select t1.land,t2.bridge,t2.land,t3.bridge,t4.land,t5.bridge,t6.land,t7.bridge,t8.land,t9.bridge,t10.land,t11.bridge,t12.land
from bridge_land t1 join bridge_land t2 on (t2.bridge=t1.bridge and t2.land!=t1.land)
                    join bridge_land t3 on (t3.land=t2.land and t3.bridge!=t1.bridge and t3.bridge!=t2.bridge)
                    join bridge_land t4 on (t4.bridge=t3.bridge and t4.land!=t3.land)
                    join bridge_land t5 on (t5.land=t4.land and t5.bridge!=t2.bridge and t5.bridge!=t3.bridge)
                    join bridge_land t6 on (t6.bridge=t5.bridge and t6.land!=t5.land)
                    join bridge_land t7 on (t7.land=t6.land and t7.bridge!=t2.bridge and t7.bridge!=t3.bridge and t7.bridge!=t5.bridge)
                    join bridge_land t8 on (t8.bridge=t7.bridge and t8.land!=t7.land)
                    join bridge_land t9 on (t9.land=t8.land and t9.bridge!=t2.bridge and t9.bridge!=t3.bridge and t9.bridge!=t5.bridge and t9.bridge!=t7.bridge)
                    join bridge_land t10 on (t10.bridge=t9.bridge and t10.land!=t9.land)
                    join bridge_land t11 on (t11.land=t10.land and t11.bridge!=t2.bridge and t11.bridge!=t3.bridge and t11.bridge!=t5.bridge and t11.bridge!=t7.bridge and t11.bridge!=t9.bridge)
                    join bridge_land t12 on (t12.bridge=t11.bridge and t12.land!=t11.land)
where t1.land=t12.land

查不出结果,也就是不存在欧拉环


5. 以下查询求得每块陆地的桥的数量
SQL> select land,count(bridge) from bridge_land group by land;

LAND  COUNT(BRIDGE)
----- -------------
N1                5
N2                3
N4                3
N3                3
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值