假设我有一个Eigen :: MatrixXf(4,5),没有重复,如下所示:
a b c d e
A: 0.60 0.70 0.80 0.90 0.00
B: 0.51 0.61 0.71 0.81 0.91
C: 0.41 0.31 0.21 0.11 0.01
D: 0.10 0.20 0.30 0.40 0.50
我需要找到row(i)和column(j)之间的匹配,其中值(i,j)是较小的(最小的最小值)1,而(i)或(j)只选择一次。
我的方法结果:
我的工作让我从左上角到右下角开始一个(微不足道的)迭代方法,并搜索最小的匹配,到目前为止,我得到了夫妻(A,e =0.00) (B,a =0.51) (C,e =0.01) (D,a =0.10)
。
a b c d e
A: 0.60 0.70 0.80 0.90 0.00
^
B: 0.51 0.61 0.71 0.81 0.91
^
C: 0.41 0.31 0.21 0.11 0.01
^
D: 0.10 0.20 0.30 0.40 0.50
^
通缉结果
所以,正如你所看到的,我得到'e'和'a'两次匹配,这是不可取的。我完美的匹配将改为(A,e =0.00) ( D,a =0.10) (C,d =0.11) (B,b =0.61)
而留下'c'无法比拟。
a b c d e
A: 0.60 0.70 0.80 0.90 0.00
^
B: 0.51 0.61 0.71 0.81 0.91
^
C: 0.41 0.31 0.21 0.11 0.01
^
D: 0.10 0.20 0.30 0.40 0.50
^
必须有办法做到这一点,但我无法理解!
这是我的代码:
for (i = 0; i < Score.rows(); i++)
{
Correspondance correspondence;
correspondence.source = source[i];
int idx = 0;
for (int j = 0; j < Score.cols(); j++)
{
if (Score(i, j) < Score(i, idx)) idx = j;
}
correspondence.target = target[idx];
correspondences_.push_back(correspondence);
}
with Source [A, B, C, D] and target [a, b, c, d, e]
答案 0 :(得分:1)
我有点把它作为一个挑战,写下我可能会做的事情来解决你的问题。 (使用C ++ 11功能)
#include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
double data[4][5] = {
{ 0.60, 0.70, 0.80, 0.90, 0.00 },
{ 0.51, 0.61, 0.71, 0.81, 0.91 },
{ 0.41, 0.31, 0.21, 0.11, 0.01 },
{ 0.10, 0.20, 0.30, 0.40, 0.50 } };
struct Element
{
int x;
int y;
double value;
};
std::vector<Element> find(double (&matrix)[4][5])
{
std::vector<Element> elements;
std::vector<Element> matches;
// build vector of all elements
for (int i = 0; i < 4; i++)
for (int j = 0; j < 5; j++)
elements.push_back({i, j, matrix[i][j]});
// sort all elements from smallest to largest
std::sort(elements.begin(), elements.end(),
[](const Element& a, const Element& b)
{
return a.value < b.value;
});
while (!elements.empty())
{
// pull out smallest value
Element smallest = elements[0];
matches.push_back(smallest);
// remove all other elements in the same row or column
elements.erase(std::remove_if(elements.begin(), elements.end(),
[smallest](const Element& e)
{
return e.x == smallest.x || e.y == smallest.y;
}), elements.end());
}
return matches;
}
int main()
{
auto matches = find(data);
// print values
for (auto match : matches)
std::cout << "(" << match.x
<< "," << match.y
<< " = " << match.value
<< ")" << std::endl;
return 0;
}
答案 1 :(得分:0)
以下是我的理解: 您正在搜索每行中的唯一最小值。并且您希望按顺序(从最小到最大)找到最小值。
这意味着您无法像现在一样逐行搜索。您需要搜索ENTIRE表4次以查找每行的最小值。在您成功找到某些内容后,请删除您找到的行和列,以便它不会再次搜索。
我提供了两个想法,用于删除已经找到的行/列。它们在下面的代码中标记为选项1和选项2。 ;)
//search for 4 values
for (i = 0; i < Score.rows(); i++)
{
//search ALL rows
for (i = 0; i < Score.rows(); i++)
{
Correspondance correspondence;
correspondence.source = source[i];
int idx = 0;
for (int j = 0; j < Score.cols(); j++)
{
//OPTION 1: Do something here to reject indexes from row/col that are already "found"
if (Score(i, j) < Score(i, idx)) idx = j;
}
}
//only record the answer after all rows are searched
//this is the global minimum value
correspondence.target = target[idx];
correspondences_.push_back(correspondence);
//OPTION 2: Do something here to eliminate the row/cols that are already "found" so that they don't get searched again
}
P.S。我不知道C ++中的通信是什么,所以我将它视为一个数组问题,其中push / pop是一个选项