如何有效地找到给定矢量集中每列的最小值?
例如,请考虑以下程序:
#include <iostream>
#include <vector>
#include <iterator>
#include <cstdlib>
using namespace std;
typedef vector<double> v_t;
int main(){
v_t v1,v2,v3;
for (int i = 1; i<10; i++){
v1.push_back(rand()%10);
v2.push_back(rand()%10);
v3.push_back(rand()%10);
}
copy(v1.begin(), v1.end(), ostream_iterator<double>(cout, " "));
cout << endl;
copy(v2.begin(), v2.end(), ostream_iterator<double>(cout, " "));
cout << endl;
copy(v3.begin(), v3.end(), ostream_iterator<double>(cout, " "));
cout << endl;
}
让输出为
3 5 6 1 0 6 2 8 2
6 3 2 2 9 0 6 7 0
7 5 9 7 3 6 1 9 2
在这个程序中,我想找到每个列的最小值(3个给定向量)并将其放入向量中。在这个程序中,我想定义一个具有值的矢量v_t vfinal
:
3 3 2 1 0 0 1 7 0
有一种有效的方法吗?我提到有效率,因为我的程序可能必须在非常大量的向量中找到最小的值。谢谢。
更新
我正在尝试使用我在以前的一个程序中使用的类似的东西
int count = std::inner_product(A, A+5, B, 0, std::plus<int>(), std::less<int>());
这计算了两个数组A和B之间的最小元素数。如果我可以循环并使用类似的函数来查找最小值,那么它是否足够有效?我并没有声称可以做到或不做。这只是一个可以改进的想法,但我不知道如何。
答案 0 :(得分:3)
我认为问题的下限是O(n*m)
,其中n
是向量的数量,m
是每个向量的元素。
我认为,平凡的算法(比较不同矢量的相同索引处的元素)尽可能高效。
实现它的最简单方法是将所有向量放在一些数据结构中(一个简单的类C数组,或者可能是向量的向量)。
答案 1 :(得分:3)
您可以使用std::transform
。循环仍在那里,它们只是隐藏在算法中。要处理的每个附加向量都是对std::transform
的调用。
这是两个线性过程中的示例问题。
typedef std::vector<double> v_t;
int main()
{
v_t v1,v2,v3,vfinal(9); // note: vfinal sized to accept results
for (int i = 1; i < 10; ++i) {
v1.push_back(rand() % 10);
v2.push_back(rand() % 10);
v3.push_back(rand() % 10);
}
std::transform(v1.begin(), v1.end(), v2.begin(), vfinal.begin(), std::min<double>);
std::transform(v3.begin(), v3.end(), vfinal.begin(), vfinal.begin(), std::min<double>);
}
注意:这适用于MSVC ++ 2010.我必须为gcc 4.3提供min
仿函数。
答案 2 :(得分:2)
要在向量中找到最小的数字,您只需要依次检查每个元素;没有更快的方法,至少从算法的角度来看。
就实际性能而言,的缓存问题可能会影响您。正如在评论中提到的,如果你可以按行而不是逐行存储向量,它可能会更有效地缓存。或者,您可能希望并行执行所有min搜索,以便最大限度地减少缓存未命中。即而不是:
foreach (col)
{
foreach (row)
{
x_min[col] = std::min(x_min[col], x[col][row]);
}
}
你应该这样做:
foreach (row)
{
foreach (col)
{
x_min[col] = std::min(x_min[col], x[col][row]);
}
}
请注意,STL已经提供了一个很好的功能: min_element()
。
答案 3 :(得分:2)
执行此操作的最佳方法是使用向量向量,只需简单循环。
void find_mins(const std::vector<std::vector<int> >& inputs, std::vector<int>& outputs)
{
// Assuming that each vector is the same size, resize the output vector to
// change the size of the output vector to hold enough.
output.resize(inputs[0].size());
for (std::size_t i = 0; i < inputs.size(); ++i)
{
int min = inputs[i][0];
for (std::size_t j = 1; j < inputs[i].size(); ++j)
if (inputs[i][j] < min) min = inputs[i][j];
outputs[i] = min;
}
}