【发布时间】:2021-11-03 22:45:43
【问题描述】:
我在互联网上寻找这个问题,发现我可以使用<algorithm> 标头中的 random_shuffle 函数。我的以下代码:
void Localization::generate_population(){
int* ptr = new int[size];
for(int i{}; i < size; ++i) ptr[i] = i;
for(int i{}; i < size; ++i) {
std::random_shuffle(ptr, ptr + size);
population[i] = ptr;
}
}
这是我的类函数,它在构造函数中自动调用。我运行了这个程序,最终得到了相同的洗牌数组。网上告诉我,我忘记在程序开头添加std::srand(std::time(0)),所以我就这样做了:
我删除了一些代码以使其更易于阅读。希望它仍然可以理解。
int main(int argc, char **argv){
std::srand(std::time(0));
Localization* gps = new Localization(array_here);
delete gps;
}
但是,当我构建并运行我的程序时,我得到了类似的结果:
[ INFO] [1630975155.983523195]: 0: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.983979451]: 1: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.983990418]: 2: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.983996142]: 3: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.984001312]: 4: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.984006477]: 5: [2, 4, 6, 0, 5, 1, 3]
[ INFO] [1630975155.984013677]: 6: [2, 4, 6, 0, 5, 1, 3]
不完全确定std::srand(std::time(0)) 是如何工作的,但可能是因为for 循环运行得太快,std::srand(std::time(0)) 无法生效。在我的情况下,有没有更好的方法来洗牌?
编辑的代码(工作但不确定是否有效):
#include <iostream>
#include <algorithm>
#include <iterator>
#include <random>
int main(){
int size {5};
int** a2d = new int*[size];
int* ptr = new int[size];
for(int i{}; i < size; ++i) ptr[i] = i;
std::random_device rd;
std::default_random_engine dre{ rd() };
for(int i{}; i < size; ++i){
int* another = new int[size];
std::copy(ptr, ptr + size, another);
std::shuffle(another, another + size, dre);
a2d[i] = another;
std::copy(another, another + size, ptr);
}
delete ptr;
for(int i{}; i < size; ++i){
printf("%d: %d, %d, %d, %d, %d\n", i, a2d[i][0], a2d[i][1], a2d[i][2], a2d[i][3], a2d[i][4]);
}
}
输出:
0: 3, 2, 4, 0, 1
1: 0, 1, 3, 4, 2
2: 4, 3, 1, 2, 0
3: 3, 2, 0, 1, 4
4: 0, 4, 2, 1, 3
【问题讨论】:
-
random_shuffle已被弃用。请改用shuffle。 -
std::time的分辨率为 1 秒,因此如果您在同一秒内多次运行程序,您将获得相同的种子,因此您会获得相同的“随机”结果。srand和rand糟透了(并且通过扩展,std::shuffle已弃用)。使用新的<random>功能 (link)。 -
所有
population的元素都指向同一个指针...使用std::vector将允许拥有真正的副本(无需手动处理内存)。 -
你可能会避免使用
new,Localization gps(array_here);在main中就足够了。std::vector/std::array用于不同的号码列表。