Fortran循环,再次求教大神,有数据和code,多谢!

f
ftmit
楼主 (未名空间)

首先多谢各路大神在我前边帖子中的建议和帮助!

还是那个如何设计fortran循环体能节省计算时间的问题。我试了一下,计算速度还是
太慢,这次把具体的数据形式和code贴出来,恳请各路大神出手相助,非常着急出结果,灌水paper,先谢谢了。

1,表一是控制参数,共29个参数,tt1,tt2,tt3,...,tt29,每个参数有1100个数据

2,表二是备选数据,除了第一列的流速(FV)之外,其余的29列参数uu1,uu2,uu3,...,uu29.和表一中的29个控制参数tt1,tt2,tt3,...,tt29,在物理意义上是一样的,可以理解为一一对应关系,每列有34000000个数据

3,需要找出表二中满足如下条件的全部流速值,FV(i)

条件1:该流速值所对应的参数值,大于在表一中所相对应参数的最小值,小于最大值。

条件2:该流速值的选取,不但要单独判断这29个参数,而且还要判断这29个参数的全部组合,每种组合都以组合的参数之和作为判据。(即,在29个参数中,取1个,2个,3个,...29个参数的情况,表一参数tt共有536870911种,表二参数uu也有536870911种
,它们是一一对应的,组合数计算在表三)。

条件3:流速FV的选取,必须同时满足这29个参数全部组合的最大最小值要求

4,总结一下,就是根据表一各参数的最大值和最小值,确定表二中相对应参数的范围
,从而挑选出表二的流速值。问题是要求考虑29个参数的全部组合,实在太大了,到底应该怎样设计这个结构,才能节约计算时间,恳请各路大神出手指点迷津,多谢了!

................................................
多谢蝗虫的帮助!补充以下三点:

1,tt和uu每列都要对应,它们的组合也要对应。

tt本身,行也要对应,即,对于任意一行,tt1,tt2,tt3,...,tt29, 都要保持在同一行上,至于行号,就无所谓上下了。

uu也一样,行也要对应,即,对于任意一行,uu1,uu2,uu3,...,uu29, 还有那个流速FV,都要保持在同一行上,至于行号,就无所谓上下了。

2, 29个参数合并的问题,举个列子您就明白了。

比如: tt1和tt2合并,有tt(:)=tt1(:)+tt2(:),这其实就相当于,比在表中的那29个参数基础之上,又多出了一个参数了。因为tt1(:)+tt2(:)的最小值,并不等于,tt1(:)的最小值加上tt2(:)的最小值,最大值也同理,并不相等。

3, 被拒绝过一次的FV,可以直接跳过下一次的筛选

已经被选上一次的FV,必须要经过下一次筛选,因为最终的FV是要满足所有的组合要求。
............................................

另,

我的做法是这样的:把29个参数的全部组合(共有536870911种),按取1个,2个,3个,...29个参数的情况分成29份(如表三中所列),分开计算,同时也能把34000000这个数值逐次降低,以求加快速度,但还是太慢了。具体code如下:

第一步:考虑29个参数组合(1种可能)
maxtt = maxval(tt(:,1)+tt(:,2)+tt(:,3)+...tt(:,29))
mintt = minval(tt(:,1)+tt(:,2)+tt(:,3)+...tt(:,29))
uuu(:) = uu(:,1)+uu(:,2)+uu(:,3)+...uu(:,29)
C
do i = 1, 34000000
if ((uuu(i).lt.mintt).or.(uuu(i).gt.maxtt)) then
FV(i) = 0
else
endif
enddo
C
n1 = 0
do i = 1, 34000000
if (FV(i).ne.0) then
n1 = n1 + 1
FV(n1) = FV(i)
C
do j = 1, 29
uu(n1,j) = uu(i,j)
enddo
else
endif
enddo

