分支限界法-优先队列-单源最短路径
算法思想:
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
给定一个带权有向图G=(V,E),其中每条边的权是非负数。给定V中的一个顶点,成为源。现在要计算从源到所有其他个顶点的最短路径长度,这里路径长度指的是各边权之和。这个问题通常被称作单源最短路径问题。
如图所示,每一边都有一非负权值。求图G到原点s的到t的最短路径。
// ShortestPaths.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<queue>
#define inf -1
using namespace std;
template<class Type>
class Graph
{
friend int main(void);
public:
void ShortestPath(int t);
private:
int* prev,//前驱顶点数组n;
n;
Type** c,//G的临界矩阵
* dist;
int best;
};
template<class Type>
class MinHeapNode
{
friend Graph<Type>;
public:
operator int()const { return length; }
int x[12];
private:
int i;
int Pos;
Type length;
};
MinHeapNode<int> H;
template<class Type>
void Graph<Type>::ShortestPath(int t)
{
priority_queue<MinHeapNode<Type>> priority;
MinHeapNode<Type> E;
E.i = t;
E.length = 0;
E.Pos = 1;
dist[t] = 0;
while (true)
{
for (int j = 1; j <= n; j++)
{
if (c[E.i][j] != inf && E.length + c[E.i][j] < dist[j])
{
dist[j] = E.length + c[E.i][j];
prev[j] = E.i;
E.x[E.Pos] = j;
E.Pos++;
MinHeapNode<Type> N;
N.i = j;
N.length = dist[j];
memcpy(N.x, E.x, 12 * sizeof(int));
N.Pos = E.Pos;
priority.push(N);
if (j == n&&best> dist[j])
{
best = dist[j];
H = N;
}
}
}
if (!priority.empty())
{
E = priority.top();
priority.pop();
}
else
{
break;
}
}
}
int main()
{
Graph<int> graph;
graph.c = new int* [12];
for (int i = 0; i < 12; i++)
(graph.c)[i] = new int[12];
for (int i = 0; i < 12; i++)
for (int j = 0; j < 12; j++)
(graph.c)[i][j] = inf;
(graph.c)[1][2] = 2, (graph.c)[1][3] = 3, (graph.c)[1][4] = 4;
(graph.c)[2][5] = 7, (graph.c)[2][6] = 2, (graph.c)[2][3] = 3;
(graph.c)[3][6] = 9, (graph.c)[3][7] = 2;
(graph.c)[4][7] = 2;
(graph.c)[5][8] = 3, (graph.c)[5][9] = 3;
(graph.c)[6][9] = 3, (graph.c)[6][7] = 1;
(graph.c)[7][9] = 5, (graph.c)[7][10] = 1;
(graph.c)[8][11] = 3;
(graph.c)[9][11] = 2;
(graph.c)[10][9] = 2, (graph.c)[10][11] = 2;
graph.dist = new int[12];
for (int i = 0; i < 12; i++)
graph.dist[i] = 10000;
graph.n = 11;
graph.prev = new int[12];
graph.best = 1000;
graph.ShortestPath(1);
for (int i = 1; i < 12; i++)
cout << graph.prev[i] << "\t";
cout << endl;
for (int i = 1; i < 12; i++)
cout << graph.dist[i] << "\t";
cout << endl;
cout << H.operator int() << endl;
for (int i = 1; i <= 11; i++)
cout << H.x[i] << "\t" ;
cout << endl;
return 0;
}