循环直到细胞数量变化非常小

时间:2012-02-20 15:06:49

标签: python while-loop

这是一个转贴,因为我得到了奇怪的结果。我正在尝试为细胞自动机代码中的细胞运行模拟循环,该代码根据相邻的邻居改变土地使用代码。我导入创建单元格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

再次感谢您的帮助.... :(

2 个答案:

答案 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个网格,我们称之为grid1grid2,并执行类似

的操作
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的值会导致不同的结果,因为在完成当前阶段之前,您将主要更改仍需要更新的单元格的邻居。