公交车换乘线路查询算法及sql存储过程代码

2008-10-28 00:42:29   来源:OKXUN.com

算法:
已知起点站A,终点站B。假设最大换乘次数3,初始值为0。
1、根据起点站获得经过该站点的车次。
2、按序分析每路车次。
3、取得某个车次获得该站点的后续站点。
4、如果发现后续站点是B,就找到一条路径。记录该路径。并退出在本线路上的搜索。如果后续站点不是B,就继续分析后续站点的后续站点。直到该线路的终点站。
5、如果该线路的后续站点不存在B,则获得该线路的经过本站点的后续站点,重复过程1~4,换乘次数加1,如果换乘次数为4则退出该线路的搜索。
6、取得第二个车次,分析同上。
7、分析完所有路线,如果不存在,就提醒用户增加换乘次数,或者打的。如果存在按换乘次数从小到大排列换乘路线。

-------------------------------------
线路表:
code   线路编号
name   线路名称
buscode   车次

地点表:
stationcode   站编号
  station   站名

中间表:
code   线路编号
stationcode   站编号
  seqnumber   某站在线路中的顺序
=======================================
线路表:
每条线路对应一路车次。按序存放各站点。每条线路有两个方向。

站点表:
每个站点,有经过该站点的所有车次。

这是邹健写的公交线路查询存储过程

SQL代码
--示例数据   
create   table   Line(lineID   int,state   nvarchar(10),orderid   int,primary   key(lineID,orderid))   
insert   Line   select   1,'鼓楼'     ,1   
union     all     select   1,'新街口',2   
union     all     select   1,'汽车站',3   
union     all     select   1,'火车站',4   
union     all     select   2,'新街口',1   
union     all     select   2,'飞机场',2   
union     all     select   2,'天安门',3   
union     all     select   3,'天安门',1   
union     all     select   3,'石门坎',2   
union     all     select   3,'驾校'     ,3   
go   
  
--查询的存储过程   
create   proc   p_qry   
@begin_state   nvarchar(10),   
@end_state   nvarchar(10)   
as  
set   nocount   on  
declare   @l   int  
set   @l=0   
select   lineID,line=cast('('+rtrim(lineID)+':   '+rtrim(state)   as   varchar(8000))   
,state,orderid=orderid+1,level=@l,gid=1   
into   #t   from   Line   where   state=@begin_state   
while   @@rowcount>0   and   not   exists(select   *   from   #t   where   state=@end_state)   
begin  
set   @l=@l+1   
insert   #t(line,lineID,state,orderid,level,gid)   
select      
line=a.line+case  
when   a.lineID=b.lineID   
then   '->'+rtrim(b.state)   
else   ')   =>   ('+rtrim(b.lineID)+':   '+rtrim(b.state)   
end,   
lineID=b.lineID,state=b.state,orderid=b.orderid+1,@l,   
case   when   a.lineID=b.lineID   then   a.gid   else   a.gid+1   end  
from   #t   a,Line   b   
where   a.level=@l-1   
and(   
a.lineID=b.lineID   and   a.orderid=b.orderid   
or      
a.state=b.state   and   a.lineID<>b.lineID)   
end  
select   起点站=@begin_state   
,终点站=@end_state   
,转车次数=gid   
,经过站数=case   when   gid<3   then   @l   else   @l-gid+2   end  
,乘车线路=line+')'      
from   #t   where   level=@l   and   state=@end_state   
go   
  
--调用   
exec   p_qry   '鼓楼','火车站'  
exec   p_qry   '鼓楼','飞机场'  
exec   p_qry   '鼓楼','石门坎'  
go   
  
--删除测试   
drop   table   Line   
drop   proc   p_qry   

结合这个存储过程

 

SQL代码
CREATE TABLE T_Line(   
ID      nvarchar(10),  --公交线路号   
Station nvarchar(10),  --站点名称   
Orders  int)           --行车方向(通过它反应每个站的上一个、下一个站)   
INSERT T_Line    
SELECT N'8路'  ,N'站A',1 UNION ALL  
SELECT N'8路'  ,N'站B',2 UNION ALL  
SELECT N'8路'  ,N'站C',3 UNION ALL  
SELECT N'8路'  ,N'站D',4 UNION ALL  
SELECT N'8路'  ,N'站J',5 UNION ALL  
SELECT N'8路'  ,N'站L',6 UNION ALL  
SELECT N'8路'  ,N'站M',7 UNION ALL  
SELECT N'20路' ,N'站G',1 UNION ALL  
SELECT N'20路' ,N'站H',2 UNION ALL  
SELECT N'20路' ,N'站I',3 UNION ALL  
SELECT N'20路' ,N'站J',4 UNION ALL  
SELECT N'20路' ,N'站L',5 UNION ALL  
SELECT N'20路' ,N'站M',6 UNION ALL  
SELECT N'255路',N'站N',1 UNION ALL  
SELECT N'255路',N'站O',2 UNION ALL  
SELECT N'255路',N'站P',3 UNION ALL  
SELECT N'255路',N'站Q',4 UNION ALL  
SELECT N'255路',N'站J',5 UNION ALL  
SELECT N'255路',N'站D',6 UNION ALL  
SELECT N'255路',N'站E',7 UNION ALL  
SELECT N'255路',N'站F',8   
GO   
  
  
--引用邹建的.乘车线路查询存储过程   
CREATE PROC p_qry   
@Station_Start nvarchar(10),   
@Station_Stop  nvarchar(10)   
AS  
SET NOCOUNT ON  
DECLARE @l int  
SET @l=0   
SELECT ID,Station,   
Line=CAST('('+RTRIM(ID)+': '+RTRIM(Station) as nvarchar(4000)),   
Orders=Orders,   
[Level]=@l   
INTO # FROM T_Line   
WHERE Station=@Station_Start   
WHILE @@ROWCOUNT>0    
AND NOT EXISTS(SELECT * FROM # WHERE Station=@Station_Stop)   
BEGIN  
SET @l=@l+1   
INSERT #(Line,ID,Station,Orders,[Level])   
SELECT    
Line=a.Line+CASE  
WHEN a.ID=b.ID THEN N'->'+RTRIM(b.Station)   
ELSE N') ∝ ('+RTRIM(b.ID)   
+N': '+RTRIM(b.Station) END,   
b.ID,b.Station,b.Orders,@l   
FROM # a,T_Line b   
WHERE a.[Level]=@l-1   
AND(a.Station=b.Station AND a.ID<>b.ID   
OR a.ID=b.ID AND(   
a.Orders=b.Orders+1   
OR  
a.Orders=b.Orders-1))   
AND LEN(a.Line)<4000   
AND PATINDEX('%[ >]'+b.Station+'[-)]%',a.Line)=0   
END  
SELECT N'起点站'=@Station_Start   
,N'终点站'=@Station_Stop   
,N'乘车线路'=Line+N')'    
FROM #    
WHERE [Level]=@l    
AND Station=@Station_Stop   
IF @@ROWCOUNT =0 --如果未有可以到达的线路,则显示处理结果表备查   
SELECT * FROM #   
GO   
  
--调用   
EXEC p_qry N'站A',N'站L'  
/*--结果   
起点站  终点站  乘车线路   
---------- ------------ -----------------------------------------------------------   
站A    站L    (8路: 站A->站B->站C->站D->站J->站L)   
--*/