C++ 在工作线程之间几乎相等地划分数据集
我有n个元素和p个线程。我试图在线程之间尽可能平均地划分元素 例如:C++ 在工作线程之间几乎相等地划分数据集,c++,algorithm,logic,C++,Algorithm,Logic,我有n个元素和p个线程。我试图在线程之间尽可能平均地划分元素 例如: If n = 8 and p = 1, then [8] If n = 8 and p = 2, then [4, 4] If n = 8 and p = 3, then [2, 3, 3] If n = 8 and p = 4, then [2, 2, 2, 2] If n = 8 and p = 5, then [1, 1, 2, 2, 2] If n = 8 and p = 6, then [1, 1, 1, 1, 2,
If n = 8 and p = 1, then [8]
If n = 8 and p = 2, then [4, 4]
If n = 8 and p = 3, then [2, 3, 3]
If n = 8 and p = 4, then [2, 2, 2, 2]
If n = 8 and p = 5, then [1, 1, 2, 2, 2]
If n = 8 and p = 6, then [1, 1, 1, 1, 2, 2]
If n = 8 and p = 7, then [1, 1, 1, 1, 1, 1, 2]
If n = 8 and p = 8, then [1, 1, 1, 1, 1, 1, 1, 1]
我想出了一个几乎有效但不完全有效的解决方案
#include <vector>
#include <stdio.h>
#include <cmath>
int main(int argc, char **argv)
{
int p = 5;
const int SIZE = 8;
int i = 0;
int num = 0;
std::vector<int> iter;
if (p == 1)
iter.push_back(SIZE);
else
{
if (SIZE % p == 0)
{
num = SIZE / p;
for (i = 0; i < p; ++i)
iter.push_back(num);
}
else
{
num = (int)floor((float)SIZE / (float)p);
for (i = 0; i < p - 1; ++i)
iter.push_back(num);
iter.push_back((SIZE - (num * (p - 1))));
}
}
for (unsigned int j = 0; j < iter.size(); ++j)
printf("[%d] = %d\n", j, (int)iter[j]);
return 0;
}
您可以尝试以下方法:
std::vector<int> iter(p);
std::generate(iter.begin(), iter.end(), [&]()
{
num += 1;
return SIZE / p + (num <= SIZE % p ? 1 : 0);
});
std::向量iter(p);
std::generate(iter.begin()、iter.end()、[&]()
{
num+=1;
返回大小/p+(num试着想想这个问题。如果对象较少,那么线程,那么每个线程将得到一个对象。如果对象较多,那么线程(桶),那么考虑如何将100个网球分成8个桶。
你可以一次拿一个球,然后把它放到下一个桶里,一旦你通过了所有的桶,你就从第一个桶开始,这将确保每个桶大小之间的差值最多为1
#include <vector>
#include <stdio.h>
int main(int argc, char **argv)
{
int p = 5;
const int SIZE = 8;
int p_size = SIZE > p ? p : SIZE;
std::vector<int> iter(p_size);
for (int i = 0; i < SIZE; i++)
{
iter[i%p_size] += 1;
}
for (unsigned int j = 0; j < iter.size(); ++j)
printf("[%d] = %d\n", j, (int)iter[j]);
return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
int p=5;
常数int SIZE=8;
int p_size=size>p?p:size;
标准:矢量iter(p_尺寸);
对于(int i=0;i
这不是对您的特定问题的回答,而是解决您的预期问题的另一种方法
您的解决方案是复杂化的方式…此代码也执行相同的操作,只是将额外的任务放在前端
#include <iostream>
#include <vector>
int main(int argc, char **argv)
{
int p = 5;
const int n = 8;
// calculate number of tasks every thread have to do...
int every = n / p;
// calculate rest
int rest = n % p;
// initialize the vector with the number of tasks every thread have to do
std::vector<int> lst(p, every);
// split rest on the threads
for(int i=0; i<rest; ++i)
lst[i]++;
// print out
for(auto it : lst)
std::cout << it << ",";
return 0;
}
#包括
#包括
int main(int argc,字符**argv)
{
int p=5;
常数int n=8;
//计算每个线程必须执行的任务数。。。
int every=n/p;
//计算剩余
int rest=n%p;
//使用每个线程必须执行的任务数初始化向量
std::向量lst(p,每一个);
//在螺纹上分开支架
对于(int i=0;i您的问题是什么?您是否尝试用纸笔解决它?抱歉,我已修复它。它现在应该可以编译了。我明白您的意思。Valery就是这样做的,尽管做得更好。我会使用常规循环来代替(因为我不知道std::generate())我想给代码写一些解释,并用一种方法来添加代码,你可以看到代码中的解释。我接受瓦里的帖子作为答案,因为他是第一个回答的,但是你的解释/实现同样是有帮助的,我感谢你。这个实现也是有用的。我用C++。在示例代码中,但在我的实际项目中,我使用的是标准C。你永远不应该以“NOT an an an an an answer”开头回答。(我不明白这怎么不是答案,所以我将留下它…@Zulan更改了它:)我的意思是,这不是答案,因为…请参见编辑…再次感谢你的帮助。希望没有人会删除此评论。
#include <iostream>
#include <vector>
int main(int argc, char **argv)
{
int p = 5;
const int n = 8;
// calculate number of tasks every thread have to do...
int every = n / p;
// calculate rest
int rest = n % p;
// initialize the vector with the number of tasks every thread have to do
std::vector<int> lst(p, every);
// split rest on the threads
for(int i=0; i<rest; ++i)
lst[i]++;
// print out
for(auto it : lst)
std::cout << it << ",";
return 0;
}