智能系统实验: Schelling 隔离模型仿真

该代码实现了一个基于Python的Schelling模型,用于模拟不同种族在相同环境中的分布情况。通过设定空房比例、相似性阈值和迭代次数,观察不同条件下种族之间的满意度和隔离现象。模型初始化、更新和绘图功能展示了不同参数下的最终状态。
摘要由CSDN通过智能技术生成
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.old_agents = None
        self.remaining_houses = None
        self.n_empty = None
        self.all_houses = None
        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):
            self.agents = dict(
                list(self.agents.items()) + list(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_different + count_similar) < self.happy_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:
                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 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)


if __name__ == '__main__':
    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')

运行结果

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小那同学

晚饭加鸡腿🍗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值