第二步:考虑28个参数组合(29种可能)
do i1 = 1, 2
do i2 = i1+1, 3
do i3 = i2+1, 4
do i4 = i3+1, 5
do i5 = i4+1, 6
do i6 = i5+1, 7
do i7 = i6+1, 8
do i8 = i7+1, 9
do i9 = i8+1, 10
do i10 = i9+1, 11
do i11 = i10+1, 12
do i12 = i11+1, 13
do i13 = i12+1, 14
do i14 = i13+1, 15
do i15 = i14+1, 16
do i16 = i15+1, 17
do i17 = i16+1, 18
do i18 = i17+1, 19
do i19 = i18+1, 20
do i20 = i19+1, 21
do i21 = i20+1, 22
do i22 = i21+1, 23
do i23 = i22+1, 24
do i24 = i23+1, 25
do i25 = i24+1, 26
do i26 = i25+1, 27
do i27 = i26+1, 28
do i28 = i27+1, 29
maxtt = maxval(tt(:,i1)+tt(:,i2)+tt(:,i3)+...tt(:,i28))
mintt = maxval(tt(:,i1)+tt(:,i2)+tt(:,i3)+...tt(:,i28))
uuu(1:n1)=uu(1:n1,i1)+uu(1:n1,i2)+uu(1:n1,i3)+...+uu(1:n1,i28)
C
do i = 1, n1
if ((FV(i).eq.0).or.(uuu(i).lt.mintt).or.(uuu(i).gt.maxtt)) then
FV(i) = 0
else
endif
enddo
......
enddo
C
n2 = 0
do i = 1, n1
if (FV(i).ne.0) then
n2 = n2 + 1
FV(n2) = FV(i)
C
do j = 1, 29
uu(n2,j) = uu(i,j)
enddo
else
endif
enddo
第三步:考虑1个参数组合(29种可能)
......
第四步:考虑27个参数组合(407种可能)
.......
第五步:考虑2个参数组合(407种可能)
..........
第六步:考虑26个参数组合(3654种可能)
..........
第七步:考虑3个参数组合(3654种可能)
.........
.........
........
最后一步:考虑15个参数组合(77558760种可能)
.............

f
ftmit

自顶一下,请版主不要删,非常着急出结果,灌水paper,谢谢了

L
LC1

现在写Fortran的人不多了。CS版的都没有几个。
f
ftmit

恩,没法子,大老板给的原始代码就是用纯fortran写的。

【 在 LC1 (ots) 的大作中提到: 】
: 现在写Fortran的人不多了。CS版的都没有几个。

l
lcspider

和语言无关。
1. 对每一列控制参数,算出它们的最大,最小值。这个是O(N)复杂度。
2. 对每一列备选参数,Sort这些行,key值是备选参数的值,value是行的index。复杂度O(MlogM).M是备选参数的行数。
3. 对每一列,用binary search。找出在min value和max value之间的行的所有index
,作为一个set
4. enumerate 1-29的所有combination。这个大概是2^29个。每一个combination,对
应3里面set 的intersection。intersection的set就是要求的所有行index。
5. 可以对这些index set对应的行的数据做任何操作,包括求average,等等。

【 在 ftmit (八戒) 的大作中提到: 】
: 恩,没法子,大老板给的原始代码就是用纯fortran写的。

l
lcspider

貌似2可以不用sort。省略2.直接3,然后traversal行,就行了。
【 在 lcspider (lcspider) 的大作中提到: 】
: 和语言无关。
: 1. 对每一列控制参数,算出它们的最大,最小值。这个是O(N)复杂度。
: 2. 对每一列备选参数,Sort这些行,key值是备选参数的值,value是行的index。复杂
: 度O(MlogM).M是备选参数的行数。
: 3. 对每一列,用binary search。找出在min value和max value之间的行的所有
index
: ,作为一个set
: 4. enumerate 1-29的所有combination。这个大概是2^29个。每一个combination,对
: 应3里面set 的intersection。intersection的set就是要求的所有行index。
: 5. 可以对这些index set对应的行的数据做任何操作,包括求average,等等。

l
linyuelegant

改写成新一代语言,python或者r,配合一些新功能,又可以灌水一篇
【 在 ftmit (八戒) 的大作中提到: 】
: 恩,没法子,大老板给的原始代码就是用纯fortran写的。

f
ftmit

谢谢大神指点迷津,我马上琢磨一下。

【 在 lcspider(lcspider) 的大作中提到: 】

: 和语言无关。

: 1. 对每一列控制参数,算出它们的最大,最小值。这个是O(N)复杂度。

: 2. 对每一列备选参数,Sort这些行,key值是备选参数的值,value是行的index。复杂

: 度O(MlogM).M是备选参数的行数。

: 3. 对每一列,用binary search。找出在min value和max value之间的行的所有index

: ,作为一个set

: 4. enumerate 1-29的所有combination。这个大概是2^29个。每一个
combination,对

: 应3里面set 的intersection。intersection的set就是要求的所有行index。

: 5. 可以对这些index set对应的行的数据做任何操作,包括求average,等等。