算法导论代码 第25章 每对顶点间的最短路径

来源:互联网 发布:淘宝虚拟试衣间入口 编辑:程序博客网 时间:2024/05/21 09:51

25章 每对顶点间的最短路径

25.1 最短路径与矩阵乘法

#include <stdio.h>#include <limits.h>#include <string.h>#include <stdlib.h>typedef struct graph_type *graph;struct edge {int u;int v;int w;};struct vertex {char str_vertex[256];//顶点的字符串表示,显示用};void vertex_ini(struct vertex *v){strcpy(v->str_vertex, "");}struct graph_type {int **adj;struct vertex *vertex_array;int v_num;int e_num;};//顶点是编号为0~v_num-1的数,str_vertex是顶点的字符串表示,显示用graph graph_create(int v_num, char *str_vertex[]){graph g = malloc(sizeof(struct graph_type));g->v_num = v_num;g->e_num = 0;g->adj = malloc(sizeof(int *) * v_num);for (int i = 0; i < v_num; i++) {g->adj[i] = malloc(sizeof(int) * v_num);for (int j = 0; j < v_num; j++) {g->adj[i][j] = 0;}}g->vertex_array = malloc(sizeof(struct vertex) * v_num);for (int i = 0; i < v_num; i++) {strcpy(g->vertex_array[i].str_vertex, str_vertex[i]);}return g;}void graph_destroy(graph g){for (int i = 0; i < g->v_num; i++) {free(g->adj[i]);}free(g->adj);free(g->vertex_array);free(g);}void graph_insert_edge(graph g, struct edge edge){g->adj[edge.u][edge.v] = edge.w;++g->e_num;}void graph_display(graph g){printf("%d vertices,%d edges\n", g->v_num, g->e_num);for (int i = 0; i < g->v_num; i++) {printf("%s: ", g->vertex_array[i].str_vertex);for (int j = 0; j < g->v_num; j++) {if (g->adj[i][j] != 0) {printf("%s,%d ", g->vertex_array[j].str_vertex,       g->adj[i][j]);}}printf("\n");}}typedef struct matrix_type *matrix;struct matrix_type {int row;int col;int **data;};matrix matrix_create(int row, int col){if (row == 0)return NULL;matrix m = malloc(sizeof(struct matrix_type));m->row = row;m->col = col;m->data = malloc(sizeof(int *) * row);for (int i = 0; i < row; i++) {m->data[i] = malloc(sizeof(int) * col);for (int j = 0; j < col; j++) {m->data[i][j] = 0;}}return m;}void matrix_destroy(matrix m){for (int i = 0; i < m->row; i++)free(m->data[i]);free(m->data);free(m);}void matrix_display(matrix m){for (int i = 0; i < m->row; ++i) {for (int j = 0; j < m->col; ++j) {printf("%2d ", m->data[i][j]);}printf("\n");}}void matrix_multiply(matrix A, matrix B, matrix C){if (A->col != B->row) {return;}for (int i = 0; i < A->row; ++i) {for (int j = 0; j < B->col; ++j) {C->data[i][j] = 0;for (int k = 0; k < A->col; ++k) {C->data[i][j] += A->data[i][k] * B->data[k][j];}}}}void matrix_copy(matrix mdst, matrix msrc){if (mdst->row != msrc->row || mdst->col != msrc->col) {matrix_destroy(mdst);mdst->row = msrc->row;mdst->col = msrc->col;mdst->data = malloc(sizeof(int *) * mdst->row);for (int i = 0; i < mdst->row; i++) {mdst->data[i] = malloc(sizeof(int) * mdst->col);}}for (int i = 0; i < mdst->row; i++) {for (int j = 0; j < mdst->col; j++) {mdst->data[i][j] = msrc->data[i][j];}}}void extend_shortest_paths(matrix in,   matrix weight,   matrix out, matrix parent_in, matrix parent_out){int n = in->col;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {out->data[i][j] = in->data[i][j];parent_out->data[i][j] = parent_in->data[i][j];for (int k = 0; k < n; k++) {int dis = (in->data[i][k] == INT_MAX   || weight->data[k][j] ==   INT_MAX) ? INT_MAX : in->data[i][k]    + weight->data[k][j];if (dis < out->data[i][j]) {out->data[i][j] = dis;parent_out->data[i][j] =    parent_in->data[k][j];}}}}}void slow_all_pairs_shortest_paths(graph g, matrix out, matrix parent_out){int n = g->v_num;matrix weight = matrix_create(n, n);matrix parent_in = matrix_create(n, n);for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i == j) {weight->data[i][j] = 0;parent_in->data[i][j] = i;} else {weight->data[i][j] =    g->adj[i][j] != 0 ? g->adj[i][j] : INT_MAX;parent_in->data[i][j] =    g->adj[i][j] != 0 ? i : -1;}}}matrix in = matrix_create(weight->row, weight->col);matrix_copy(in, weight);for (int m = 2; m <= n - 1; m++) {extend_shortest_paths(in, weight, out, parent_in, parent_out);matrix_copy(in, out);matrix_copy(parent_in, parent_out);}matrix_destroy(weight);matrix_destroy(parent_in);matrix_destroy(in);}void faster_all_pairs_shortest_paths(graph g, matrix out, matrix parent_out){int n = g->v_num;matrix weight = matrix_create(n, n);matrix parent_in = matrix_create(n, n);for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i == j) {weight->data[i][j] = 0;parent_in->data[i][j] = i;} else {weight->data[i][j] =    g->adj[i][j] != 0 ? g->adj[i][j] : INT_MAX;parent_in->data[i][j] =    g->adj[i][j] != 0 ? i : -1;}}}matrix in = matrix_create(weight->row, weight->col);matrix_copy(in, weight);for (int m = 1; m < n - 1; m *= 2) {extend_shortest_paths(in, in, out, parent_in, parent_out);matrix_copy(in, out);matrix_copy(parent_in, parent_out);}matrix_destroy(weight);matrix_destroy(parent_in);matrix_destroy(in);}void print_all_pairs_shortest_path(graph g, matrix parent, int i, int j){if (i == j) {printf("%s ", g->vertex_array[i].str_vertex);} else {if (parent->data[i][j] == -1) {printf("no path from %s to %s exist\n",       g->vertex_array[i].str_vertex,       g->vertex_array[j].str_vertex);} else {print_all_pairs_shortest_path(g, parent, i,      parent->data[i][j]);printf("%s ", g->vertex_array[j].str_vertex);}}}int main(){//数据根据书上的图25-1char *str_vertex[5] = { "1", "2", "3", "4", "5" };graph g = graph_create(5, str_vertex);struct edge edges[] =    { {0, 1, 3}, {0, 2, 8}, {0, 4, -4}, {1, 4, 7}, {1, 3, 1}, {2, 1, 4},{3, 2, -5}, {3, 0, 2}, {4, 3, 6}};for (unsigned i = 0; i < sizeof(edges) / sizeof(edges[0]); i++) {graph_insert_edge(g, edges[i]);}graph_display(g);matrix out = matrix_create(g->v_num, g->v_num);matrix parent = matrix_create(g->v_num, g->v_num);slow_all_pairs_shortest_paths(g, out, parent);printf("慢速算法的最短路径矩阵:\n");matrix_display(out);printf("慢速算法的前驱矩阵:\n");matrix_display(parent);int i = 4;int j = 1;printf("path from %s to %s\n", str_vertex[i], str_vertex[j]);print_all_pairs_shortest_path(g, parent, i, j);printf("\n");faster_all_pairs_shortest_paths(g, out, parent);printf("快速算法的最短路径矩阵:\n");matrix_display(out);printf("快速算法的前驱矩阵:\n");matrix_display(parent);printf("path from %s to %s\n", str_vertex[i], str_vertex[j]);print_all_pairs_shortest_path(g, parent, i, j);printf("\n");matrix_destroy(out);matrix_destroy(parent);graph_destroy(g);return 0;}


原创粉丝点击