如何在Fortran中生成729个1-1000的不重复随机数?
生成1-1000范围内无重复的729个随机数(Fortran实现)
要生成无重复的随机数,最高效且易实现的方法是洗牌法(Fisher-Yates算法),尤其适合你这种从1000个数中选取729个的场景(样本量接近总量)。以下是具体实现步骤和代码:
方法一:Fisher-Yates洗牌法(推荐)
思路
- 先创建一个包含1到1000的完整整数数组;
- 通过随机交换数组元素的方式打乱顺序(洗牌);
- 取洗牌后的前729个元素,就是无重复的随机序列。
代码示例
program unique_random_shuffle implicit none integer, parameter :: total_num = 1000, needed_num = 729 integer :: nums(total_num), i, j, temp real :: rnd_val ! 初始化数组为1到1000的连续整数 do i = 1, total_num nums(i) = i end do ! 初始化随机种子(必须调用,否则每次运行结果一致) call random_seed() ! Fisher-Yates洗牌:从后往前随机交换元素 do i = total_num, 2, -1 call random_number(rnd_val) ! 生成1到i之间的随机整数索引 j = int(rnd_val * i) + 1 ! 交换第i个和第j个元素 temp = nums(i) nums(i) = nums(j) nums(j) = temp end do ! 输出前729个无重复随机数(按需使用) print *, "无重复随机数序列:" do i = 1, needed_num write(*, '(I4)', advance='no') nums(i) ! 每9个数字换行,方便阅读 if (mod(i, 9) == 0) print * end do end program unique_random_shuffle
关键说明
random_seed():初始化随机数生成器,确保每次运行程序得到不同的随机序列;- 洗牌过程从数组末尾开始,每次随机选一个前面的元素交换,保证每个元素被随机打乱的概率均等,不会出现重复;
- 由于只需要729个元素,洗牌后直接取前729个即可,无需处理剩余元素。
方法二:生成随机数并检查重复(不推荐用于大样本量)
如果你的需求是选取少量随机数(比如从1000中选10个),可以用这种方法,但当样本量接近总量时(如729/1000),效率会极低,因为后期会频繁生成重复值,需要多次检查。
代码示例
program unique_random_check implicit none integer, parameter :: needed_num = 729, max_val = 1000 integer :: result(needed_num), count = 0, rnd_num, i real :: rnd_val logical :: is_duplicate call random_seed() do while (count < needed_num) ! 生成1到1000的随机整数 call random_number(rnd_val) rnd_num = int(rnd_val * max_val) + 1 ! 检查当前随机数是否已存在于结果数组中 is_duplicate = .false. do i = 1, count if (result(i) == rnd_num) then is_duplicate = .true. exit end if end do ! 非重复则加入结果数组 if (.not. is_duplicate) then count = count + 1 result(count) = rnd_num end if end do ! 输出结果 print *, "无重复随机数序列:" do i = 1, needed_num write(*, '(I4)', advance='no') result(i) if (mod(i, 9) == 0) print * end do end program unique_random_check
注意事项
- 上述两种方法均使用Fortran内置的
random_number(),属于伪随机数生成器,满足大多数常规需求; - 如果需要更高质量的随机数(如加密场景),需调用系统级随机数接口,但这超出基础Fortran编程范畴。
内容的提问来源于stack exchange,提问作者Marta
相关产品推荐
相关产品推荐

