这是一个转贴,因为我得到了奇怪的结果。我正在尝试为细胞自动机代码中的细胞运行模拟循环,该代码根据相邻的邻居改变土地使用代码。我导入创建单元格id键=土地使用代码值的文本文件。我还导入了每个单元格的相邻邻居的文本文件。我第一次运行代码时,7509个单元基于相邻的邻居土地使用改变了土地使用。我可以注释读取字典文本文件并再次运行,然后大约5,000个单元格更改。再次运行,然后再少运行等等。我想要做的是循环运行,直到只有0.0001的总单元格改变,然后打破循环。
我尝试了一段时间循环,但它没有给我我想要的结果。第一次运行后,计数在7509正确。之后计数一次又一次是28,476。我不明白为什么会这样,因为计数应该回到零。谁能告诉我我做错了什么?这是代码:
import sys, string, csv
#Creating a dictionary of FID: LU_Codes from external txt file
text_file = open("H:\SWAT\NC\FID_Whole_Copy.txt", "rb")
#Lines = text_file.readlines()
FID_GC_dict = dict()
reader = csv.reader(text_file, delimiter='\t')
for line in reader:
FID_GC_dict[line[0]] = int(line[1])
text_file.close()
#Importing neighbor list file for each FID value
Neighbors_file = open("H:\SWAT\NC\Pro_NL_Copy.txt","rb")
Entries = Neighbors_file.readlines()
Neighbors_file.close()
Neighbors_List = map(string.split, Entries)
#print Neighbors_List
#creates a list of the current FID
FID = [x[0] for x in Neighbors_List]
gridList = []
for nlist in Neighbors_List:
row = []
for item in nlist:
row.append(FID_GC_dict[item])
gridList.append(row)
#print gridList
#Calculate when to end of one sweep
tot_cells = len(FID)
end_sim = tot_cells
p = 0.0001
#Performs cellular automata rules on land use grid codes
while (end_sim > tot_cells*p):
i = iter(FID)
count = 0
for glist in gridList:
Cur_FID = i.next()
Cur_GC = glist[0]
glist.sort()
lr_Value = glist[-1]
if lr_Value < 6:
tie_LR = glist.count(lr_Value)
if tie_LR >= 4 and lr_Value > Cur_GC:
FID_GC_dict[Cur_FID] = lr_Value
#print "The updated gridcode for FID ", Cur_FID, "is ", FID_GC_dict[Cur_FID]
count += 1
end_sim = count
print end_sim
再次感谢您的帮助.... :(
答案 0 :(得分:1)
我修改了代码,以便在更改的单元格数小于总单元格的0.0001后停止模拟。我把while循环放在错误的地方。如果有人有兴趣,这里是修改后的土地使用细胞自动机代码。
import sys, string, csv
#Creating a dictionary of FID: LU_Codes from external txt file
text_file = open("H:\SWAT\NC\FID_Whole_Copy.txt", "rb")
#Lines = text_file.readlines()
FID_GC_dict = dict()
reader = csv.reader(text_file, delimiter='\t')
for line in reader:
FID_GC_dict[line[0]] = int(line[1])
text_file.close()
#Importing neighbor list file for each FID value
Neighbors_file = open("H:\SWAT\NC\Pro_NL_Copy.txt","rb")
Entries = Neighbors_file.readlines()
Neighbors_file.close()
Neighbors_List = map(string.split, Entries)
#print Neighbors_List
#creates a list of the current FID
FID = [x[0] for x in Neighbors_List]
#print FID
#Calculate when to end the simulations (neglible change in land use)
tot_cells = len(FID)
end_sim = tot_cells
p = 0.0001
#Performs cellular automata rules on land use grid codes
while (end_sim > tot_cells*p):
gridList = []
for nlist in Neighbors_List:
row = []
for item in nlist:
row.append(FID_GC_dict[item])
gridList.append(row)
#print gridList
i = iter(FID)
count = 0
for glist in gridList:
Cur_FID = i.next()
Cur_GC = glist[0]
glist.sort()
lr_Value = glist[-1]
if lr_Value < 6:
tie_LR = glist.count(lr_Value)
if tie_LR >= 4 and lr_Value > Cur_GC:
FID_GC_dict[Cur_FID] = lr_Value
print "The updated gridcode for FID ", Cur_FID, "is ", FID_GC_dict[Cur_FID]
count += 1
end_sim = count
print count
答案 1 :(得分:0)
我不知道您正在编程的细胞自动机的类型,因此我只是猜测,但通常细胞自动机的工作方式是更新整个阶段,忽略更新的值,直到阶段结束。
当我对简单的细胞自动机产生了意想不到的结果时,我只是忘了将相位应用到备份网格,但是我将它直接应用到我正在处理的网格中。
我的意思是你应该有2个网格,我们称之为grid1
和grid2
,并执行类似
init grid1 with data
while number of generations < total generations needed
calculate grid2 as the next generation of grid1
grid1 = grid2 (you replace the real grid with the buffer)
直接更改grid1的值会导致不同的结果,因为在完成当前阶段之前,您将主要更改仍需要更新的单元格的邻居。