乘车线路查询

原创 2008年01月02日 07:41:00
 
背景
有如下表示乘车线路和站点的数据,要求查询出指定站点之间的所有乘车线路:
USE tempdb
GO
 
-- 模拟数据
SET NOCOUNT ON
IF OBJECT_ID(N'tempdb..#tb') IS NOT NULL
    DROP TABLE #tb
CREATE TABLE #tb(
    id int IDENTITY
        PRIMARY KEY,
    lineID int,
    state nvarchar(10),
    orderid int
)
INSERT #tb(
     lineID, state, orderid)
SELECT 1, N'广州东',UNION ALL
SELECT 1, N'体育中心',UNION ALL
SELECT 1, N'体育西',UNION ALL
SELECT 1, N'烈士陵园',UNION ALL
SELECT 1, N'公园前',UNION ALL
SELECT 1, N'西门口',UNION ALL
SELECT 2, N'火车站',UNION ALL
SELECT 2, N'纪念堂',UNION ALL
SELECT 2, N'公园前',UNION ALL
SELECT 2, N'中大',UNION ALL
SELECT 2, N'客村',UNION ALL
SELECT 2, N'琶洲',UNION ALL
SELECT 2, N'万胜围',UNION ALL
SELECT 3, N'广州东',UNION ALL
SELECT 3, N'体育西',UNION ALL
SELECT 3, N'珠江新城',UNION ALL
SELECT 3, N'客村',UNION ALL
SELECT 3, N'市桥',UNION ALL
SELECT 4, N'万胜围',UNION ALL
SELECT 4, N'金洲', 2
 
CREATE INDEX IX_lineID
    ON #tb(
        lineID)
 
CREATE INDEX IX_state
    ON #tb(
        state)
 
CREATE INDEX IX_orderid
    ON #tb(
        orderid)
GO
 
处理方法:
之前也有发表过一些如何处理这个问题的方法,但效率不是太好。下面的这种方法加上了乘车方向的考虑:同一条线路上,只有两个乘车方向,而且一旦方向了,就不会再反向乘车(因为是从这个方向来,再坐回去是不合理的);如果某个站点可以换到另一条线路,则换乘后的另一条线路也是两个方向乘车。通过乘车方向的控制,减少了算法要搜索的路径。
-- 乘车路线查询
DECLARE
    @state_start nvarchar(10),
    @state_stop nvarchar(10)
SELECT
    @state_start = N'广州东',
    @state_stop = N'中大'
 
-- 查询
IF OBJECT_ID(N'tempdb..#re') IS NOT NULL
    DROP TABLE #re
CREATE TABLE #re(
    ID int IDENTITY
       PRIMARY KEY,
    path nvarchar(max),
    state_count int,
    line_count int,
    start_lineID int,
    start_state nvarchar(10),
    current_lineID int,
    current_state nvarchar(10),
    next_orderid int,
    flag int,
    lineIDs varchar(max),
    level int
)
 
CREATE INDEX IX_current_lineID
    ON #re(
       current_lineID )
 
CREATE INDEX IX_current_state
    ON #re(
       current_state )
 
CREATE INDEX IX_next_orderid
    ON #re(
       next_orderid )
 
CREATE INDEX IX_current_level
    ON #re(
       level )
 
DECLARE
    @level int,
    @rows int
SET
    @level = 0
 
-- 开始
INSERT #re(
    path,
    state_count, line_count,
    start_lineID, start_state,
    current_lineID, current_state,
    next_orderid, flag, lineIDs, level)   
SELECT
    path = CONVERT(nvarchar(max),
           RTRIM(A.lineID) + N'{'
              + RTRIM(A.orderid) + N'.' + A.state
       ),
    state_count = 0,
    line_count = 0,
    start_lineID = A.lineID,
    start_state = A.state,
    current_lineID = A.lineID,
    current_state = A.state,
    next_orderid = A.orderid,
    flag = CASE
           WHEN A.state = @state_stop THEN 0
           ELSE NULL END,
    lineIDs = ',' + RTRIM(A.lineID) + ',',
    level = -(@level + 1)
