fortran90 中的 n 嵌套 for 循环

问题描述 投票:0回答:3

我已经阅读了一些有关此的主题,但我不太认为它回答了我的问题。如果确实如此,请引导我到正确的主题,我一定会再看一次。

这是我的问题:

我想编写一个 for 循环,它将循环遍历数组长度为“n”的每个可能的组合。

也就是说,如果 n = 2 那么我的 for 循环将是

do i1 = 1,2
    do i2 = 1,2
         ! do stuff here
    enddo
enddo

如果 n = 3 那么我的数组看起来像

do i1 = 1,3
    do i2 = 1,3
         do i3 = 1,3
             ! do stuff here
         enddo
    enddo
enddo

等等。我将如何编写一个例程,只需输入变量“n”即可自动执行此操作?

nested-loops fortran90
3个回答
1
投票

如果你写出索引,你得到的是一个以 n 为基数的 n 位数字(几乎 - 偏移量为 1,因为你在 fortran 中使用基于 1 的索引)。 你要求的是该数字可以取的每个可能值。

换句话说,如果我们为了简单起见暂时使用基于 0 的索引,您将得到:

  • n=2,values=00,01,10,11(从0到3的二进制计数)
  • n=3,值=000,001,002,010,011,012,020,021,022,100,101,102,110,111,112,120,121,122,200,201,202,210,211,212,220,221,222(三元( ?)从0数到26)

所以你要问的是在一般情况下如何做到这一点。

您可以使用数组来保存从 [0,0....0] 开始的 n 位数字。 然后,在“while”循环中(它将替换您的n个嵌套for循环),尝试增加最右边的条目(数字)。 如果等于 n,则返回到零并向左递增。 一旦您设法在不达到 n 的情况下增加一个值,那么您就“完成”了,可以使用这些数字作为索引。

非常简单 - 每次只需加 1。

然后,对于 fortran 基于 1 的索引,每个数字加 1。 换句话说,将上面的内容更改为从 1s 开始,并在 n+1 处向左移动。

例如,对于 n=4:

  • 以 [1,1,1,1] 开头
    • 进行内循环动作
  • 将最右边的值增加到 [1,1,1,2]
    • 进行内循环动作
  • 将最右边的值增加到 [1,1,1,3]
    • 进行内循环动作
  • 将最右边的值增加到 [1,1,1,4]
    • 进行内循环动作
  • 最右边增加到 [1,1,1,5]
  • 您增加的数字现在位于 n+1,这意味着回到 1 并将数字向左增加 [1,1,2,1]
    • 进行内循环动作
  • 将最右边的值增加到 [1,1,2,2]
    • 进行内循环动作
  • 等等..

1
投票

我猜你只能通过将循环折叠成一个 n**n 循环来做到这一点,并从折叠的全局索引中计算单独的 n 索引(或者简单地用不同的步幅对它们进行计数)。

编辑:尝试将其放入示例代码中:

do i=1,n**n
  do j=1,n
    ind(j) = mod((i-1)/max((j-1)*n,1),n) + 1
  end do
  ! Some code using ind(1:n)
end do

0
投票

考虑以下形式的一般 n 层嵌套 do 循环:

DO IX(1) = 1, NX(1)

DO IX(2) = 1, NX(2)

    .....

       DO IX(N) = 1, NX(N)

        perform operations on F(IX(1),IX(2), ..., IX(N))

       ENDDO

    .....

ENDDO

ENDDO

等效的单循环构造如下:

NT = NX(1)

DO I = 2, N

NT = NT * NX(I)

ENDDO

DO K=1,NT

M = K

DO  I = N,1,-1

    NN = 1

    DO  J = 1, I - 1

        NN = NN * NX(J)

    ENDDO

    IF (I .GT. 1) THEN

         IX(I) = (M-1) / NN + 1

        M = M - (IX(I) - 1) * NN

    ELSE

       IX(I) = M

    ENDIF

ENDDO

perform operations on F(IX(1),IX(2), ..., IX(N))

ENDDO

来源:https://www.coatsengineering.com

© www.soinside.com 2019 - 2024. All rights reserved.