Reachability analysis of Dijstra algorithm for heap optimization

Keywords: less Windows

1. Problem description

Given a graph structure, including n points, e edges, given a search radius of 100000, solve all points with a distance of 100000 s from the source point. The distance here should still refer to the weight of.

Data file "union.txt", format:

start_id,end_id,weight,start_x,start_y,end_x,end_y
1,101043,540,567.988263,99.564119,567.988263,100.104119
......

2. Algorithm strategy

The solution of the shortest path of single source can be modified slightly, and the realization idea is exactly the same. In the process of searching, it is found that the weight of a node is less than or equal to 100000, then the node is output and recorded, because each node may be relaxed many times, so it needs to be marked as 1 to avoid duplicate records. That is to say, if a node is not finally recorded, it is either not reachable, or the weight is still greater than 100000 after all the slack.

Nodes are recorded in search order. In order to verify the correctness, the recorded node ID is sorted and output. At the same time, the dist array is traversed directly, and the ID whose weight is less than or equal to 100000 is output. Comparing the two results, it is found that the results are equal. The result is correct.

3. Code implementation

#include "stdio.h"
#include "windows.h"
#include <vector>
#include <queue>
#include <stack>
#include <ctime>
using namespace std;

#define MAXN 195234 //1 ... 195233
#define MAXW 0x3f3f3f3f3f3f / / maximum weight

typedef struct WNode{
	int id;
	int cur_w;
	bool operator<(const WNode& n)const{
		return cur_w>n.cur_w;
	}
	WNode(int id,int cur_w):id(id),cur_w(cur_w){}
}WNode;

//Graph[i] stores the number j of nodes adjacent to node i and the corresponding weight W, Graph[i] = {pair < j, w >,...}
vector<pair<int,int> > Graph[MAXN];
bool visit[MAXN];
int path[MAXN];
int dist[MAXN];
int searched[MAXN];
vector<int> ans;

int s; //Source point
int searchRadius; //Search radius
clock_t start,finish;

//Read in file for initialization
bool Initialize(){
	printf("Input the starting point: ");
	scanf("%d",&s);
	printf("Input the searching radius: ");
	scanf("%d",&searchRadius);

	printf("\nInputing data...\n");
	start=clock();
	FILE* fp=fopen("union.txt","r");
	if(fp==NULL){
		printf("File open error./n");
		return -1;
	}
	int sid,tid,w;
	double sx,sy,tx,ty;
	fscanf(fp,"%*[^\n]%*c");//Skip first line
	while(true){
		fscanf(fp,"%d,%d,%d,%lf,%lf,%lf,%lf",&sid,&tid,&w,&sx,&sy,&tx,&ty);
		Graph[sid].push_back(make_pair(tid,w));
		if(sid%1000==0){
			printf("\r[%.2f%%]",sid/195233.0*100);
			fflush(stdout);
		}
		if(sid==195233){
			printf("\r[%.2f%%]",sid/195233.0*100);
			finish=clock();
			printf("\nData input successfully.\n");
			printf("Total time is %.2fs.\n",(double)(finish-start)/CLOCKS_PER_SEC);
			break;
		}
	}
	fclose(fp);
	return true;
}

//Solve the shortest path, output and save the points in the range to a file
void ShortestPath(int s){
	printf("\nPoints in range %d are: \n",searchRadius);
	start=clock();
	FILE* fp=fopen("101.txt","w");

	memset(path,0,sizeof(path));
	memset(visit,0,sizeof(visit));
	memset(dist,MAXW,sizeof(dist));	
	memset(searched,0,sizeof(searched));
	priority_queue<WNode> qu;
	qu.push(WNode(s,0));
	path[s]=0;
	dist[s]=0;

	while(!qu.empty()){
		WNode cur=qu.top();
		qu.pop();
		if(visit[cur.id])continue;
		visit[cur.id]=1;

		for(int i=0;i<Graph[cur.id].size();i++){
			pair<int,int> tmp=Graph[cur.id][i];
			if(!visit[tmp.first]){	//Team up those who have not been visited
				qu.push(WNode(tmp.first,tmp.second+cur.cur_w));
			}
			if(tmp.second+cur.cur_w < dist[tmp.first]){	//Slack
				dist[tmp.first]=tmp.second+cur.cur_w;
				path[tmp.first]=cur.id;
				//Within the search radius and not searched
				if(dist[tmp.first]<searchRadius && searched[tmp.first]==0){
					searched[tmp.first]=1;
					printf("%d ",tmp.first);//Output to screen
					fprintf(fp,"%d ",cur.id);//output to a file
					ans.push_back(tmp.first);//The results are recorded in ans
				}
			}
		}
	}
	fclose(fp);
	printf("\n\nPath solved successfully.\n");
	finish=clock();
	printf("Total time is %.2fs.\n\n",(double)(finish-start)/CLOCKS_PER_SEC);
}

int _tmain(int argc, _TCHAR* argv[])
{
	Initialize();
	ShortestPath(s);
	printf("-----To verify the correctness, sort the ID array and print it:-----\n");
	sort(ans.begin(),ans.end());
	for(int i=0;i<ans.size();i++){
		printf("%d ",ans[i]);
	}
	printf("\n-----Compared with the IDs directly from the dist array:-----\n");
	for(int i=1;i<MAXN;i++){
		if(dist[i]<100000 && dist[i]!=0/*Remove the source point itself*/){
			printf("%d ",i);
		}
	}
	printf("\n");
	return 0;
}

4. Result output

Set the source point 101, search the radius 100000, get the node ID in the range, and verify the correctness.

Posted by mikosiko on Mon, 11 Nov 2019 10:38:28 -0800