我想在8x8电路板上选择随机坐标。 x和y坐标只能是-8。 -6,-4,-2,0,2,4,6和8.我想为20个对象选择随机坐标,但我不希望任何2个对象具有相同的坐标。用C ++编程!
答案 0 :(得分:4)
每个坐标只有9个可能的值,所以总共有81个点。最简单的解决方案是枚举所有可能的点(例如:在数组或向量中),然后随机选择20。
你可以通过从0到80选择一个索引来随机选择20,用索引80交换数组的那个元素,然后随机选择一个从0到79的索引,用索引79交换索引,依此类推20次。然后你的数组的最后20个元素将是20个不同的随机点。
答案 1 :(得分:1)
获取集合中的所有坐标对,并将它们放入列表中,并生成列表的随机排列(对此存在标准算法,例如Laurence建议的算法)。取排列的前20个元素。
答案 2 :(得分:1)
如果您可以枚举电路板上的所有坐标,则可以使用任何采样算法。你是一个9x9网格;只需从范围[0,80]中选取20个值,然后将它们转换为网格坐标:
// Say the number picked is "n"
int x = ((n % 9) - 4) * 2;
int y = ((n / 9) - 4) * 2;
您可以使用任何抽样算法生成n
s;例如,查看this question的答案。
这种方法明显优于生成点的优点是可以在大网格上节省相当多的内存(和处理时间)。如果它们真的很大并且你选择了一个小的简单,那么显而易见的算法也可以正常工作:只需选择一个随机点,如果已经选择它,请再试一次。这个算法唯一的问题是,如果你选择了很大一部分,它最终会进行很多重试。
答案 3 :(得分:0)
将劳伦斯的算法放入程序中。工作正常。
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
//To store x and y coordinate of a point
struct Point
{
int x, y;
};
int main()
{
vector<Point> v;
Point p;
//Populate vector with 81 combinations.
for(int i = -8; i < 10; i += 2)
{
for(int j = -8; j < 10; j += 2)
{
p.x = i;
p.y = j;
v.push_back(p);
}
}
srand(time(NULL));
int lastIndex = 80;
for(int i = 0; i < 20; i++)
{
int randNum = rand() % (81-i);
//Swap to isolate chosen points.
std::swap(v[randNum], v[lastIndex-i]);
}
//Print chosen random coordinates
cout<<"Random points chosen are "<<endl;
for(int i = 61; i < 81; i++)
{
Point p = v[i];
cout<<p.x<<"\t"<<p.y<<endl;
}
}
答案 4 :(得分:0)
例如,你可以使用std :: random_shuffle,因为你有一个有限数量的整数坐标。所以只需改变那组矢量/位置。您也可以将自己的RNG作为函数对象传递给random_shuffle。
示例:
#include <algorithm> //for copy and random_shuffle
#include <utility> //for pair and make_pair
#include <vector>
...
std::vector<std::pair<int, int> > coords;
std::vector<std::pair<int, int> > coords20(20);
for(int y=-8; y<=8; y+=2)
for(int x=-8; x<=8; x+=2)
coords.push_back(std::make_pair(x,y));
std::random_shuffle(coords.begin(), coords.end());
std::copy(coords.begin(), coords.begin() + 20, coords20.begin());