使用推力库获得最近的质心?(k - means)
Get nearest centroid using Thrust library? (K-Means)
我已经完成计算距离并存储在推力矢量中,例如,我有2个质心和5个数据点,我计算距离的方式是,对于每个质心,我首先计算5个数据点的距离并存储在数组中,然后在距离的1d数组中使用其他质心,就像这样:
for (int i = 0; i < centroids.size(); ++i)
{
computeDistance(Data, distances, centroids[i], nDataPoints, nDimensions);
}
导致向量1d,例如:
DistancesValues = {10, 15, 20, 12, 10, 5, 17, 22, 8, 7}
DatapointsIndex = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5}
其中前5个值为质心1,其余5个值为质心2。
我想知道是否有一个推力函数,我可以将计数存储在每个质心的最小值的另一个数组中?
比较各指标的值,结果应为:
Counts = {2, 3}
地点:
CountOfCentroid 1 = 2
CountOfCentroid 2 = 3
这是一个可能的方法:
-
创建一个额外的质心索引向量:
DistancesValues = {10, 15, 20, 12, 10, 5, 17, 22, 8, 7} DatapointsIndex = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5} CentroidIndex = {1, 1, 1, 1, 1, 2, 2, 2, 2, 2}
-
现在做一个sort_by_key,使用
DatapointsIndex
作为键,和其他两个向量压缩在一起作为值。这将重新排列所有3个向量,使DatapointsIndex
具有类似的索引组合在一起:DatapointsIndex = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5}
-
现在执行reduce_by_key。如果我们选择
thrust::minimum
算子,我们得到一个约简,它有效地选择了组中的最小值(而不是组中的值相加)。Reduce_by_key表示对每个连续的类似键组进行这种类型的约简。因此,我们将再次使用DatapointsIndex
作为我们的关键向量,并将其他两个向量压缩在一起作为我们的值向量。reduce_by_key的大部分输出我们都不关心,除了从CentroidIndex
向量产生的结果向量。通过计算这个结果向量中的质心指数,我们可以得到期望的输出。
下面是一个完整的例子:
$ cat t428.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/reduce.h>
#include <thrust/copy.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/iterator/discard_iterator.h>
#include <stdio.h>
#define NUM_POINTS 5
#define NUM_CENTROID 2
#define DSIZE (NUM_POINTS*NUM_CENTROID)
int main(){
int DistancesValues[DSIZE] = {10, 15, 20, 12, 10, 5, 17, 22, 8, 7};
int DatapointsIndex[DSIZE] = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5};
int CentroidIndex[DSIZE] = {1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
thrust::device_vector<int> DV(DistancesValues, DistancesValues + DSIZE);
thrust::device_vector<int> DI(DatapointsIndex, DatapointsIndex + DSIZE);
thrust::device_vector<int> CI(CentroidIndex, CentroidIndex + DSIZE);
thrust::device_vector<int> Ra(NUM_POINTS);
thrust::device_vector<int> Rb(NUM_POINTS);
thrust::sort_by_key(DI.begin(), DI.end(), thrust::make_zip_iterator(thrust::make_tuple(DV.begin(), CI.begin())));
thrust::reduce_by_key(DI.begin(), DI.end(), thrust::make_zip_iterator(thrust::make_tuple(DV.begin(), CI.begin())), thrust::make_discard_iterator(), thrust::make_zip_iterator(thrust::make_tuple(Ra.begin(), Rb.begin())), thrust::equal_to<int>(), thrust::minimum<thrust::tuple<int, int> >());
printf("CountOfCentroid 1 = %dn", thrust::count(Rb.begin(), Rb.end(), 1));
printf("CountOfCentroid 2 = %dn", thrust::count(Rb.begin(), Rb.end(), 2));
return 0;
}
$ nvcc -arch=sm_20 -o t428 t428.cu
$ ./t428
CountOfCentroid 1 = 2
CountOfCentroid 2 = 3
$
正如Eric在他的回答中指出的那样(你的问题几乎是那个问题的副本),sort_by_key
可能是不必要的。该数据的重新排序遵循规则模式,因此我们不需要利用排序的复杂性,因此可以巧妙地使用迭代器对数据进行重新排序。在这种情况下,可能(大约)通过调用reduce_by_key
来完成整个操作。
- 查找最近配对时的OpenMP竞赛条件
- 如何获取pcl迭代最近点(ICP)的迭代点数?
- 什么是"undetectable means",它们如何更改 C/C++ 程序的对象?
- 如何找到给定点的最近平方
- 将前向声明的结构替换为最近定义的结构
- 应该如何编写用于计算最近点距离的C++函数?
- 最近的邻居用nanoflann搜索
- GCC:--静态链接到pthread的整个存档配方在最近的GCC版本中停止工作
- 向下四舍五入到五个c++的最近倍数
- 在 3D 点云、GPU 中查找最近的邻居
- 我最近更改了编译器路径以运行 c++ 代码,但现在我无法运行任何 python 代码。我该如何解决这个问题?
- 在RHEL6上使用最近的gcc进行编译:如何分发软件?
- 最近最少使用的 (LRU) 缓存
- 我最近正在阅读opencv源代码。有没有更好的方法来在opencv库中查找类定义?
- 对来自csv文件的数据执行OpenCV k-means
- c++ Valgrind:地址0x0不是堆叠的、恶意的或(最近)释放的
- 如何在无限轴上找到 N 个点,以便从 M 点到其最近的 N 的距离总和最小
- 地址0x20ec8348e5894855不是堆叠的、恶意的或(最近)释放的
- 在 OpenCV 和 C++ 中查找距轮廓中心最近的黑色像素
- 使用推力库获得最近的质心?(k - means)