问题描述:
已知一拓扑网络,在其中1和6号节点中,有目标出现,同时也已知了两节点之间的间隔时间,其中目标车辆的速度v为10m/s,间隔40s
其临界表如下所示:
代码如下:
#include "stdafx.h" #include <iostream> #include <stdlib.h> #include <queue> #define MAX_VERTEX_NUM 6 #define MAX_VALUE_TYPE INT_MAX typedef int VertexType; int visit[MAX_VERTEX_NUM]; std::queue<int> Q; //存储活节点 std::queue<int*> Q_lujing; //存储路径和距离 typedef struct node { VertexType adjvex; int weight; struct node* next; }EdgeNode; //边表节点 typedef struct vnode { VertexType vertex; int dist; int len; int path[MAX_VERTEX_NUM]; EdgeNode *firstedge; }VertexNode; //表头节点 typedef VertexNode adjList[MAX_VERTEX_NUM]; typedef struct { adjList adjlist; int n, e; }ALGraph; void CreateALGraph(ALGraph *G) { int i, j; int k; EdgeNode *s; scanf("%d%d", &G->n, &G->e); for (i = 0; i <G->n; i++) { scanf("%d", &G->adjlist[i].vertex); G->adjlist[i].firstedge = NULL;//边表设置成空表 } for (k = 1; k <= G->e; k++) { int nwight = 0; scanf("%d%d", &i, &j);//i = Locate(G, i); j = Locate(G, j); //查找结点序号 s = (EdgeNode *)malloc(sizeof(EdgeNode)); scanf("%d", &nwight); s->weight = nwight; s->adjvex = j;//邻接点序号为j s->next = G->adjlist[i].firstedge; G->adjlist[i].firstedge = s; s = (EdgeNode *)malloc(sizeof(EdgeNode)); s->adjvex = i; s->weight = nwight; s->next = G->adjlist[j].firstedge; G->adjlist[j].firstedge = s; } } void print(ALGraph *G) { EdgeNode *p; int i; for(i=0; i<G->n; i++) { printf("index %d VERTEX %d", i, G->adjlist[i].vertex); for(p = G->adjlist[i].firstedge; p ; p = p->next) { printf("->\tVERTEX %d weight %d", p->adjvex, p->weight); } putchar('\n'); } } void GetNewPathWay( ALGraph * g , int k , int i )///---------更新路径函数------------------------- { int j; for( j = 0 ; j <= g->adjlist[k].len ; j++ ) g->adjlist[i].path[j] = g->adjlist[k].path[j]; //拷贝k中的路径 g->adjlist[i].path[j] = i; } int ShowPathWay( ALGraph * g , int y )///----------------------输出路径函数------------------------- { /*int i,j; printf("最短路径是:\n"); for ( i = 0; i <= g->adjlist[y].len; i++) { printf("%d->",g->adjlist[g->adjlist[y].path[i]].vertex + 1); } printf("\n最短距离为:\n"); printf("%d\n\n",g->adjlist[y].dist);*/ return g->adjlist[y].dist; } void Visit( ALGraph * g )///-------------初始化路径 { int i,j; for( i = 0 ; i <g->n ; i ++) { visit[i] = false; g->adjlist[i].dist = INT_MAX; g->adjlist[i].len = 0; for( j = 0 ; j < g->n ; j ++ ) g->adjlist[i].path[j] = INT_MAX; } } int Dijkstra( ALGraph * g , int _start, int _end)///---------------------DIJKSTRA算法---(权值无负数)--------------------------- { int x = _start ,y = _end; int s = 0; /*while( (scanf("%d",&x))!= EOF , x != -1 && x != 0 && x <= g->n ) { */ Visit( g ); //初始化路径 int i , j , k , m , min = 0 , t; g->adjlist[x-1].dist = 0; g->adjlist[x-1].path[0] = x-1; k = x-1; EdgeNode * p; for( i = 0 ; i < g->n ; i ++)//计算每个点到其实点的距离 { t = INT_MAX; p = g->adjlist[k].firstedge; visit[k] = true; //k表示已经访问了 while( p ) { if( !visit[p->adjvex])//如果这个节点没有访问过 { if( g->adjlist[k].dist == INT_MAX ) { g->adjlist[p->adjvex].dist = p->weight; g->adjlist[p->adjvex].len = g->adjlist[k].len+1; GetNewPathWay( g , k , p->adjvex); } else if( g->adjlist[k].dist + p->weight < g->adjlist[p->adjvex].dist ) { g->adjlist[p->adjvex].dist = g->adjlist[k].dist + p->weight; g->adjlist[p->adjvex].len = g->adjlist[k].len+1; GetNewPathWay( g ,k , p->adjvex); } } p = p->next; } for( j = 0 ; j < g->n ; j++) { if( g->adjlist[j].dist < t && !visit[j] ) { t = g->adjlist[j].dist; min = j; } } k = min; } s = ShowPathWay( g ,y-1 ); return s; } void printf_yuce(int arr[10]) { int num = arr[9];//数组中元素的个数 for (int i = 0; i < num; i++) { std::cout << arr[i] << " ,"; } std::cout << std::endl; } //分支限界查找 void DFS_S(ALGraph *g, int v/*速度*/, int start_Node, int last_Node, int time_limit) { while(!Q.empty()) Q.pop(); while(!Q_lujing.empty()) Q_lujing.pop(); int *temp_lj = new int[10];//第九项表示距离,第十项表示数组中元素的个数 temp_lj[0] = start_Node; temp_lj[9] = 1; temp_lj[8] = 0; Q.push(start_Node); //初始节点放入队列中 Q_lujing.push(temp_lj); while (!Q.empty()) { int curNode = Q.front(); int *temp_c = Q_lujing.front(); if ( curNode == last_Node ) //如果当前节点正好为结束点,则输出 { int* p = Q_lujing.front(); printf_yuce(p);//输出 Q.pop(); Q_lujing.pop(); delete p; continue; } int timed = temp_c[8]/v; //计算已经经过的时间 int remain_time = Dijkstra(g, curNode, last_Node)/v; //剩下多少时间 //限定条件判断 if ( timed <= time_limit && remain_time <= (time_limit - timed) ) //如果当前节点满足限定条件 { //将其相邻节点全部放入队列中 EdgeNode *temp = g->adjlist[curNode-1].firstedge; while (temp != NULL) { int num = temp_c[9]; int *temp_n = new int[10]; temp_n[9] = temp_c[9] + 1; temp_n[8] = temp_c[8] + temp->weight; for (int i = 0; i < num; i++) { temp_n[i] = temp_c[i]; } temp_n[num] = temp->adjvex + 1; Q_lujing.push(temp_n); Q.push(temp->adjvex + 1); temp = temp->next; } } Q.pop(); int* p = Q_lujing.front(); Q_lujing.pop(); delete p; } } int _tmain(int argc, _TCHAR* argv[]) { int v = 10; //速度m/s int limit_time = 40; //两点间时间秒 int start_node = 1; //开始节点 int end_node = 6; //最末节点 FILE *fp; fp = freopen("my.txt", "r", stdin); ALGraph G; CreateALGraph(&G); fclose(fp); print(&G); DFS_S(&G, v, start_node, end_node, limit_time); system("pause"); return 0; }