类似于分支限界

问题描述:

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值