我正在尝试建立一个查询,从A到B获得一条路线。有时可能会有直接路线,有时我需要找到路口并获得交换路线。目标是让一个人从A到B旅行并给出不同的模式类型和路线。我将在稍后添加最短或最佳路线,但现在只是为了获得正确的路线。问题是当我试图获得相交路线时。不知何故,我觉得应该有一个更简单的方法来完成这项工作。我希望这不是太多的代码。
我认为应该运作的逻辑是
找到起始路线(Halts表),如果我们有一个获取RouteID和路线号,如果我们找不到起跑路线,试着去下一个最近的路线。
找到结束路线。如果我们有一个,检查起始路线是否在此路线内(这是直接路线),如果是,则获取RouteID和路线编号并插入临时表以显示最终路线。
this is where I got lost as there can be more than one intersecting route
路线类型表
此表有不同的路线类型,如城市巴士,长途巴士,本地火车,长途列车,国内航班,国际航班
CREATE TABLE [dbo].[RouteTypes](
[RouteTypeID] [int] IDENTITY(1,1) NOT NULL,
[ModeTypeID] [int] NOT NULL,
[RouteType] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_RouteTypes] PRIMARY KEY CLUSTERED
(
[RouteTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ModeTypes表
此表格将包含不同的交通工具类型,如公共汽车,火车,航班
CREATE TABLE [dbo].[ModeTypes](
[ModeTypeID] [int] IDENTITY(1,1) NOT NULL,
[ModeType] [nvarchar](50) NOT NULL,
[IsEnabled] [bit] NOT NULL,
CONSTRAINT [PK_ModeTypes] PRIMARY KEY CLUSTERED
(
[ModeTypeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
暂停表格
此表将保留所有暂停,并且是暂停的主表
CREATE TABLE [dbo].[Halts](
[HaltID] [int] IDENTITY(1,1) NOT NULL,
[Halt] [nvarchar](100) NOT NULL
) ON [PRIMARY]
路线表
此表的路线编号有些。由于我不太清楚需要在这里添加什么,我现在还没有使用的大部分字段
CREATE TABLE [dbo].[Routes](
[RouteID] [int] IDENTITY(1,1) NOT NULL,
[RouteTypeID] [int] NOT NULL,
[RouteNo] [nvarchar](30) NOT NULL,
[Duration] [nvarchar](30) NULL,
[Distance] [nvarchar](30) NULL,
[OldRouteNo] [nvarchar](30) NULL,
[DaysAvailable] [char](15) NULL,
[IsEnabled] [bit] NOT NULL,
[BeginAt] [time](7) NULL,
[EndAt] [time](7) NULL,
CONSTRAINT [PK_Routes] PRIMARY KEY CLUSTERED
(
[RouteID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
路线暂停表
CREATE TABLE [dbo].[RouteHalts](
[RouteHaltID] [int] IDENTITY(1,1) NOT NULL,
[RouteID] [int] NOT NULL,
[FirstLastHalt] [char](1) NULL,
[HaltNo] [smallint] NULL,
[HaltID] [int] NOT NULL,
CONSTRAINT [PK_RouteHalts] PRIMARY KEY CLUSTERED
(
[RouteHaltID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我正在使用存储过程,这是我到目前为止所拥有的。当我得到检查路线时,结果不正确。
DECLARE @StartingRouteID int;
DECLARE @EndingRouteID int;
DECLARE @CrossRouteHalt nvarchar(100);
CREATE TABLE #TmpStartingRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpStartingHalts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpEndingRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpEndingHalts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
Duration nvarchar(60) null,
Distance nvarchar(60) null,
DaysAvailable nvarchar(60) null,
Halt nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpRts
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
Halt nvarchar(100) null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #TmpIntersection
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
Halt nvarchar(100) null,
RouteNo nvarchar(60) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
CREATE TABLE #FinalRoute
(
ID INT IDENTITY(1,1) NOT NULL,
RouteID int null,
RouteNo nvarchar(60) null,
Halt nvarchar(100) null,
RouteType nvarchar(100) null,
ModeType nvarchar(100) null
)
-- Check if Starting point exits
IF EXISTS(SELECT 1 FROM RouteHalts where Halt like'%'+ @StartingPoint +'%')
BEGIN
SELECT
@StartingRouteID=R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @StartingPoint +'%'
insert into #TmpStartingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID, R.RouteNo,RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @StartingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert halts of starting routes
insert into #TmpStartingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID, R.RouteNo,RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@StartingRouteID and RH.Halt not like'%'+ @StartingPoint +'%'
order by
R.RouteNo,RH.HaltNo
END
ELSE
-- Find the closest locaton of the starting point
BEGIN
RAISERROR('No Routes Available', 16, 2)
RETURN
END
-- Check if Ending point exits within the start route to get the direct route
IF EXISTS(SELECT 1 FROM RouteHalts R INNER JOIN #TmpStartingRoute SR on R.RouteID=SR.RouteID
where R.Halt like'%'+ @EndingPoint +'%')
BEGIN
print 'In End route exists within starting route'
SELECT
@EndingRouteID= R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
INNER JOIN
#TmpStartingRoute SR on R.RouteID=SR.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
insert into #TmpEndingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
INNER JOIN
#TmpStartingRoute SR on R.RouteID=SR.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert all halts of ending route
insert into #TmpEndingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@EndingRouteID and RH.Halt not like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
delete from #TmpStartingHalts where RouteID not in (select RouteID from #TmpEndingRoute)
delete from #TmpStartingRoute where RouteID not in (select RouteID from #TmpEndingRoute)
select * from #TmpEndingRoute
END
ELSE
-- Find the closest locaton of the starting point
BEGIN
print 'In End route does NOT exists within starting route'
SELECT
@EndingRouteID= R.RouteID
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
insert into #TmpEndingRoute(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.Halt like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
-- Insert all halts of ending route
insert into #TmpEndingHalts(RouteID,RouteNo,RouteType,Duration,Distance,DaysAvailable,Halt,ModeType)
SELECT
R.RouteID,R.RouteNo, RT.RouteType,R.Duration,R.Distance,R.DaysAvailable, RH.Halt,M.ModeType
from
ModeTypes M
inner join
RouteTypes RT on M.ModeTypeID=RT.ModeTypeID
inner join
Routes R on RT.RouteTypeID=R.RouteTypeID
inner join
RouteHalts RH on R.RouteID=RH.RouteID
where
RH.RouteID=@EndingRouteID and RH.Halt not like'%'+ @EndingPoint +'%'
order by
R.RouteNo,RH.HaltNo
END
-- Get the intersection Routes
insert into #TmpRts(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.halt,TER.RouteNo,TER.RouteType,TER.ModeType
from
RouteHalts RH
INNER JOIN
#TmpEndingRoute TER on RH.RouteID=TER.RouteID
-- Get the intersection Halt
IF EXISTS( select 1 from RouteHalts RH INNER JOIN #TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute))
begin
print 'in exists'
select
@CrossRouteHalt= TER.Halt
from
RouteHalts RH
INNER JOIN
#TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute)
-- Insert into #TmpIntersection
insert into #TmpIntersection(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.Halt,RouteNo,RouteType,ModeType
from
RouteHalts RH
INNER JOIN
#TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute)
end
-- If no intersection halt exsits then try to get the matching routes from the starting point halts
IF not EXISTS( select 1 from RouteHalts RH INNER JOIN #TmpRts TER on TER.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingRoute))
begin
print 'in not exists'
insert into #TmpRts(RouteID,Halt,RouteNo)
select distinct RH.RouteID,RH.halt,TSR.RouteNo
from
RouteHalts RH
INNER JOIN
#TmpStartingHalts TSR on RH.Halt=TSR.Halt
-- Update the Route type to show the current route type of the connecting routes
update TER
set TER.RouteType = RT.RouteType, TER.ModeType=MT.ModeType
from #TmpRts TER
INNER JOIN Routes R on TER.RouteID=R.RouteID
inner join
RouteTypes RT on R.RouteTypeID=RT.RouteTypeID
inner join
ModeTypes MT on RT.ModeTypeID=MT.ModeTypeID
select
@CrossRouteHalt= TSR.Halt
from
RouteHalts RH
INNER JOIN
#TmpRts TSR on TSR.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingHalts)
-- Insert into #TmpIntersection
insert into #TmpIntersection(RouteID,Halt,RouteNo,RouteType,ModeType)
select RH.RouteID,RH.Halt,RouteNo,RouteType,ModeType
from
RouteHalts RH
INNER JOIN
#TmpRts TSR on TSR.Halt=RH.Halt
where RH.RouteID in (select RouteID from #TmpStartingHalts)
end
/*
Insert all data in to #FinalRoute
*/
-- Insert the Starting Route record
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpStartingRoute
-- Insert the Intersection Halt
insert into #FinalRoute(Halt)
select @CrossRouteHalt
-- Get the new Starting point
delete from #TmpRts where routeid in (select routeid from #TmpStartingRoute)
select RH.RouteID,RH.halt,R.RouteNo,TER.RouteType,TER.ModeType
into #TmpNewStartingPoint
from
RouteHalts RH
INNER JOIN
#TmpRts TER on RH.RouteID=TER.RouteID and TER.RouteID not in (select routeid from #TmpEndingRoute)
inner join Routes R on TER.RouteID=R.RouteID and TER.RouteID not in (select routeid from #TmpEndingRoute)
/*
Insert all data in to #FinalRoute
*/
-- Check if #TmpNewStartingPoint is empty then add the insersection route from #TmpRts else add the data from #TmpNewStartingPoint
IF NOT EXISTS(select 1 from #TmpNewStartingPoint)
BEGIN
print 'in no new starting point'
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID, Halt,RouteNo,RouteType,ModeType from #TmpRts where Halt=@CrossRouteHalt
END
IF EXISTS(select 1 from #TmpNewStartingPoint)
BEGIN
print 'in new starting point'
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpNewStartingPoint where halt in (select halt from #TmpEndingHalts)
END
-- Insert the Ending Route record
insert into #FinalRoute(RouteID,Halt,RouteNo,RouteType,ModeType)
select RouteID,Halt,RouteNo,RouteType,ModeType from #TmpEndingRoute
select * from #FinalRoute
修改1 我发现这些链接很有趣,所以在这里添加
答案 0 :(得分:2)
您需要使用旅行费用创建网络网格,以便使用Travel Salesman Promblem
或djistra
short A*
算法解决旅行问题
就我而言,我使用postgres lib PgRouting
http://workshop.pgrouting.org/chapters/shortest_path.html#
在图表中
链接
这样您就可以使用TSP算法来优化成本。您使用每种速度计算成本以计算Time = Distance / Speed
或仅计算distance
。您也可以在使用像忽略总线路由之类的算法之前更改select
中的网格。或使用实时交通改变道路速度