You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fortran90中随机删除矩阵行触发SIGABRT错误,求解决方案

问题分析与解决方案

原代码的核心问题

  1. 数组越界触发崩溃:
    你的h变量会在每次外层循环(a循环)中累加近1000次,第一次循环后h就会到999,远超NMatrix的729列上限,直接触发内存访问错误(也就是你看到的SIGABRT)。
  2. 逻辑混乱且效率极低:
    每次“删除一行”都要复制整个矩阵,还会重复选中同一行删除(随机数可能重复),最终根本得不到729列的结果。
  3. 索引错误:
    rand_num=int(rand_num*Mc)-1会生成-1到998的数,当rand_num=-1时,b /= -1永远成立,相当于没删任何行。

正确实现方式

直接生成不重复的随机索引,提取需要保留的列(或行,根据你的矩阵维度调整)是更高效且可靠的方案。下面用Fisher-Yates洗牌算法生成无重复的随机索引:

integer, parameter :: Mc=1000, N=729
real :: Matrix(3,Mc), NMatrix(3,N)
integer :: indices(Mc), i, temp, rand_pos
real :: rand_num

! 初始化索引数组为1到Mc的连续整数
do i=1, Mc
    indices(i) = i
end do

! Fisher-Yates洗牌:打乱索引顺序,确保无重复
do i=Mc, 2, -1
    call random_number(rand_num)
    rand_pos = int(rand_num * i) + 1  ! 生成1到i的随机整数
    ! 交换当前位置与随机位置的索引
    temp = indices(i)
    indices(i) = indices(rand_pos)
    indices(rand_pos) = temp
end do

! 提取前N个打乱后的索引,复制到新矩阵
NMatrix(:,1:N) = Matrix(:,indices(1:N))

代码说明

  • 先创建一个包含1到1000的索引数组,通过洗牌算法打乱顺序,确保每个索引只出现一次。
  • 直接提取前729个索引对应的列,一次性完成复制,避免循环中的数组越界问题。
  • 索引从1开始,符合Fortran的默认规则,不会出现负数索引的错误。

内容的提问来源于stack exchange,提问作者Marta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:01:51