您的位置:首页 > 其它

对加权(无负值边)的图进行最短路径搜索

2015-09-03 18:24 337 查看

摘要:本次对加权边的图进行单源最短路径搜索.

(1)与无权搜索有什么不一样?以前的算法在加权边上行不通了,这是因为从最短路径为k的点到相邻的点的路径不一定是最短路径,因为这条连接的边可能很长.

(2)基本思路:利用Dijkstra算法-

[1]首先访问起始点的所有邻接定点,找到到起始点最短的一个,将它标记为已访问.

[2]将该节点设置为当前节点,访问它的所有节点,并更新它们到起始点的最短路径距离.(一开始除了起始点本身距离都是Infinity)

[3]在所有的未访问的节点中找到一个最短路径,然后重复[1]

[4]直到所有的节点都被访问.

(3)注意细节:

[1]我们用了一个自定义的数据结构-Table.,该结构用来存放节点的距离,是否访问等信息.

[2]如果采用扫描表的办法,这个算法花费了O(|V|^2)来找最小未知点,花费了O(|E|)来更新距离.如果表是稠密的,那么该算法很好.如果不是,那么在寻找最小距离上的开销就太多了,这个时候可以考虑采用优先队列.

struct TableEntry
{
List Header;
int distance;
int path;
bool known;
};
typedef TableEntry Table[Number];
void ReadGraph(Graph G,Table T)
{
for (int i =0;i<=Number -1;i++)
{
T[i].Header = G[i];
}
}
void InitTable(Table T,Graph G,int start,int mark)//mark = Infinity/0
{
ReadGraph(G,T);//将图的邻接情况读入表
for (int i = 0;i<=Number-1;i++)
{
T[i].known = false;
T[i].path = Notvertex;
T[i].distance = mark;
}
T[start].distance = Infinity - mark;
}
int FindMinunknown(Table T)
{
int min = Infinity,index;
for (int i = 0;i<=Number-1;i++)
{
if (T[i].known!=true&&T[i].distance < min)
{
min = T[i].distance;
index = i;
}
}
return index;
}

void Dijstra(Table T,int start)
{
//加权无负值
int v,w,cw,counter = 0;
while(counter <=Number-1)
{

//找到最小未知节点
v = FindMinunknown(T);
T[v].known = true;
T[v].Header = T[v].Header->Next;
counter++;//处理好的元素个数加1;
while(T[v].Header!=NULL)
{

w = T[v].Header->Element;
cw = T[v].Header->weight;
if(T[w].known != true&&cw+T[v].distance <T[w].distance)
{
//更新
T[w].distance = cw+T[v].distance;
T[w].path = v;
}
T[v].Header = T[v].Header->Next;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 dijkstra