算法实验:弗洛伊德算法(任意两点之间的最短路径算法)

弗洛伊德算法实验

弗洛伊德算法解析见弗洛伊德算法

采用邻接矩阵存储图,矩阵的行和列为图的节点,矩阵的内容为图的权重。

//#pragma comment(linker,"/STACK:614400000,614400000") 
//在运行PRINT_ALL_PAIRS_SHORTEST_PATH的时候如果发生stack overflow,请使用上一行的语句扩展栈
#define INF 999999999//无穷大定义
#define NIL -1//Pi矩阵的不可达定义
#define _CRT_SECURE_NO_DEPRECATE
#define frow 11484 //这里是我的图的行数,改成自己图的行数即可
#define N 1000 //这是我节点的数量,改成自己节点的数量即可
#include <iostream>
#include<fstream>
#include<stdio.h>
#include<string>
using namespace std;
int* read(string filename, int n) {
    ifstream fp(filename, ios::in);
    int p1, p2, weight; //数据缓冲区
    int *MAT = new int[n * n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            MAT[i * n + j] = INF;
            if (i == j)MAT[i * n + j] = 0;
        }
    }
    if (!fp) {  // 判断文件是否存在
        cerr << "open error." << endl;
        return nullptr;
    }
    for (int i = 0; i < frow; i++) {
        fp >> p1;
        fp >> p2;
        fp >> weight;
        //cout << p1 << " " << p2 << " " << weight << endl;
        if (p1 < 0 || p1>1000 || p2 < 0 || p2>1000) {
            throw"读取数据错误";
        }
        MAT[p1 * n + p2] = weight;
    }
    return MAT;
}
void write(string filename, int* MAT,int n) {
    ofstream fout(filename, ios::out);
    if (!fout) {  // 判断文件是否存在
        cerr << "open error." << endl;
        //exit(1); // 退出程序
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++){
            if (MAT[i * n + j] == INF)fout << "INF" << ",";
            else fout << MAT[i * n + j] << ",";
        }
        fout << endl;
    }
    fout.close();
}
void print(int *D, int n) {
    //打印矩阵
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (D[i * n + j] == INF)cout << "INF ";
            else
                cout << D[i*n+j]<<"  ";
        }
        cout << endl;
    }
}
int** FLOYD_WARSHALL(int* W, int n) {
    int* D;
    int* PI;
    int** res = new int* [2];
    D = new int [n*n];
    PI = new int[n * n];
    res[0] = D;
    res[1] = PI;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (W[i * n + j] == INF || i == j)PI[i * n + j] = NIL;
            else PI[i * n + j] = i;
            D[i * n + j] = W[i * n + j];
        }
    }//初始化D矩阵

    for (int k = 0; k < n; k++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (D[i * n + j] > D[i * n + k] + D[k * n + j]) {
                    PI[i * n + j] = PI[k * n + j];
                    D[i * n + j] = D[i * n + k] + D[k * n + j];
                }
            }
        }
        printf("正在运算%d/%d\r", k+1,n);
    }
    return res;
}

void PRINT_ALL_PAIRS_SHORTEST_PATH(int *PI,int i,int j) {
    if (i == j) {
        cout << i<<" ";
    }
    else if (PI[i*N+j] == NIL) {
        cout << "No path from " << i << " to " << j << " exits" << endl;
    }
    else
    {
        PRINT_ALL_PAIRS_SHORTEST_PATH(PI, i, PI[i * N + j]);
        cout << j<<" ";
    }
}

int main() {
    /*int W[25] = { 0  ,3  ,8  ,INF,-4,INF,0  ,INF,1  ,7  ,INF,4  ,0  ,INF,INF,2  ,INF,-5 ,0  ,INF,INF,INF,INF,6  ,0  };
    //print(W,5);
    //cout << endl;
    int** res;
    res = FLOYD_WARSHALL(W, 5);
    print(res[0], 5);
    cout << endl;
    print(res[1], 5);
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            cout << "从" << i << "到" << j << "的最短路径为:" << endl;
            PRINT_ALL_PAIRS_SHORTEST_PATH(res[1], i, j, 5);
            cout << endl;
        }
    }
    delete[]res;*/
    /*ifstream fp("weight_graph.txt", ios::in);
    string buff;
    int p1, p2, weight; //数据缓冲区
    int* W = new int[N*N];
    int** res;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            W[i * N + j] = INF;
            if (i == j)W[i * N + j] = 0;
        }
    }
    if (!fp) {  // 判断文件是否存在
        cerr << "open error." << endl;
        return 1;
    }
    for (int i = 0; i < 11484; i++) {
        for (int j = 0; j < 3; j++) {
            if (j == 0)fp >> p1;
            else if (j == 1)fp >> p2;
            else fp >> weight;
        }
        //cout << p1 << " " << p2 << " " << weight << endl;
        W[p1 * N + p2] = weight;
    }
    */
    int* W;
    int** res;
    W = read("weight_graph.txt", N);
    res = FLOYD_WARSHALL(W,N);
    //for (int i = 0; i < N; i++) {
        //for (int j = 0; j < N; j++) {
            //PRINT_ALL_PAIRS_SHORTEST_PATH(res[1], i, j);
            //cout << endl;
        //}
    //}
    cout << "正在存储D矩阵" << endl;
    write("D-result.txt", res[0],N);
    cout << "D矩阵存储完成" << endl;
    cout << "正在存储Pi矩阵" << endl;
    write("Pi-result.txt", res[1], N);
    cout << "Pi矩阵存储完成" << endl;
    if (W != nullptr) {
        delete[]W;
    }
    if (res != nullptr) {
        delete[]res;
    }
    /*ofstream dout("D-result.txt", ios::out);
    ofstream pout("Pi-result.txt", ios::out);
    string D;
    string Pi;
    if (!dout) {  // 判断文件是否存在
        cerr << "open error." << endl;
        //exit(1); // 退出程序
    }
    if (!pout) {  // 判断文件是否存在
        cerr << "open error." << endl;
        //exit(1); // 退出程序
    }
    dout << result[0];
    dout << result[1];
    fp.close();
    dout.close();
    pout.close();*/
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值