二维元细胞自动机之机器人寻伴记(已可视化)

##
# 数学模型:二维元细胞自动机模型
# 问题背景:在一个长宽为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()
            
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值