毕设进程:公交换乘算法

这个最开始是在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);
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值