FROM #tb A
WHERE state = @state_start
SET @rows = @@ROWCOUNT
WHILE @rows > 0
BEGIN
    SELECT
       @level = @level + 1
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 同一LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + A.flag,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE A.flag END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND A.level = @level - 1
       AND A.current_lineID = B.lineID
       AND A.next_orderid = B.orderid
   
    UNION ALL
    -- 不同LineID
    SELECT
       path = CONVERT(nvarchar(max),
              A.path + N')->'
                  + RTRIM(B.lineID) + N'{'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       line_count = A.line_count + 1,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE NULL END,
       A.lineIDs + RTRIM(B.lineID) + ',',
       level = - @level
    FROM #re A, #tb B
    WHERE A.flag <> 0
       AND state_count = @level - 1
       AND A.current_lineID <> B.lineID
       AND A.current_state = B.state
       AND NOT EXISTS(
              SELECT * FROM #re
              WHERE CHARINDEX(',' + RTRIM(B.lineID) + ',', A.lineIDs) > 0)
    SET @rows = @@ROWCOUNT
 
    INSERT #re(
       path,
       state_count, line_count,
       start_lineID, start_state,
       current_lineID, current_state,
       next_orderid, flag, lineIDs, level)   
    -- 不同LineID 的第站正向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid + 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid + 1 = B.orderid
    UNION ALL
    -- 不同LineID 的第站反向
    SELECT
       path = CONVERT(nvarchar(max),
              A.path
                  + N'->'
                  + RTRIM(B.orderid) + N'.' + B.state
           ),
       state_count = A.state_count + 1,
       A.line_count,
       A.start_lineID, A.start_state,
       current_lineID = B.lineID,
       current_state = B.state,
       next_orderid = B.orderid - 1,
       flag = CASE
              WHEN B.state = @state_stop THEN 0
              ELSE - 1 END,
       A.lineIDs,
       level = @level
    FROM #re A, #tb B
    WHERE A.flag IS NULL
       AND A.level = - @level
       AND A.current_lineID = B.lineID
       AND A.next_orderid - 1 = B.orderid
 
    SET @rows = @rows + @@ROWCOUNT
END
 
SELECT
-- *,
    path = path + N'}',
    line_count,
    state_count
FROM #re
WHERE flag = 0
 
 

最短乘车线路查询

CREATE TABLE T_Line(ID      nvarchar(10),  --公交线路号Station nvarchar(10),  --站点名称Orders  int)         ...
  • emailqjc
  • emailqjc
  • 2009年07月29日 18:05
  • 644

转:邹建--乘车线路查询

转:http://blog.csdn.net/zjcxc/archive/2008/01/02/2009421.aspx背景有如下表示乘车线路和站点的数据,要求查询出指定站点之间的所有乘车线路:USE...
  • flyskylf
  • flyskylf
  • 2008年01月04日 11:49
  • 647

乘公交车换乘,选路线,花最少时间

遇到一道笔试题,笔试的时候没有解出来,大概记了下题目,后面花时间解出来,但没有环境,只通过了demo。 题目大概是这样的: 题目描述:小明要从家里去看奥运会,中途要换乘公交车,有很多条路线,不同路...
  • lywtbbigcow
  • lywtbbigcow
  • 2017年09月07日 23:41
  • 311

公交线路查询系统 C++实现 图

一、需求与规格说明    本次实验涉及实际问题,实现公交线路系统的增删改查功能,建立公交线路网,用户可以在威海市范围内实用。    本次实验要求分为: 1.实现根据给定的数据公交数据建立图的存储...
  • bcj296050240
  • bcj296050240
  • 2015年05月15日 16:28
  • 2262

[NOI1997]最优乘车

最优乘车时间限制: 1 Sec 内存限制: 128 MB题目描述H城是一个旅游胜地,为方便游客,在各个旅游景点及宾馆、饭店等地设置了N个巴士站,并开通了M条一些单向巴士线路。 现在用整数1,2,…...
  • slongle_amazing
  • slongle_amazing
  • 2015年07月14日 23:36
  • 954

腾讯乘车码小程序,二维码乘车新选择

腾讯与多地公交公司合作推出二维码乘车,市民游客在乘坐公交车时,可通过腾讯乘车码小程序一键享受移动支付便捷乘车服务,二维码乘车将成市民出行新选择。...
  • wexiaocheng
  • wexiaocheng
  • 2017年10月18日 16:27
  • 130

最小乘车费用

Problem Description 某条街上每隔一公里就有一汽车站,乘车费用如下表: 公里数 1 2 3 4 5 6 7 8 9 10 费用 12 21 31 40 49 58 69 7...
  • u011123263
  • u011123263
  • 2014年03月14日 20:13
  • 745

最短乘车路线查询

--最短乘车路线查询示例(邹老大的。)CREATE TABLE T_Line(ID      nvarchar(10),  --公交线路号Station nvarchar(10),  --站点名称Or...
  • issacp
  • issacp
  • 2009年04月03日 11:02
  • 312

什么是BGP线路,如何分辨BGP线路真伪

BGP(Border GatewayProtocol)是一种在自治系统之间动态交换路由信息的路由协议。一个自治系统的经典定义是在一个管理机构控制之下的一组路由器,它使用IGP和普通度量值向其他自治系统...
  • liuzhenhua_andy
  • liuzhenhua_andy
  • 2012年09月06日 16:34
  • 2765

中国地铁换乘网——免费提供地铁查询代码下载

 中国地铁换乘网免费提供地铁换乘查询代码下载,通过网页嵌入代码的方式,在您的网站轻松快捷实现对中国城市地铁换乘的在线查询,提供最优地铁换乘路线、时刻表、票价及站点周边相关信息。并提供了多语言选择,包括...
  • metrosguide
  • metrosguide
  • 2009年11月26日 14:53
  • 270
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:乘车线路查询
举报原因:
原因补充:

(最多只允许输入30个字)