【问题标题】:Fortran: Unknown array size (Counting elements of an array)Fortran:未知数组大小(计算数组元素)
【发布时间】:2013-11-27 06:23:34
【问题描述】:

这是Fortran: Open, form='(un)formatted', read 的后续问题。我必须创建一个数组来保存特定条件下的元素数量。

program location
implicit none
interface
    function distkm(deglat1,deglon1,deglat2,deglon2)
    real :: distkm
    real, intent(in) :: deglat1,deglon1,deglat2,deglon2
    end function distkm
end interface
integer, parameter :: maxnr = 200000
integer :: nr, i, j, ios
character(len=1) :: junkfornr
real :: start, finish
! My variable declaration
character(len=15), dimension(:), allocatable :: key
real, dimension(:), allocatable :: lat, lon
integer, dimension(:), allocatable :: jobs
! Secondary arrays
integer, dimension(:), allocatable :: jobs_within
    integer, dimension(:), allocatable :: sum_jobs
! Determine total number of lines in file
nr=0
open(10, file='location_data2.txt', status='old')
do i=1,maxnr
    read(10,*,iostat=ios) junkfornr
    if (ios/=0) exit
    if (i == maxnr) then
        stop
    endif
    nr = nr + 1
end do
! Create variables: key, lat, lon, jobs
allocate(key(nr))
allocate(lat(nr))
allocate(lon(nr))
allocate(jobs(nr))
allocate(jobs_within(nr))
allocate(sum_jobs(nr))
rewind(10)
do i=1,nr
    read(10,*) key(i), lat(i), lon(i), jobs(i)
end do
do i=1,nr
    do j=1,nr
        if (distkm(lat(i),lon(i),lat(j),lon(j)) <= 0.3) then
            jobs_within(j) = jobs(j)
        else
            jobs_within(j) = 0
        end if  
    end do
    sum_jobs(i) = sum(jobs_within)
end do
close(10)
open(20,file='key_sum_jobs_0.3.txt')
do i=1,nr
    write(20,100) key(i), sum_jobs(i)
end do
100 format(A15,I6)
end program location

do 循环为每个公司节省了 0.3 公里范围内的工人总数。在这里,对于每家公司,0.3 公里范围内的公司数量是不同的。如何创建一个数组(例如,n_neighbor)来记录每个公司的相邻公司数量?

编辑: 我相信以下方法可以解决问题:

do i=1,nr
    n_aux(1:nr) = 0
    do j=1,nr
        if (distkm(lat(i),lon(i),lat(j),lon(j)) <= 1) then
            jobs_within(j) = jobs(j)
            n_aux(j) = n_aux(j) + 1
        else
            jobs_within(j) = 0
        end if
    end do
    write(20,100) key(i), sum(jobs_within), sum(n_aux)
    100 format(A15,I8,1X,I3)
end do

我创建了一个整数数组 (n_aux)。然后,unit=20 的输出文本文件保存了三列:(1)企业密钥,(2)0.3km 内的工人总数,以及(3)0.3km 内的企业数量。

需要思考的事情: 我将n_aux 的所有元素设置为0j 循环之前。然后,我在 if 条件成立的地方抛出 1's。是否应该有其他方式来表达这种操作,例如...动态地将值分配到数组上?

【问题讨论】:

    标签: arrays fortran


    【解决方案1】:

    首先,您的代码在双循环中效率略低。假设您只有 5 家公司,那么您的循环会将它们计为

    (1,1), (1,2), (1,3), (1,4), (1,5)

    (2,1), (2,2), (2,3), (2,4), (2,5)

    (3,1), (3,2), (3,3), (3,4), (3,5)

    (4,1), (4,2), (4,3), (4,4), (4,5)

    (5,1), (5,2), (5,3), (5,4), (5,5)

    您可能不想计算从位置 1 到位置 1 的距离,因为它是 0,因为它是同一家公司。您可能也不想计算(2,1),因为您已经完成了(1,2) 的工作。你可以做的是

    do i=1,nr
       do j=i+1,nr
          ...
       enddo
    enddo
    

    但是,如果您确实想计算(1,2) (2,1),则必须这样做

    do i=1,nr
       do j=1,nr
          if(j == i) cycle
          ...
       enddo
    enddo
    

    这将跳过j=i 并转到j=i+1


    至于您的实际问题,我认为您需要一个一维数组,即allocate(n_neighbor(nr))。如果我们认为相邻在同一 0.3 公里内,那么你可以这样做

    if(distkm(lat(i), lon(i), lat(j), lon(j)) <= 0.3) then
       jobs_within(j) = jobs(j)
       n_neighbors(j) = n_neighbors(j) + 1
    else
       jobs_within(j) = 0
    endif
    

    我们在哪里初始化了n_neighbors=0

    虽然我不太了解您的问题的上下文,但在我看来 jobs_within 的索引应该是 i 而不是 j 并且您可能想对它们求和,即 @987654335 @。如果不是这种情况,请随意忽略评论。

    【讨论】:

    • 亲爱的凯尔。 (1) 我不明白你提到的:“我们已经初始化了n_neighbors=0。” n_neighbors 是一个数组,初始化是如何工作的? (2)我想我通过你的想法解决了我的问题:如果满足条件,则抛出 1。请看我的编辑。谢谢。
    • Bill:Fortran 允许数组数学运算,因此 n_neighbor=0 将数组中的每个元素设置为 0。看起来您的编辑或多或少符合我的建议。
    • Kyle:现在我知道了n_neighbor=0。你是对的。更新仅来自您的想法。谢谢!
    【解决方案2】:

    我不完全确定您真正想要什么,但只是猜测听起来好像您可以编写如下内容:

    n_neighbor(j)=jobs(j) 
    

    在你的 else 部分。 如果你想得到更好的答案,请去掉你代码中所有不必要的东西。然后像你为jobs_within做的那样总结它。

    【讨论】:

    • 我认为如果我展示我的分析背景会更好。下次我会尽量减少我的问题。而且,我认为您的回答不能解决问题。谢谢。
    • 好吧,也许我误解了你的问题。如果你告诉我为什么它不能解决问题,我也许可以改进我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多