Dijkstra算法的验证

本文介绍了一种使用迪杰斯特拉算法寻找图中两点间最短路径的方法,并通过具体的代码实现了该算法。通过递归查找路径上的顶点并输出从指定起点到各个可达顶点的最短路径。

头文件及功能函数详见【图算法库】

代码:

#include "graph.h"
#define MaxSize 100


void Ppath(int path[],int i,int v)  //前向递归查找路径上的顶点
{
    int k;
    k=path[i];
    if (k==v)  return;          //找到了起点则返回
    Ppath(path,k,v);            //找顶点k的前一个顶点
    printf("%d,",k);            //输出顶点k
}
void Dispath(int dist[],int path[],int s[],int n,int v)
{
    int i;
    for (i=0; i<n; i++)
        if (s[i]==1)
        {
            printf("  从%d到%d的最短路径长度为:%d\t路径为:",v,i,dist[i]);
            printf("%d,",v);    //输出路径上的起点
            Ppath(path,i,v);    //输出路径上的中间点
            printf("%d\n",i);   //输出路径上的终点
        }
        else  printf("从%d到%d不存在路径\n",v,i);
}
void Dijkstra(MGraph g,int v)
{
    int dist[MAXV],path[MAXV];
    int s[MAXV];
    int mindis,i,j,u;
    for (i=0; i<g.n; i++)
    {
        dist[i]=g.edges[v][i];      //距离初始化
        s[i]=0;                     //s[]置空
        if (g.edges[v][i]<INF)      //路径初始化
            path[i]=v;
        else
            path[i]=-1;
    }
    s[v]=1;
    path[v]=0;              //源点编号v放入s中
    for (i=0; i<g.n; i++)               //循环直到所有顶点的最短路径都求出
    {
        mindis=INF;                 //mindis置最小长度初值
        for (j=0; j<g.n; j++)       //选取不在s中且具有最小距离的顶点u
            if (s[j]==0 && dist[j]<mindis)
            {
                u=j;
                mindis=dist[j];
            }
        s[u]=1;                     //顶点u加入s中
        for (j=0; j<g.n; j++)       //修改不在s中的顶点的距离
            if (s[j]==0)
                if (g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])
                {
                    dist[j]=dist[u]+g.edges[u][j];
                    path[j]=u;
                }
    }
    Dispath(dist,path,s,g.n,v);     //输出最短路径
}


int main()
{
    MGraph g;
    int A[6][6]=
    {
        {0,50,10,INF,45,INF},
        {50,0,15,INF,5,INF},
        {20,INF,0,15,INF,INF},
        {INF,20,INF,0,35,INF},
        {INF,INF,INF,30,0,INF},
        {INF,INF,INF,3,INF,0},
    };
    ArrayToMat(A[0], 6, g);
    Dijkstra(g,0);
    return 0;
}

测试用图:

 

运行结果:

### Dijkstra算法的实现与正确性验证 Dijkstra算法是一种用于计算加权图中最短路径的经典贪心算法。它通过逐步扩展已知距离来找到从起点到其他节点的最短路径[^1]。 #### 使用Java实现Dijkstra算法 以下是基于优先队列优化版本的Dijkstra算法的Java代码实现: ```java import java.util.*; public class Dijkstra { static class Edge implements Comparable<Edge> { int vertex; int weight; public Edge(int v, int w) { this.vertex = v; this.weight = w; } @Override public int compareTo(Edge other) { return Integer.compare(this.weight, other.weight); } } public static void dijkstra(List<List<Edge>> graph, int start, int[] distances) { PriorityQueue<Edge> pq = new PriorityQueue<>(); Arrays.fill(distances, Integer.MAX_VALUE); distances[start] = 0; pq.offer(new Edge(start, 0)); while (!pq.isEmpty()) { Edge current = pq.poll(); int u = current.vertex; int d = current.weight; if (d > distances[u]) continue; // 已经有更优解跳过 for (Edge edge : graph.get(u)) { // 遍历邻接表中的每条边 int v = edge.vertex; int weight = edge.weight; if (distances[v] > distances[u] + weight) { // 更新条件 distances[v] = distances[u] + weight; pq.offer(new Edge(v, distances[v])); } } } } public static void main(String[] args) { int n = 5; // 节点数 List<List<Edge>> graph = new ArrayList<>(n); for (int i = 0; i < n; ++i) { graph.add(new ArrayList<>()); } // 构建带权重的无向图 addDirectedEdge(graph, 0, 1, 4); addDirectedEdge(graph, 0, 2, 1); addDirectedEdge(graph, 2, 1, 2); addDirectedEdge(graph, 1, 3, 1); addDirectedEdge(graph, 2, 3, 3); addDirectedEdge(graph, 3, 4, 2); int[] distances = new int[n]; dijkstra(graph, 0, distances); // 计算从顶点0出发的距离 System.out.println(Arrays.toString(distances)); // 输出结果 } private static void addDirectedEdge(List<List<Edge>> graph, int from, int to, int weight) { graph.get(from).add(new Edge(to, weight)); } } ``` 上述代码实现了带有优先队列优化的Dijkstra算法,能够高效处理稀疏图的情况。 #### C++实现及其测试用例 对于C++语言,可以利用`std::priority_queue`配合自定义比较器完成相同功能。下面是一个简单的例子以及对应的测试用例: ```cpp #include <bits/stdc++.h> using namespace std; struct Node { int id; long dist; }; bool operator>(const Node& lhs, const Node& rhs) { return lhs.dist > rhs.dist; } void dijkstra(vector<vector<pair<int, int>>> &graph, vector<long>& distance, int source) { priority_queue<Node, vector<Node>, greater<>> pq; fill(distance.begin(), distance.end(), LLONG_MAX); distance[source] = 0; pq.push({source, 0}); while (!pq.empty()) { auto top = pq.top(); pq.pop(); int u = top.id; long du = top.dist; if (du != distance[u]) continue; for (auto &[v, w] : graph[u]) { if (distance[v] > distance[u] + w) { distance[v] = distance[u] + w; pq.push(Node{v, distance[v]}); } } } } int main() { int V = 6; vector<vector<pair<int, int>>> adj(V); // 添加边并设置权重 adj[0].emplace_back(1, 7); adj[0].emplace_back(2, 9); adj[0].emplace_back(5, 14); adj[1].emplace_back(2, 10); adj[1].emplace_back(3, 15); adj[2].emplace_back(3, 11); adj[2].emplace_back(5, 2); adj[3].emplace_back(4, 6); adj[4].emplace_back(5, 9); vector<long> distance(V); dijkstra(adj, distance, 0); cout << "Shortest Distances:" << endl; for (int i = 0; i < V; ++i) cout << "Node " << i << ": " << distance[i] << "\n"; } ``` 此程序展示了如何构建一个具有多个连接关系的图,并应用Dijkstra算法求解源节点至其余各节点间的最小代价路径长度[^2]。 #### 测试用例设计原则 为了全面检验Dijkstra算法的有效性和鲁棒性,应考虑以下几种典型场景: - **简单线性链路**:仅存在单一方向上的连续链接。 - **完全连通网络**:任意两点间均至少有一条直接或间接可达路线。 - **含有负权重循环**:尽管标准版不支持此类情形,但仍需确认其行为表现合理。 - **大规模随机生成实例**:评估性能极限及稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值