这个最开始是在i一个论文上看到的,是Dijkstral之外我见到的第一个关于公交换乘的算法。但是论文里面讲的太复杂啦,后来就到CSDN上看了公交换乘算法的介绍,懂了大概流程,但是改进算法我没看,只是知道是要先比较一下经过起终点的公交线先选择一个较少的,然后从这里开始判断直达,一次换乘,两次换乘。
算法最终是自己写的,下面贴出来:
change_res结构作为函数的返回值,方便后期写入到数据库中
struct change_res
{
int flag;
int station[10];
int bus[3];
};
bool in_array(int array[],int t)
{
int i=0;
int location=false;
while(array[i++]!=0&&location==false)
{
if(array[i-1]==t)
location=true;
}
return location;
}
void create_bus_line(int n,int bus_line[],int bus_id)
{
int i=0,j=0,k=0,flag=0;
int bus_start=0;
for(i=1;(flag==0)&&(i<=n);i++)
{
for(j=1;(flag==0)&&(j<=n);j++)
{
if(g[i][j].bus_id==bus_id)
{
flag=1;
for(k=j+1;(flag==1)&&(k<=n);k++)
{
if(g[i][k].bus_id==bus_id)
flag=2;
}
}
}
}//找到起点flag=1;
if(flag==1)
{
i--;
j--;
bus_line[0]=i;
bus_line[1]=j;
k=2;
for(i=1;i<=n;i++)
{
if(in_array(bus_line,i))
{}
else
{
if(g[j][i].bus_id==bus_id)
{
bus_line[k++]=i;
j=i;
i=0;
}
}
}//构建完成
}
}
change_res direct_arrive(int n,int s,int t)
{
int i=0,j=0,k=0,n_s=0,n_t=0,bus_s[20]={0},bus_t[20]={0};
int bus_line[20]={0};
int flag=0;
change_res temp_res={0,{0},{0}};
// change_res* p_temp_res=&temp_res;
//选择经过的公交车线较少的站点
for(i=1;i<=n;i++)
{
if(g[s][i].bus_id!=0)
{
if(in_array(bus_s,g[s][i].bus_id))
{}
else
{
bus_s[j++]=g[s][i].bus_id;
n_s++;
}
}
if(g[t][i].bus_id!=0)
{
if(in_array(bus_t,g[t][i].bus_id))
{}
else
{
bus_t[k++]=g[t][i].bus_id;
n_t++;
}
}
}
if(n_s<n_t)//经过s的公交线较少,选择s
{
for(i=0;bus_s[i]!=0&&flag==0;i++)
{
//构建bus_s[i]表示的公交线
create_bus_line(n,bus_line,bus_s[i]);
if(in_array(bus_line,s)&&in_array(bus_line,t))
{
flag=1;
//result_bus[0]=bus_s[i];
temp_res.flag=t;
temp_res.station[0]=s;
temp_res.station[1]=t;
temp_res.bus[0]=bus_s[i];//目前没有比较 多条线路 的情况,bus
}
}
}
else
{
for(i=0;bus_t[i]!=0&&flag==0;i++)
{
//构建bus_t[i]表示的公交线
create_bus_line(n,bus_line,bus_t[i]);
if(in_array(bus_line,s)&&in_array(bus_line,t))
{
flag=1;
// result_bus[0]=bus_t[i];
temp_res.flag=t;
temp_res.station[0]=s;
temp_res.station[1]=t;
temp_res.bus[0]=bus_t[i];//目前没有比较多条线路的情况,bus
}
}
}
if(flag=0)
temp_res.flag=0;
return temp_res;
// return p_temp_res;
}//没有比较多种选择时的最优路线
change_res one_change_arrive(int n,int s,int t)
{
int i=0,flag=0,min=length_inf*cost_inf;//值可能有问题
int s_direct=0,t_direct=0;
int s_bus=0,t_bus=0;
change_res temp_res={0,{0},{0}};
// change_res *p_temp_res=temp_res;
//找出到s直达,到t也直达的点
for(i=1;i<=n&&flag==0;i++)
{
s_direct=direct_arrive(n,s,i).flag;
s_bus=direct_arrive(n,s,i).bus[0];
t_direct=direct_arrive(n,i,t).flag;
t_bus=direct_arrive(n,i,t).bus[0];
if((s_direct!=0)&&(t_direct!=0))
{
//if(min>)
flag=1;
temp_res.flag=i;
temp_res.station[0]=s;
temp_res.station[1]=i;
temp_res.station[2]=t;
temp_res.bus[0]=s_bus;//目前没有比较多条线路的情况,bus
temp_res.bus[1]=t_bus;
}
}
if(flag==0)
temp_res.flag=0;
return temp_res;
}
change_res two_change_arrive(int n,int s,int t)
{
int i=0,flag=0;
int s_direct=0,t_change=0;
int s_bus=0,i_bus=0,t_bus=0;
change_res temp_res={0,{0},{0}};
for(i=1;i<=n&&flag==0;i++)
{
s_direct=direct_arrive(n,s,i).flag;
t_change=one_change_arrive(n,i,t).flag;
s_bus=direct_arrive(n,s,i).bus[0];
i_bus=one_change_arrive(n,i,t).bus[0];
t_bus=one_change_arrive(n,i,t).bus[1];
if((s_direct!=0)&&(t_change!=0))
{
flag=1;
temp_res.flag=i;
temp_res.station[0]=s;
temp_res.station[1]=s_direct;
temp_res.station[2]=t_change;
temp_res.station[3]=t;
temp_res.bus[0]=s_bus;
temp_res.bus[1]=i_bus;
temp_res.bus[2]=t_bus;
}
}
if(flag==0)
temp_res.flag=0;
return
temp_res;
}
//将结果写入数据库,写入bus_id和站点
void result_output_Huan(PGconn*conn,change_res temp_res)
{
int i=0;
PGresult*res;
char* paramValues[1];
char temp[10];
//先将result_station,result_bus表清空
res=PQexec(conn,"DELETE FROM result_station WHERE station_id>0");
PQclear(res);
res=PQexec(conn,"DELETE FROM result_bus WHERE bus_id>0");
PQclear(res);
if(temp_res.flag==0)
{
//已清空result_station和result_bus表
//do nothing
}
else
{
//写入result_station,result_bus
for(i=0;temp_res.station[i]!=0;i++)
{
itoa(temp_res.station[i],temp,10);
paramValues[0]=temp;
res=PQexecParams(conn,"INSERT INTO result_station (station_id,way) VALUES ($1::BIGINT,(SELECT way FROM planet_osm_station WHERE station_id=$1::BIGINT))",
1,
NULL,
paramValues,
NULL,
NULL,
0);
fprintf(stderr,"%s",PQerrorMessage(conn));
PQclear(res);
}
for(i=0;temp_res.bus[i]!=0;i++)
{
itoa(temp_res.bus[i],temp,10);
paramValues[0]=temp;
res=PQexecParams(conn,"INSERT INTO result_bus (bus_id,way) VALUES ($1::BIGINT,(SELECT way FROM planet_osm_bus WHERE bus_id=$1::BIGINT))",
1,
NULL,
paramValues,
NULL,
NULL,
0);
fprintf(stderr,"%s",PQerrorMessage(conn));
PQclear(res);
}
}
}