作者goddirk (dirk)
看板Fortran
標題[問題] 關於數對儲存格b(i,j)
時間Sun Sep 15 16:32:16 2013
接觸FORTRAN時間不算太常但也不短
但是對於副程式和寫數對b(i,j)的部分還是偏弱的
以下是修改後有問題的所有程式碼,想看原本的程式碼可私信給我信箱
我在下方每一代產生20個母體的部分有個小問題
因為怕產生的母體會有重複而影響程式效率
所以想加上判斷式,進而提高效率
問題點在"確認數列是否重複"那一段
小弟手邊也有FORTRAN 95 彭國倫編寫的書
或許有人可以跟我指點一下哪邊可以找到
program wu
use msimsl
parameter(n=08,m=20,l=1) !n=工作件數,m=代數,l=總資料組數
integer a(n),pt1(n),pt2(n),ag(n),tempa(n),t(n)
integer ag1,ag2,best(n),dd(n),b(l,m)
real sum,suma,cta(n),ctb(n)
open(4,file='lovsol.txt') !!!
141 format(08i5)
100 format(1x,08i5)
101 format(1x,08i5,/)
103 format(1x,08i5,2x,f12.4) !!!
108 format(1x,08i5,2x,2f24.4) !!!
109 format(1x,08i5,f24.4) !!!
102 format(1x,08i5,2x,f12.4)
open(1,file='data01.txt')
c call rnset(20130827)
c=====================================================
c 步驟一、讀取排序與值
c=====================================================
do 999 kkk=1,l
t0=cpsec()
c-----讀取資料 pt -----
read(1,100) (pt1(i),i=1,n)
read(1,100) (pt2(i),i=1,n)
read(1,100) (ag(i),i=1,n)
read(1,101) (dd(i),i=1,n)
tmax=1*10e30
c-----定義排序 a -----
do i=1,n
a(i)=i
enddo
c write(*,*)'原始排序'
c write(*,'(08i5)')a
c pause
c=====================================================
do 223 cc=1,m !!!20代
c=====================================================
10 loop=0
11 do i=1,n
t(i)=8*rnunf()+1
end do
!----確認為可使用數列
do i=1,n-1
do j=i+1,n
if (t(i)==t(j)) then
go to 11
end if
end do
end do
do i=1,n
a(i)=t(i)
end do
!----確認數列是否重複
do i=1,n
b(kkk,cc)=a(i)
end do
do s=1,kkk
do t=1,cc
if (a(i)==b(s,t)) then
go to 11
end if
end do
end do
!----
do i=1,n
if (ag(a(i))==1) then
ag1=i
else if (ag(a(i))==2) then
ag2=i
end if
if (ag2<ag1) then
go to 11
end if
end do
c write(*,100) (i,i=1,n)
c write(*,100) (a(i),i=1,n)
c write(*,100) (pt1(a(i)),i=1,n)
c write(*,100) (pt2(a(i)),i=1,n)
c write(*,101) (ag(a(i)),i=1,n)
c pause
!----算目標函數
sum=0.0
suma=0.0
25 do 30 i=1,n
cta(i)=0.0
ctb(i)=0.0
if (i==1) then
cta(i)=pt1(a(i))
ctb(i)=cta(i)+pt2(a(i))
else
cta(i)=cta(i-1)+pt1(a(i))
ctb(i)=max(cta(i),ctb(i-1))+pt2(a(i))
endif
ct=ctb(i)
suma=suma+ctb(i)
sum=suma
30 continue
c write(*,*) sum
c pause
!---------------判別大小(sum是挑選前,tmax是挑選後)
if (sum<tmax) then
tmax=sum
do i=1,n
best(i)=a(i)
end do
end if
c print*, kk, sum
!---------------
loop=loop+1
if (loop<20) then !!!母體數量
go to 11
end if
c write(*,103) (best(i),i=1,n),tmax
c write(*,*)
!--------------------
if (sum<tmax) then
tmax=sum
do i=1,n
best(i)=a(i)
end do
end if
223 continue
t1=cpsec()
print*, kkk, tmax, t1-t0
write(4,103) (best(i),i=1,n),tmax
c pause
999 continue
end
--
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 編輯: goddirk 來自: 140.134.18.171 (09/15 16:32)
1F:→ charlesdc:基本上你要描述的問題是? 09/15 17:04
2F:→ charlesdc:還有你對提高效率的意思可能誤解很深! 09/15 17:04
我讓他跑了20個母體出來然後重複這動作做了20次~也就是總共跑了400個母體
但是這400個母體中可能出現同樣的母體,所以我想去做排除
抱歉~詞不達意= ="
※ 編輯: goddirk 來自: 140.134.18.171 (09/15 17:07)
3F:→ charlesdc:所以你的問題是亂數取值中不重複的問題吧? 09/15 18:52
4F:→ charlesdc:做一個陣列存用過值 每次取值時去比對 09/15 18:53
5F:→ charlesdc:覺得麻煩你就一開始產生400組不重複的值去用就好了 09/15 18:54
這方法應該行不通
我們用的是基因演算法,第一代產生20個母體,然後做20代,看其收斂情況
※ 編輯: goddirk 來自: 122.117.36.192 (09/16 03:03)
6F:→ charlesdc:那這樣就有趣啦 既然母體產生的樣本會演化 演化到樣本一 09/16 20:04
7F:→ charlesdc:樣不是很正常的事嗎? 09/16 20:05
這話有道哩!我去跟我老闆討論討論
※ 編輯: goddirk 來自: 122.117.36.192 (09/16 23:21)
8F:→ charlesdc:其實爭議的地方還有幾個 你的rand seed可靠嗎? 09/17 00:31
關於這個~SEED的我C掉了
因為我發現只要是產生400個,不論是20*20或是10*40、5*80等等
跑出來的結果都會一樣
※ 編輯: goddirk 來自: 122.117.36.192 (09/17 01:25)
9F:→ charlesdc:seed通常都有一個重製的語法可以查一下 應該是漏了什麼 09/17 09:59
10F:→ charlesdc:然後通常你要你的樣本分佈較均勻的話 量要大 09/17 10:00
11F:→ charlesdc:不然你就得先跑出一大組數據符合分佈後再從裡面亂數拿取 09/17 10:01
這問題跟老師回覆過了.....他可能再想想吧XD
※ 編輯: goddirk 來自: 122.117.36.192 (10/24 17:26)