我有一个数组X(9,2),我想生成另一个包含所有可能组合的数组B(512,9)。
我想过做9次循环,但我希望能有更高效的方式。
这就是我所拥有的
do i1=1, 2
do i2=1, 2
do i3=1,2
do i4=1,2
do i5=1,2
do i6=1,2
do i7=1,2
do i8=i,2
do i9=1,2
B(row, col) = X(1,i1)
col = col + 1
B(row, col) = X(2,i2)
col = col + 1
B(row, col) = X(3,i3)
col = col + 1
B(row, col) = X(4,i4)
col = col + 1
B(row, col) = X(5,i5)
col = col + 1
B(row, col) = X(6,i6)
col = col + 1
B(row, col) = X(7,i7)
col = col + 1
B(row, col) = X(8,i8)
col = col + 1
B(row, col) = X(9,i9)
col = 1
row = row + 1
end do
end do
end do
end do
end do
end do
end do
end do
end do
这种方式有问题吗?有没有更好的方法呢?
谢谢!
答案 0 :(得分:1)
你应该通过循环遍历B的元素来反过来制作循环(如下所示)(我有一个print语句而不是赋值...):
program test
implicit none
integer, parameter :: nn = 9, imax = 2
integer :: row, col, ii
integer :: indices(nn)
indices(:) = 1
do row = 1, imax**nn
do col = 1, nn
print "(A,I0,A,I0,A,I0,A,I0,A)", "B(", row, ",", col, ") = X(",&
& col, ",", indices(col), ")"
!B(row, col) = X(col, indices(col))
end do
indices(nn) = indices(nn) + 1
ii = nn
do while (ii > 1 .and. indices(ii) > imax)
indices(ii) = 1
indices(ii-1) = indices(ii-1) + 1
ii = ii - 1
end do
end do
end program test
据我所知,这给出了与原始代码相同的结果,但它更紧凑,适用于任何元组大小和索引范围。
答案 1 :(得分:1)
我认为这也是一招
ncol = 9
B = 0
tot = 2**ncol
do n = 1, ncol
div = 2**n
step = tot/div
do m = 0, div-1
fr = 1 + m*step
to = fr + step
B(fr:to,n) = X(n, 1+mod(m,2))
end do
end do
do n = 1, tot
write(*,*) (B(n,i), i=1,ncol)
end do
答案 2 :(得分:0)
确实有更好的方法。例如,请参阅Martin Broadhurst's combinatorial algorithms - 特别是笛卡尔积产品示例和文件n-tuple.c
。尽管在C中,代码始终使用数组和引用参数,因此可以毫无困难地将其转换为Fortran,而不是将索引更改为从1开始而不是0.他使用的方法是使用索引数组向上计数。 / p>
答案 3 :(得分:0)
character *70 ofil
ofil='allcomb.txt'
write(*,*)'feed n and m (Note: n or m larger than 20 takes time)'
read(*,*) n,m
write(*,*)'feed file name to store results'
read(*,*) ofil
call combin(n,m,ofil)
write(*,*)'Over'
end
!---------------------------------------------------------------
subroutine combin(n,m,ofil)
! Generates all ncm combinatins
parameter (mx=20)! mx is maximum dimension
Integer a(mx),b(mx),c
double precision ncm,ic
character *70 ofil
open(15,file=ofil)
ncm=1
do i=1,m
a(i)=i ! a is least indexed combination
b(i)=n-m+i ! b is maximum indexed combination
ncm=ncm*b(i)/i ! total possible combinations
enddo
write (15,*) (a(i),i=1,m)! Initial (least indexed) combination
incmpl=1
ic=1
! --------------------------------------------------------------
do while (incmpl.ne.0 .and.int(ic).lt.ncm)
incm=0
do i=1,m
incm=incm+(b(i)-a(i))
enddo
incmpl=incm
a(m)=a(m)+1
do i=1,m
ii=m-i+1
if(a(ii).gt.b(ii)) then
a(ii-1)=a(ii-1)+1
do j=ii,m
a(j)=a(j-1)+1
enddo
endif
enddo
ic=ic+1
write(15,*)(a(k),k=1,m)
enddo ! end do while loop
! --------------------------------------------------------------
close(15)
return
end