用python实现agent模型[对原文订正版]

[说明]这篇博客是对原文代码的订正的原创[笑哭]好绕口啊
疫情当前没法去学校,网课学习之余学习一下课外之物[偷笑]
因为发现CSDN上和百度上的agent模型代码是错误的,而且各种查到的代码中错误地方大都一样。因此为了方便需要的朋友学习把正确的发一下,如果想看原文可以参考下面的链接。
这是我原来我找到的agent模型链接:原文链接本文只是对上述链接中代码的一些小错误的订正

运行后会在代码文件所在目录下产生这四个文件详细的就不多发了

博主00后高中生,不知道有没有00后的朋友看到这篇文章,看到的麻烦举个爪
在这里插入图片描述
这是订正后的代码

import matplotlib.pyplot as plt
import itertools
import random
import copy
class Schelling:
    def __init__( self,width, height, empty_ratio, similarity_threshold, n_iterations, races = 2):
        self.width = width
        self.height = height
        self.races = races
        self.empty_ratio = empty_ratio
        self.similarity_threshold = similarity_threshold
        self.n_iterations = n_iterations
        self.empty_houses = []
        self.agents = {}
 
    def populate(self):
        self.all_houses = list(itertools.product(range(self.width),range(self.height)))
        random.shuffle(self.all_houses)
 
        self.n_empty = int( self.empty_ratio * len(self.all_houses) )
        self.empty_houses = self.all_houses[:self.n_empty]
 
        self.remaining_houses = self.all_houses[self.n_empty:]
        houses_by_race = [self.remaining_houses[i::self.races] for i in range(self.races)]
        for i in range(self.races):
            # 为每个种族创建 agent
            self.agents = dict(self.agents.items() + dict(zip(houses_by_race[i], [i+1]*len(houses_by_race[i]))).items())
 
    def is_unsatisfied(self, x, y):
 
        race = self.agents[(x,y)]
        count_similar = 0
        count_different = 0
 
        if x > 0 and y > 0 and (x-1, y-1) not in self.empty_houses:
            if self.agents[(x-1, y-1)] == race:
                count_similar += 1
            else:
                count_different += 1
        if y > 0 and (x,y-1) not in self.empty_houses:
            if self.agents[(x,y-1)] == race:
                count_similar += 1
            else:
                count_different += 1
        if x < (self.width-1) and y > 0 and (x+1,y-1) not in self.empty_houses:
            if self.agents[(x+1,y-1)] == race:
                count_similar += 1
            else:
                count_different += 1
        if x > 0 and (x-1,y) not in self.empty_houses:
            if self.agents[(x-1,y)] == race:
                count_similar += 1
            else:
                count_different += 1        
        if x < (self.width-1) and (x+1,y) not in self.empty_houses:
            if self.agents[(x+1,y)] == race:
                count_similar += 1
            else:
                count_different += 1
        if x > 0 and y < (self.height-1) and (x-1,y+1) not in self.empty_houses:
            if self.agents[(x-1,y+1)] == race:
                count_similar += 1
            else:
                count_different += 1        
        if x > 0 and y < (self.height-1) and (x,y+1) not in self.empty_houses:
            if self.agents[(x,y+1)] == race:
                count_similar += 1
            else:
                count_different += 1        
        if x < (self.width-1) and y < (self.height-1) and (x+1,y+1) not in self.empty_houses:
            if self.agents[(x+1,y+1)] == race:
                count_similar += 1
            else:
                count_different += 1
 
        if (count_similar+count_different) == 0:
            return False
        else:
            return float(count_similar)/(count_similar+count_different) < self.similarity_threshold
 
    def update(self):
        for i in range(self.n_iterations):
            self.old_agents = copy.deepcopy(self.agents)
            n_changes = 0
            for agent in self.old_agents:
                if self.is_unsatisfied(agent[0], agent[1]):
                    agent_race = self.agents[agent]
                    empty_house = random.choice(self.empty_houses)
                    self.agents[empty_house] = agent_race
                    del self.agents[agent]
                    self.empty_houses.remove(empty_house)
                    self.empty_houses.append(agent)
                    n_changes += 1
            print n_changes
            if n_changes == 0:
                break

    def move_to_empty(self, x, y):
        race = self.agents[(x,y)]
        empty_house = random.choice(self.empty_houses)
        self.updated_agents[empty_house] = race
        del self.updated_agents[(x, y)]
        self.empty_houses.remove(empty_house)
        self.empty_houses.append((x, y))
 
    def plot(self, title, file_name):
        fig, ax = plt.subplots()
        # 如果要进行超过 7 种颜色的仿真,你应该相应地进行设置
        agent_colors = {1:'b', 2:'r', 3:'g', 4:'c', 5:'m', 6:'y', 7:'k'}
        for agent in self.agents:
            ax.scatter(agent[0]+0.5, agent[1]+0.5, color=agent_colors[self.agents[agent]])
 
        ax.set_title(title, fontsize=10, fontweight='bold')
        ax.set_xlim([0, self.width])
        ax.set_ylim([0, self.height])
        ax.set_xticks([])
        ax.set_yticks([])
        plt.savefig(file_name)
                            
