问题描述:
已知一拓扑网络,在其中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;
}