【问题标题】:Minimum of a matrix in C++C++中矩阵的最小值
【发布时间】:2021-08-25 15:53:30
【问题描述】:

我有一个std::vector<std::vector<type T>> matrix,我将type T 的元素插入到这个矩阵中,我对这些元素逐行执行一些指令。我还需要在每次迭代时以最低成本删除元素。

我创建了一个std::priority_queue<Costelement, std::vector<Costelement>, Costelement::Comparekeys> Costvec;,其中:

 struct Costelement
{
    int row;
    int column;
    std::vector<double> cost;

    struct CompareCosts
    {
        bool operator()(const Costelement &e1, const Costelement &e2)
        {
            return (e1.cost > e2.cost);
        }
    };
};

其中rowcolumn 是元素在matrix 中具有相应成本的位置。但是,当我从matrix 中删除具有最小键的元素时,相应row 中元素的位置会发生变化。我在matrix 的每次迭代中都使用了std::min_element,但这非常昂贵。我们如何才能有效地建模这种情况?

【问题讨论】:

  • 为什么Costelement 结构的cost 成员是double 值的向量?不应该是一个double吗?
  • e1.cost &gt; e2.cost 中,Costelement::cost 是一个向量,比较如何工作?

标签: c++ vector min priority-queue multimap


【解决方案1】:

默认情况下,std::priority_queue 只是保持排序状态的std::vector。从队列中插入和删除元素仍然很昂贵,并且正如您所注意到的,当您从 matrix 插入或删除元素时,您可能需要更新队列中的所有 Costelements 以反映新职位。但是,您可以通过将优先级队列也设为二维来提高效率,如下所示:

std::priority_queue<std::priority_queue<Costelement, ...>, ...> cost_matrix;

基本上,内部优先级队列对单行列的成本进行排序,外部优先级队列应该对整行的成本进行排序。让我们创建ColumnCostRowCost 结构:

struct ColumnCost {
    int column;
    double cost;

    friend bool operator<(const ColumnCost &a, const ColumnCost &b) {
        return a.cost > b.cost;
    }
};

struct RowCost {
    int row;
    std::priority_queue<ColumnCost> columns;

    friend bool operator<(const RowCost &a, const RowCost &b) {
        return a.columns.top() > b.columns.top();
    }
};

std::priority_queue<RowCost> cost_matrix;

现在您可以轻松地从costmatrix 获取最低成本元素,它返回包含最低成本元素的RowCost,然后您从该元素中获得成本最低的ColumnCost

const auto &lowest_row = cost_matrix.top();
const auto &lowest_column = lowest_row.columns.top();
int row = lowest_row.row;
int column = lowest_column.column;

当您现在从matrix 插入或删除一个元素时,您以同样的方式从cost_matrix 插入或删除。您仍然需要更新rowcolumn 坐标,但现在工作量要少得多。唯一需要注意的是,如果您更新添加或删除元素到 RowCost 的优先级队列,您需要从 cost_matrix 删除并重新插入整行以确保保留外部优先级队列正确排序。

另一个可能的优化是使用std::priority_queue 来保持行排序,但使用std::min_element() 来跟踪每个单独行的最小值。这大大减少了存储cost_matrix 所需的内存量,并且您只需调用std::min_element() 即可在更改该行时重新计算该行的最小成本元素。

【讨论】:

  • 感谢您的回复。如果我使用std::priority_queue&lt;std::priority_queue&lt;..&gt;&gt; 我无法访问矩阵的元素
  • 为什么不呢?二维优先级队列包含矩阵中的行索引和列索引。
  • Silepen with priority_queue 我们无法访问元素,除非我们弹出它们以便访问每个元素link italic bold
  • @user108724 啊,这就是你的意思。但是为什么你需要访问优先队列的随机元素呢?问题不只是为了能够以最低的成本找到元素吗?这应该可以通过在优先级队列上使用.top() 来实现。如果您需要更多,那么您确实不能使用std::priority_queue 本身,那么您可能想要一个排序的std::vector 或者可能是一个std::set(但您也应该能够嵌套它们)。
  • 是的,我需要操纵矩阵每一行的数据,而不幸的是不仅要搜索最小值
【解决方案2】:

您可能想用绳索替换行向量(参见维基百科中的rope data structure)。

这是一个基于二叉树的结构,它允许非常有效地删除元素搜索第 n 个元素(“索引”),因此当你删除时不需要更新所有元素中的位置其中之一。

【讨论】:

    猜你喜欢
    • 2017-04-02
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 2016-08-12
    相关资源
    最近更新 更多