schelling_1 = Schelling(50, 50, 0.3, 0.3, 500, 2)
schelling_1.populate()
 
schelling_2 = Schelling(50, 50, 0.3, 0.5, 500, 2)
schelling_2.populate()
 
schelling_3 = Schelling(50, 50, 0.3, 0.8, 500, 2)
schelling_3.populate()

schelling_1.plot('Schelling Model with 2 colors: Initial State', 'schelling_2_initial.png')

schelling_1.update()
schelling_2.update()
schelling_3.update()
 
schelling_1.plot('Schelling Model with 2 colors: Final State with Similarity Threshold 30%', 'schelling_2_30_final.png')
schelling_2.plot('Schelling Model with 2 colors: Final State with Similarity Threshold 50%', 'schelling_2_50_final.png')
schelling_3.plot('Schelling Model with 2 colors: Final State with Similarity Threshold 80%', 'schelling_2_80_final.png')

第一个错误:
在def is_unsatisfied(self, x, y):上面一行中,dict的最后面少了一个括号“ ) ”,结果就是导致解释器认为def is_unsatisfied(self, x, y):是错误的并将def标为红色。

dict(zip(houses_by_race[i], [i+1]*len(houses_by_race[i]))).items())
 
    def is_unsatisfied(self, x, y):

第二个错误:
在def update(self):上面一行的else语句中,原文的self.happy_threshold应为self.similarity_threshold。

else:
            return float(count_similar)/(count_similar+count_different) < self.similarity_threshold#self.happy_threshold
 
    def update(self):

因为在定义__init__时定义的是similarity_threshold

class Schelling:
    def __init__( self,width, height, empty_ratio, similarity_threshold, n_iterations, races = 2):

第三个错误:
和第二个一样的错误

def update(self):
        for i in range(self.n_iterations):
            self.old_agents = copy.deepcopy(self.agents)
            n_changes = 0
            for agent in self.old_agents:
                if self.is_unsatisfied(agent[0], agent[1]):

在def update(self):语句中的if语句中
原文的self.is_unhappy应为self.is_unsatisfied。原因也是因为在定义__init__时使用的是self.is_unsatisfied

if self.is_unsatisfied(agent[0], agent[1]):

最后一个问题就是:

schelling_1.plot('Schelling Model with 2 colors: Initial State', 'schelling_2_initial.png')

schelling_1.update()
schelling_2.update()
schelling_3.update()

原文中schelling_1.plot(‘Schelling Model with 2 colors: Initial State’, ‘schelling_2_initial.png’)为schelling_1_1导致没法运行
这个是初始情况下的分布图,而我直接改为schelling_1

The Ending

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值