我想生成一个包含10,000个节点的随机Barabasi-Albert图,但我的程序非常慢。如果我的子程序是否正确,任何人都可以帮忙吗?在我的代码中,ran1()是标准的随机数生成器。谢谢你的帮助。
***********************************************************************
subroutine barabasi_albert(kon,n,m0,m,a,idum)
***********************************************************************
implicit real*8(a-h,o-z)
implicit integer*4(i-n)
logical linked(n) ! logical array for storing if a node is connected
! to the current one
dimension kon(n,n) ! connectivity matrix
! m0: number of initial nodes
! m: minimal degree
! a: scale parameter
! idum: argument to the random number generation
c
c Initialize kon(:,:)
c
kon(:n,:n)=0
c
c Create complete graph of m0 node
c
kon(:m0,:m0)=1
do i=1,m0
kon(i,i)=0
end do
c
c Extend the graph with n-m0 node
c
do i=m0+1,n
linked(:i)=.false.
c
c Add edges while the vertex degree of the ith node is less than m
c
do
if(sum(kon(i,:i-1)).eq.m) exit
ii=floor(dble(i-1)*ran1(idum))+1
if(.not.linked(ii)) then
p=(dble(sum(kon(ii,:i-1)))/sum(kon(:i-1,:i-1)))**a
if(p.gt.ran1(idum)) then
kon(i,ii)=1
kon(ii,i)=1
linked(ii)=.true.
endif
endif
end do
end do
end
一些链接连接到:
Implementing Barabasi-Albert Method for Creating Scale-Free Networks
答案 0 :(得分:1)
我对Fortran并不熟悉,但有些事情很突出。首先考虑函数的时间复杂度。你有两个嵌套循环。第一个运行n
次,其中n
与输入的大小成比例。第二个运行,直到找到m0
个连接。但是在最里面的循环中,你可以计算出数组部分的总和。第一笔金额包括i*(i-1)
个加法,这可能是最昂贵的。所以时间复杂度受O(n*m0*i^2)
的限制。假设m0
很小,则变为O(n^3)
。
我认为最好的改进是改用时间复杂度较低的算法,但如果不可能,你仍然可以调整你所拥有的。首先,缓存你的总和。不要两次计算相同的金额。或者,如果您计算sum(1:i)
,请保存该结果并在计算sum(1:i+1)
或sum(1:i-1)
时使用。