C++ 反向Cutchill-McKee算法:Matlab和boost实现中无与伦比的结果

C++ 反向Cutchill-McKee算法:Matlab和boost实现中无与伦比的结果,c++,algorithm,matlab,matrix,boost,C++,Algorithm,Matlab,Matrix,Boost,我为特征值问题写了一个代码。在工作中,我需要一些对称矩阵的Cuthill-McKee算法。我在Matlab上有一个测试代码,我希望在С++上编写这个实现 但是,我遇到了以下问题:一些矩阵的Matlab和boost结果不匹配。例如,在boost站点上进行测试 对于Matlab(基于零的索引): 对于boost C++: input_bandwidth = 8 output_bandwidth = 4 [0 8 5 7 3 6 4 2 1 9] input_bandwidt

我为特征值问题写了一个代码。在工作中,我需要一些对称矩阵的Cuthill-McKee算法。我在Matlab上有一个测试代码,我希望在С++上编写这个实现

但是,我遇到了以下问题:一些矩阵的Matlab和boost结果不匹配。例如,在boost站点上进行测试

对于Matlab(基于零的索引):

对于boost C++:

input_bandwidth = 8
output_bandwidth = 4

[0  8  5  7  3  6  4  2  1  9] 
input_bandwidth = 11
output_bandwidth = 3

[13  10  3  6  11  9  2  4  12  8  1  5  0  7]
但是,另一个类似这样的测试(C++代码):

给出了无与伦比的结果

对于Matlab(基于零的索引):

对于boost C++:

input_bandwidth = 8
output_bandwidth = 4

[0  8  5  7  3  6  4  2  1  9] 
input_bandwidth = 11
output_bandwidth = 3

[13  10  3  6  11  9  2  4  12  8  1  5  0  7]
请帮帮我,因为我的解算器很大程度上依赖于这个算法

我读过很多关于这个问题的书,但没有找到合适的


当然我可以自己实现,但我不想做我已经拥有的事情。

我认为答案隐藏在MATLAB的帮助下(文档中没有记录)
根据symrcm中的描述,它对对称矩阵很有效,如果S是非对称的,MATLAB计算symrcm(S+S')。您的示例都是这样的

,使用Matlab和相同矩阵的boost程序可以得到什么样的结果?Matlab代码正确吗?你能给我们看更多的C++代码吗?没有算法代码很难发现bug。这两种算法之间的行主索引与列主索引是否存在问题?我用您的评论更改了我的问题。列主索引和行主索引在这里并不重要,因为当我编译图的边时,(I,j)和(j,I)之间没有区别。
#include <boost/config.hpp>
#include <vector>
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/cuthill_mckee_ordering.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/bandwidth.hpp>


void r_cuthill_mckee(std::vector<int> &cm_ord)
{
    using namespace boost;
    using namespace std;
    typedef adjacency_list<vecS, vecS, undirectedS,
        property<vertex_color_t, default_color_type,
        property<vertex_degree_t, int> > > Graph;
    typedef graph_traits<Graph>::vertex_descriptor Vertex;
    typedef graph_traits<Graph>::vertices_size_type size_type;

    typedef std::pair<std::size_t, std::size_t> Pair;
    vector<Pair> edges = {
        Pair(0, 0),
        Pair(0, 7),
        Pair(1, 1),
        Pair(1, 5),
        Pair(1, 8),
        Pair(1, 12),
        Pair(2, 2),
        Pair(2, 4),
        Pair(2, 9),
        Pair(2, 11),
        Pair(3, 3),
        Pair(3, 6),
        Pair(3, 10),
        Pair(3, 13),
        Pair(4, 4),
        Pair(4, 9),
        Pair(4, 11),
        Pair(5, 5),
        Pair(5, 8),
        Pair(5, 12),
        Pair(6, 6),
        Pair(6, 10),
        Pair(6, 13),
        Pair(7, 7),
        Pair(8, 8),
        Pair(8, 12),
        Pair(9, 9),
        Pair(9, 11),
        Pair(10, 10),
        Pair(10, 13),
        Pair(11, 11),
        Pair(12, 12),
        Pair(13, 13)
    };  


    Graph G(14);
    for (int i = 0; i < edges.size(); ++i)
        add_edge(edges[i].first, edges[i].second, G);

    graph_traits<Graph>::vertex_iterator ui, ui_end;

    property_map<Graph, vertex_degree_t>::type deg = get(vertex_degree, G);
    for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
        deg[*ui] = degree(*ui, G);

    property_map<Graph, vertex_index_t>::type
        index_map = get(vertex_index, G);

    std::cout << "original bandwidth: " << bandwidth(G) << std::endl;

    std::vector<Vertex> inv_perm(num_vertices(G));
    std::vector<size_type> perm(num_vertices(G));

    //reverse cuthill_mckee_ordering
    cuthill_mckee_ordering(G, inv_perm.rbegin(), get(vertex_color, G),
        make_degree_map(G));

    cout << "Reverse Cuthill-McKee ordering:" << endl;
    cout << "  ";

    cm_ord.reserve(14);
    for (std::vector<Vertex>::const_iterator i = inv_perm.begin(); i != inv_perm.end(); ++i)
        cm_ord.push_back(index_map[*i]);
    cout << endl;

    for (size_type c = 0; c != inv_perm.size(); ++c)
        perm[index_map[inv_perm[c]]] = c;
    std::cout << "  bandwidth: "
        << bandwidth(G, make_iterator_property_map(&perm[0], index_map, perm[0]))
        << std::endl;
    }


int main()
{
    std::vector<int> cm_ord;
    r_cuthill_mckee(cm_ord);

    for (auto ic : cm_ord)
        std::cout << ic << " " << std::flush;

    system("pause");
    return 0;
}
A = zeros(14,14);

A(1, 1) = 1;
A(1, 8) = 1;
A(2, 2) = 1;
A(2, 6) = 1;
A(2, 9) = 1;
A(2, 13) = 1;
A(3, 3) = 1;
A(3, 5) = 1;
A(3, 10) = 1;
A(3, 12) = 1;
A(4, 4) = 1;
A(4, 7) = 1;
A(4, 11) = 1;
A(4, 14) = 1;
A(5, 5) = 1;
A(5, 10) = 1;
A(5, 12) = 1;
A(6, 6) = 1;
A(6, 9) = 1;
A(6, 13) = 1;
A(7, 7) = 1;
A(7, 11) = 1;
A(7, 14) = 1;
A(8, 8) = 1;
A(9, 9) = 1;
A(9, 13) = 1;
A(10, 10) = 1;
A(10, 12) = 1;
A(11, 11) = 1;
A(11, 14) = 1;
A(12, 12) = 1;
A(13, 13) = 1;
A(14, 14) = 1;

[i,j] = find(A);
bandwidth1 = max(i-j) + 1

p = symrcm(A)
%p - 1 = [7     0    12     8     1     5    11     9     2     4    13    10     3     6]

B = A(p,p);

[i,j] = find(B);
bandwidth2 = max(i-j) + 1
input_bandwidth = 1
output_bandwidth = 4

[7  0  12  8  1  5  11  9  2  4  13  10  3  6]
input_bandwidth = 11
output_bandwidth = 3

[13  10  3  6  11  9  2  4  12  8  1  5  0  7]