欢迎光临散文网 会员登陆 & 注册

C++基于拓扑排序的迭代法最短路径求解

2023-06-25 18:12 作者:bili_69278239799  | 我要投稿

#include <cstddef>

#include <iostream>

#include <sstream>

#include <string>

#include <array>

#include <memory>

#include <map>

#include <stack>

#include <vector>


using namespace std;


//控制台输入参数 顶点序列,和边权值

//a b c d e q 空格结束

//ab5 ae4 ac3 bc2 cd8 ce6 de10 q 空格结束

constexpr int MAX_COST = 9999;


union VexItem

{

    char value_;

    int index_;

};


class Vex

{

public:

    Vex(Vex&&) = default;

    Vex& operator =(Vex&&) = default;

    Vex() = default;

    explicit Vex(char ch, int cost = 0)

    : cost_(cost)

    , rudu_(0)

    , next_(nullptr)

    {

        vex_item_.value_ = ch;

        //cout << "init vex_item_.value_: " << vex_item_.value_ << endl;

    }


    explicit Vex(int index, int cost = 0)

    : cost_(cost)

    , rudu_(0)

    , next_(nullptr)

    {

        vex_item_.index_ = index;

        //cout << "init vex_item_.index_: " << vex_item_.index_ << endl;

    }


    VexItem vex_item_;

    int cost_;

    int rudu_;

    shared_ptr<Vex> next_;

};


int main() {

    constexpr int input_len{2 + 10};

    constexpr auto vex_len{100};

    int vex_count{0};

    array<Vex, vex_len> vex;

    map<char, int> vex_index;

    auto string2num = [](const char* str)

    {

        int cost{0};

        stringstream ss;

        ss << str;

        ss >> cost;

        return cost;

    };


    cout << "input vex point" << endl;

    for(int i = 0 ;; ++i)

    {

        array<char, input_len> input;

        cin.getline(input.data(), input_len, ' ');

        //cout << "you input vex point:" << input.data() << endl;


        if(input[0] == 'q')

            break;

       

        vex[i] = Vex(input[0]);

        vex_index[input[0]] = i;

        vex_count++;

        //cout << input[0] << " map to " << i << endl;

    }


    cin.ignore(std::numeric_limits< streamsize >::max(), '\n');

    cout << "input vex pair and cost" << endl;

    do

    {

        array<char, input_len> input;

        cin.getline(input.data(), input_len, ' ');

        //cout << "you input vex pair and cost:" << input.data() << endl;


        if(input[0] == 'q')

            break;

       

        //cout << input[0] << "}}" << input[1] << endl;

        auto from_index = vex_index[input[0]];

        auto to_idnex = vex_index[input[1]];

        auto tmp = make_shared<Vex>(to_idnex, string2num(input.data() + 2));

       

        tmp->next_ = vex[from_index].next_;

        vex[from_index].next_ = tmp;

        vex[to_idnex].rudu_++;

       

    }while(true);

    //a b c d e q

    //ab5 ae4 ac3 bc2 cd8 ce6 de10 q

    stack<int> stack_vex;

    vector<int> order_vex;

    for(int i = 0; i < vex_count; i++)

    {

        auto& item = vex[i];

        if(item.vex_item_.value_ == '\0' && item.vex_item_.index_ == 0)

            break;

        auto ptr = item.next_;

        cout << "vex :" << item.vex_item_.value_ << ", rudu:" << item.rudu_ << endl;

        if(ptr == nullptr)

        {

            cout << "end vex:" << item.vex_item_.value_ << endl;

        }


        for(; ptr != nullptr; ptr = ptr->next_)

        {

            cout << item.vex_item_.value_ << "-" << ptr->cost_ << "->"

                 << vex[ptr->vex_item_.index_].vex_item_.value_ << "  ";

        }

        cout << endl;

   

        if(item.rudu_ == 0)

        {

            stack_vex.push(i);

        }    

    }


    while(!stack_vex.empty())    

    {

        auto i = stack_vex.top();

        stack_vex.pop();

        order_vex.push_back(i);

        auto ptr = vex[i].next_;

        for(;ptr != nullptr; ptr = ptr->next_)

        {

            auto to_index = ptr->vex_item_.index_;

            vex[to_index].rudu_--;

            if(vex[to_index].rudu_ == 0)

            {

                stack_vex.push(to_index);

            }

        }

    }


    cout << "order_vex: " ;

    for(auto& itme : order_vex)

    {

        cout << vex[itme].vex_item_.value_ << " " ;

    }

    cout << endl;


    //求order_vex 第一个顶点到最后一个顶点的最短路径

    int order_vex_len = order_vex.size();

    const int start_vex = 1, end_vex =  order_vex.back(); //指定路径前迄点

    vector<int> cost(order_vex_len, MAX_COST);

    vector<int> succ(order_vex_len, -1);

    cost[end_vex] = 0;


    int cur_vex_index = 0;

    for(int i = 0; i < order_vex_len; ++i)

    {

        if(order_vex[i] == end_vex)

            cur_vex_index = i;

    }


    while(order_vex[cur_vex_index] != start_vex)

    {

        int front_vex = order_vex[--cur_vex_index];

        int front_vex_cost = MAX_COST;

        int front_vex_succ = -1;


        for(int i = 0; i < vex_count; ++i)

        {

            auto next = vex[front_vex].next_;

            while(next != nullptr)

            {

                if(next->vex_item_.index_ == i &&  cost[i] + next->cost_ < front_vex_cost)

                {

                    front_vex_cost = cost[i] + next->cost_;

                    front_vex_succ = i;

                    //cout << cur_vex_index << " " << front_vex_cost << " " << front_vex_succ << endl;

                }


                next = next->next_;

            }

        }


        cost[front_vex] = front_vex_cost;

        succ[front_vex] = front_vex_succ;

    }


    int path_index = start_vex;


    cout << vex[start_vex].vex_item_.value_ << " to " << vex[end_vex].vex_item_.value_

         << " succ path is :"  << endl << vex[start_vex].vex_item_.value_ << " ";

    do

    {

        cout << vex[path_index = succ[path_index]].vex_item_.value_ << " ";

    }while(path_index != end_vex);


    return 1;

}



C++基于拓扑排序的迭代法最短路径求解的评论 (共 条)

分享到微博请遵守国家法律