实验目的:使用分枝限界法求解带权图中从起点到目标点的最短路径长度及经过的路径条数。实验环境:C语言编程环境。实验内容:1 使用邻接矩阵存储带权图。2 使用分枝限界法求解从起点到目标点的最短路径长度及经过的路径条数。算法设计:1 定义一个结构体用于表示图中的边包含起点、终点和权值。2 定义一个优先队列用于存储当前搜索的路径按照路径长度从小到大排列。3 定义一个变量dist数组用于存储从起点到每个顶点
以下是使用分枝限界法求解带权图中从起点到目标点的最短路径长度及经过的路径条数的C语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_VERTEX 100
#define INFINITY 9999
// 定义图的边结构体
typedef struct {
int start;
int end;
int weight;
} Edge;
// 定义优先队列的节点结构体
typedef struct {
int vertex;
int weight;
} QueueNode;
// 定义优先队列结构体
typedef struct {
QueueNode* nodes;
int size;
} PriorityQueue;
// 初始化优先队列
PriorityQueue* initPriorityQueue(int maxSize) {
PriorityQueue* queue = (PriorityQueue*)malloc(sizeof(PriorityQueue));
queue->nodes = (QueueNode*)malloc(maxSize * sizeof(QueueNode));
queue->size = 0;
return queue;
}
// 入队
void enqueue(PriorityQueue* queue, int vertex, int weight) {
int i;
for (i = queue->size - 1; i >= 0; i--) {
if (queue->nodes[i].weight <= weight) {
break;
}
queue->nodes[i + 1] = queue->nodes[i];
}
queue->nodes[i + 1].vertex = vertex;
queue->nodes[i + 1].weight = weight;
queue->size++;
}
// 出队
int dequeue(PriorityQueue* queue) {
int vertex = queue->nodes[0].vertex;
int weight = queue->nodes[0].weight;
for (int i = 1; i < queue->size; i++) {
queue->nodes[i - 1] = queue->nodes[i];
}
queue->size--;
return vertex;
}
// 判断优先队列是否为空
bool isQueueEmpty(PriorityQueue* queue) {
return queue->size == 0;
}
// 使用分枝限界法求解最短路径长度和路径条数
void shortestPath(Edge* graph, int n, int m, int s, int t) {
int dist[MAX_VERTEX]; // 存储最短路径长度
int count[MAX_VERTEX]; // 存储最短路径条数
bool visited[MAX_VERTEX] = { false }; // 记录顶点是否被访问过
PriorityQueue* queue = initPriorityQueue(n); // 初始化优先队列
// 初始化dist数组和count数组
for (int i = 0; i < n; i++) {
dist[i] = INFINITY;
count[i] = 0;
}
dist[s] = 0;
count[s] = 1;
// 将起点添加到优先队列中
enqueue(queue, s, 0);
while (!isQueueEmpty(queue)) {
int u = dequeue(queue); // 取出队列中的路径
visited[u] = true;
// 判断是否到达目标点t
if (u == t) {
break;
}
// 扩展当前路径的下一个顶点
for (int i = 0; i < m; i++) {
if (graph[i].start == u && !visited[graph[i].end]) {
int v = graph[i].end;
int weight = graph[i].weight;
// 更新最短路径长度和最短路径条数
if (dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
count[v] = count[u];
enqueue(queue, v, dist[v]);
} else if (dist[u] + weight == dist[v]) {
count[v] += count[u];
}
}
}
}
// 输出最短路径长度和最短路径条数
printf("最短路径长度:%d\n", dist[t]);
printf("最短路径条数:%d\n", count[t]);
}
int main() {
int n, m, s, t;
Edge graph[MAX_VERTEX];
printf("请输入顶点数和边数:");
scanf("%d%d", &n, &m);
printf("请输入边的起点、终点和权值:\n");
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &graph[i].start, &graph[i].end, &graph[i].weight);
}
printf("请输入起点和目标点:");
scanf("%d%d", &s, &t);
shortestPath(graph, n, m, s, t);
return 0;
}
注意:以上代码中使用了邻接矩阵存储带权图,需要根据实际情况进行修改适配。同时,代码中使用了邻接矩阵的方式来表示带权图,如果希望使用其他方式(如邻接表)来表示带权图,需相应修改代码
原文地址: https://www.cveoy.top/t/topic/hN2V 著作权归作者所有。请勿转载和采集!