贪心算法之单源最短路径

问题:在一个有向网络中,从某点出发得到所有到该顶点的最短距离。


迪杰斯特拉算法是解单源最短路径问题的一个贪心算法,其基本思想是,设置顶点集合S不断的贪心选择来扩充这个集合。当源点到该顶点的最短距离已知,则添加到集合来,最终包括网络中的所有顶点。


贪心选择:

step1:首先选择网络中的某一顶点V出发,那么该顶点肯定可以添加到S中,然后以V为源点,得到它到其他顶点的距离(初始化d[],表示V到其他顶点的距离)

step2:在这些顶点中选择没有标记过的(即未添加到S集合中的点)  并且到V的距离最小的顶点V’,然后将其标记

step3:更新d[],从V'出发遍历网络没有标记的顶点,如果找到一个点d[u]+edge[u][j]<d[j]的情况,则更新d[j]=d[u]+edge[u][j]

step4:重复step2


性能分析:

      算法时间主要花在两个for循环中,时间复杂度为O(n2)


代码实现:


#include<stdio.h>

typedef char VertexType;
typedef int EdgeType;
#define MAX 20//定义数组大小
#define INFINITY 500

typedef struct 
{
	VertexType vexs[MAX];
	EdgeType edges[MAX][MAX];
	int vexnum;//记录图的顶点数
	int arcnum;//记录图的边或弧的条数
}AdjMatrix;
//创建图的邻接矩阵
AdjMatrix CreatGraph_Matrix(int graphtype)
{
	AdjMatrix G;
	int i,j,k;
	int weight;
	printf("please input graph's vexnum and arcnum:\n");
	scanf("%d,%d",&G.vexnum,&G.arcnum);
    setbuf(stdin,NULL);
	for(i=1;i<=G.vexnum;i++)
	{
		scanf("%c",&G.vexs[i]);
		 setbuf(stdin,NULL);
	}
	setbuf(stdin,NULL);
	
	for(i=1;i<=G.vexnum;i++)
		for(j=1;j<=G.vexnum;j++)
			G.edges[i][j]=INFINITY;
	for(k=1;k<=G.arcnum;k++)
	{
		printf("please input NO.%d edge's start,end and weight:\n",k);
		scanf("%d,%d,%d",&i,&j,&weight);
		G.edges[i][j]=weight;
	}
	
	return G;
}



void Dijkstra(AdjMatrix &N,int v,int D[],int P[])
{
	int S[MAX];
	int mindistance,temp;
	int i,j,u;
	/*******开始初始化的工作*******/
	for(i=1;i<=N.vexnum;i++)//前提是采取邻接矩阵储存,并且是有向网络
	{
		D[i]=N.edges[v][i];
		S[i]=0;
		if(INFINITY==N.edges[v][i])
			P[i]=-1;
		else
			P[i]=v;
	}

	S[v]=1;
	/**********开始最短路径求解************/
	for(i=1;i<=N.vexnum;i++)
	{
		mindistance=INFINITY;
		//在D中找出尚未确定最短路径的顶点中路径长度最小的顶点u
		for(j=1;j<=N.vexnum;j++)
		{
			if(0==S[j]&&D[j]<mindistance)
			{
				mindistance=D[j];
				u=j;
			}
		}
		S[u]=1;//找到路径最小的顶点,然后进行标识

		//对还未确定最短路径的顶点进行调整
		for(j=1;j<=N.vexnum;j++)
		{
			if(0==S[j])//未确定最短路径的顶点
			{
				temp=D[u]+N.edges[u][j];
			    if(D[j]>temp)
				{
					D[j]=temp;//修改最短路径
				    P[j]=u;//同时修改前驱
				}
			}
		}
	
	}
}
int main()
{
	AdjMatrix G;
	G=CreatGraph_Matrix(51);
    int D[MAX],P[MAX];
	Dijkstra(G,1,D,P);
    for(int i=1;i<=G.vexnum;i++)
	{
		printf("D[%d]=%d,P[%d]=%d\n",i,D[i],i,P[i]);
	}
	return 0;
}



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
贪心算法单源最短路径指的是在一个加权有向图中,从给定的源点到所有其他顶点的最短路径问题。Dijkstra算法是最常用的贪心算法之一,用于解决单源最短路径问题。其基本思想是从源点开始,每次选择当前最短路径的顶点,并更新其相邻顶点的距离,直到所有顶点都被遍历。具体步骤如下: 1.初始化:将源点到所有顶点的距离初始化为无穷大,源点到自身的距离为0。 2.选择当前最短路径的顶点:从未确定最短路径的顶点中选择距离最短的顶点。 3.更新相邻顶点的距离:对于当前选定的顶点,更新其相邻顶点的距离,如果经过当前顶点到达相邻顶点的距离比原来的距离更短,则更新距离。 4.重复步骤2和3,直到所有顶点都被遍历。 以下是一个使用Dijkstra算法求解单源最短路径的Python代码示例: ```python import heapq def dijkstra(graph, start): # 初始化距离 distances = {vertex: float('infinity') for vertex in graph} distances[start] = 0 # 使用堆来存储顶点和距离 pq = [(0, start)] while pq: # 取出距离最小的顶点 current_distance, current_vertex = heapq.heappop(pq) # 如果当前距离大于已知最短距离,则跳过 if current_distance > distances[current_vertex]: continue # 更新相邻顶点的距离 for neighbor, weight in graph[current_vertex].items(): distance = current_distance + weight if distance < distances[neighbor]: distances[neighbor] = distance heapq.heappush(pq, (distance, neighbor)) return distances ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值