##
# 数学模型:二维元细胞自动机模型
# 问题背景:在一个长宽为64*64的广场上随机分布着小兰和小红两种机器人,他们在广场上游荡着,找着自己的另一半。
# 模型假设:
# 1. 只有两者的接口相匹配的时候才能成功,接口有圆形,矩形,三角形三种形状
# 2. 他们会和东西南北四个方向的机器人碰面,如果有自己的另一半,那么就有merge的概率去结合
# 3. 结合之后有part的概率再次分开,分开之后机器人泯灭
# 4. 每回合有一定的概率可以重生机器人
# ##
import matplotlib.pyplot as plt
import random
import numpy as np
class Map:
def __init__(self):
self.map_size =(64,64)
#正数表示小兰,负数表示小红。1,2,3;-1,-2,-3六个值
self.map = np.zeros(self.map_size,int)
self.map2 = self.map.copy()
self.union_map = np.zeros(self.map_size,int)#指向另一半
self.union_map2 = self.union_map.copy()
for i in range(64):
for j in range(64):
type = random.randint(-3,20)#空地和机器人是3:1
if type >= 4:
type = 0
self.map2[i][j] = type
self.map = self.map2.copy()
self.time = 1
self.count = 0
self.inc = 0
self.dec = 0
self.relf =0
self.merge_rate = 0.521
self.part_rate = 0.00520
self.relife_rate = 0
self.cycle()
def possible(self,probility):
num = random.random()
if num < probility:
return True
else:
return False
def move(self):
p = [(0,1),(0,-1),(-1,0),(1,0)]
size = self.map_size[0]
for i in range(size):
for j in range(size):
if self.union_map[i][j] != 0:
continue
d = random.randint(0,3)
for dir in range(4):
newi = i + p[d][0]
newj = j + p[d][1]
if self.outBound(newi,newj):
continue
#东西南北都没空间的话就不动了
num = self.map2[ newi ][ newj ]
if num != 0:
d = d + 1
d = d % 4
else:
temp = self.map2[i][j]
self.map2[i][j] = 0
self.map2[ newi ][ newj ] = temp
break
self.map = self.map2.copy()
def outBound(self,i,j):
size = self.map_size[0]
if i < 0 or j < 0:
return True
elif i >= size or j >= size:
return True
return False
def find(self):
p = [(0,1),(0,-1),(-1,0),(1,0)]
size = self.map_size[0]
for i in range(size):
for j in range(size):
if self.union_map2[i][j] != 0:
continue
d = random.randint(0,3)
for dir in range(4):
newi = i + p[d][0]
newj = j + p[d][1]
if self.outBound(newi,newj):
continue
if self.union_map2[newi][newj] != 0:
continue
if self.map2[newi][newj] == 0:
continue
n1 = self.map2[i][j]
n2 = self.map2[newi][newj]
if n1+n2 == 0:
if self.possible(self.merge_rate):
self.map2[i][j] = self.map2[newi][newj] = 9
self.union_map2[i][j] = newi*size + newj
self.union_map2[newi][newj] = i*size + j
self.count += 1
self.inc += 1
break
self.map = self.map2.copy()
self.union_map = self.union_map2.copy()
def part(self):
size = self.map_size[0]
for i in range(size):
for j in range(size):
if self.union_map2[i][j] == 0:
continue
if self.possible(self.part_rate):
num = self.union_map2[i][j]
newi = int(num / size)
newj = int(num % size)
self.map2[i][j] = self.map2[newi][newj] = 0
self.union_map2[i][j] = self.union_map2[newi][newj] = 0#化为乌有
self.count -=1
self.dec += 1
self.map = self.map2.copy()
self.union_map = self.union_map2.copy()
def relife(self):
size = self.map_size[0]
for i in range(size):
for j in range(size):
if self.map2[i][j] == 0:
if self.possible(self.relife_rate):
rtype = random.choice([-1,-2,-3,1,2,3])
self.map2[i][j] = rtype
self.relf += 1
self.map = self.map2.copy()
def cycle(self):
for i in range(100000):
self.find()
print(f"总对数:{self.count}")
self.move()
self.part()
self.relife()
plt.imshow(self.map)
plt.pause(self.time)
print(f"第{i}轮:新匹配的:{self.inc},分手的:{self.dec},复活的:{self.relf}" )
self.relife_rate = self.dec/1000
self.dec = self.relf = self.inc = 0
if __name__ == "__main__":
rmap = Map()
二维元细胞自动机之机器人寻伴记(已可视化)
最新推荐文章于 2024-07-27 12:20:46 发布