我是Python新手。我有两个用于生成和绘制2D点阵的脚本,这些脚本以分形图像的形式表示空间分布的属性。第一个脚本包含函数生成分形(正统名称:使用逆傅里叶变换的光谱合成),而第二个脚本只调用函数,绘制它,广告将其写入一个.csv文件。 函数依赖于多个random.gauss(0.0, sigma)
调用来获取正态分布的随机数。它还会调用random.random()
,因为它需要其他随机数。 以下是代码。 感谢任何有帮助的人!
问题:情节总是显示相同的模式,因此让我觉得代码中有一些不随机的东西。我的目的是每次运行代码时获得不同的分形图像。什么使它不随机?在第二个脚本中是seed=122
吗?
PS :请注意,由于该过程引入了给定程度的周期性,并且由于我不希望显示该周期性,因此绘制的晶格小于生成的晶格。特别是,我使用 size(绘制)= 101x101 ,而 size(生成)= 256x256 。
第一个脚本:函数本身
from __future__ import division #Avoids the floor of the mathematical result of division if the args are ints or longs
import numpy
import random
import math
import pylab
def SpectralSynthesisFM2D(max_level, sigma, H, seed=0, normalise=True, bounds=[0,1]):
"""
________________________________________________________________________
Args:
max_level : Maximum number of recursions (N = 2^max_level)
sigma : Initial standard deviation
H : Roughness constant (Hurst exponent), varies form 0.0 to 1.0
H=0.8 is a good representation of many natural phenomena (Voss, 1985)
seed : seed value for random number generator
normalise : normalizes the data using bound
bounds : used for normalization of the grid data
Result:
Output is given in the form of an array (grid) which holds surface
values for a square region.
_________________________________________________________________________
"""
N = int(2**max_level)
A = numpy.zeros((N,N), dtype = complex)
random.seed() #Seeds the random number generator
PI = 3.141592
for i in range(0,int((N-1)/2)):
for j in range(0,int((N-1)/2)):
phase = 2*PI*random.random() #/random.randrange(1,Arand)
if i != 0 or j != 0:
rad = pow((i*i + j*j),(-(H+1)/2) )*random.gauss(0.0, sigma)
else:
rad = 0.0
A[i][j] = rad*math.cos(phase) + rad*math.sin(phase)*j
if i ==0:
i0 = 0
else:
i0 = N - i
if j==0:
j0 = 0
else:
j0 = N - j
A[i0][j0] = rad * math.cos(phase) - rad*math.sin(phase)*j
for i in range(1,int((N-1)/2)):
for j in range(1,int((N-1)/2)):
phase = 2*PI*random.random() #/random.randrange(1,Arand)
rad = pow((i*i + j*j),(-(H+1)/2) )*random.gauss(0.0, sigma)
A[i][N-j] = rad * math.cos(phase) + rad* math.sin(phase)*j
A[N-i][j] = rad * math.cos(phase) - rad* math.sin(phase)*j
Grid = numpy.real(pylab.ifft2(( A ))) #Implements the Discrete Inverse Fast Fourier Transform on a 2D lattice (grid)
if(normalise):
Grid += numpy.amin(Grid)*-1 + bounds[0]
Grid = (Grid/numpy.amax(Grid)) * bounds[1]
return Grid
第二个脚本:绘制函数并获得分形图像:
from __future__ import division #Avoids the floor of the mathematical result of division if the args are ints or longs
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import SSFM2D
#Parameter assignments
max_level=8 #This is the exponent controlling the grid size. In this case N=2^8=256. Use only integers.
N=2**max_level
sigma=1 #Variation for random Gauss generation (standardised normal distribution)
H=0.8 #Hurst exponent (0.8 is a recommended value for natural phenomena)
seed=122 #Setting the seed for random Gauss generation
print ('The lattice size is '+str(N)+'x'+str(N))
#Lattice initialization
Lattice=np.zeros((256,256))
#Calling Spectral fBm function
Lattice=SSFM2D.SpectralSynthesisFM2D(max_level, sigma, H, seed, normalise=True, bounds=[0,1])
#Plotting the lattice
M=np.zeros((101,101)) #Lattice to be plotted. Size(M) != size(Lattice) to minimize visual fBm periodic features.
for i in range(0,101):
for j in range(0,101):
M[i][j]=Lattice[i][j]
#Lattice statistics
print M[-101:,-101:].sum()
print M[-101:,-101:].max()
print M[-101:,-101:].min()
print M[-101:,-101:].mean()
#Writing X, Y and values to a .csv file from scratch
import numpy
import csv
with open('C:\\Users\\Francesco\\Desktop\\Python_files\\csv\\fBm_256x256.csv', 'w') as f: # Change directory if necessary
writer = csv.writer(f)
writer.writerow(['X', 'Y', 'Value'])
for (x, y), val in numpy.ndenumerate(M):
writer.writerow([x, y, val])
# Plotting - Showing interpolation of randomization
plt.imshow(M[-101:,-101:].T, origin='lower',interpolation='nearest',cmap='Blues', norm=mc.Normalize(vmin=0,vmax=M.max()))
title_string=('fBm: Inverse FFT on Spectral Synthesis')
subtitle_string=('Lattice size: 101x101')
plt.suptitle(title_string, y=0.99, fontsize=17)
plt.title(subtitle_string, fontsize=9)
plt.show()
# Makes a custom list of tick mark intervals for colour bar (assumes minimum is always zero)
numberOfTicks = 5
ticksListIncrement = M.max()/(numberOfTicks)
ticksList = []
for i in range((numberOfTicks+1)):
ticksList.append(ticksListIncrement * i)
cb=plt.colorbar(orientation='horizontal', format='%0.2f', ticks=ticksList)
cb.set_label('Values')
plt.show()
plt.xlim(0, 100)
plt.xlabel('Easting (Cells)')
plt.ylim(100, 0)
plt.ylabel('Northing (Cells)')
答案 0 :(得分:1)
通常使用seed
初始化随机数生成器。同一seed
- >相同的随机数序列(非常适合测试)。
import random
random.seed(22)
for i in range(10):
print(random.randint(0, 100))
所以不管你运行那个程序多少次(甚至在什么机器上运行),输出总是一样的。
但是当你想要“真正的”随机性(或至少更好的随机性)时,你最好打电话
random.seed() # or: random.seed(None)
没有参数。然后python使用当前系统时间调用seed
- 这提供了一些随机性的来源。
因为我不知道你的图书馆,我无法确定,但我敢打赌它以一种简单的方式工作。您可以尝试设置seed=None
或seed=random.randint(something)
。
无论如何:请务必阅读您图书馆的api文档并查看seed
的内容。