我有 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, 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;
}
我的解决方案产生的结果:
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, 2, 4]
If n = 8 and p = 4, then [2, 2, 2, 2]
If n = 8 and p = 5, then [1, 1, 1, 1, 4]
If n = 8 and p = 6, then [1, 1, 1, 1, 1, 3]
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]
答案 0 :(得分:4)
试着想一想。如果你有更少的对象然后线程,那么每个线程将获得一个对象。如果你有更多的物体然后线程(桶),那么考虑如何将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;
}
答案 1 :(得分:1)
你可以试试这个:
std::vector<int> iter(p);
std::generate(iter.begin(), iter.end(), [&]()
{
num += 1;
return SIZE / p + (num <= SIZE % p ? 1 : 0);
});
第一行创建所需数量的元素,第二行使用实际数据填充此向量。它的编写没有显式循环,使代码更具表现力。
答案 2 :(得分:1)
这不是您特定问题/问题的答案,而是针对您预期问题的替代方法。
你的解决方案是复杂的方法...这个代码也是一样的,除了额外的任务被放在前面......
#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;
}
技巧是整数截断,不需要浮点算术,正如你可能看到的那样,其他答案也可以...