1. 程式人生 > >基於 Agent 的模型入門Python實現 讀書筆記

基於 Agent 的模型入門Python實現 讀書筆記

def populate(self):
    self.all_house = 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(self.agents.items()+dict(zip(house_by_race[i],[i+1]*len(houses_by_race[i]))).items()
is_unsatisfied 方法把房屋的 (x, y) 座標作為傳入引數,檢視同種群鄰居的比例,如果比理想閾值(happiness threshold)高則返回 True,否則返回 False。
    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
update 方法將檢視網格上的居民是否尚未滿意,如果尚未滿意,將隨機把此人分配到空房子中。並模擬 n_iterations 次
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_unhappy(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
move_to_empty 方法把房子座標(x, y)作為傳入引數,並將 (x, y) 房間內的居民遷入空房子。這個方法被 update 方法呼叫,會把尚不滿意的人遷入空房子。
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))

plot 方法用來繪製整個城市和居民。我們隨時可以呼叫這個方法來了解城市的居民分佈。這個方法有兩個傳入引數:title 和 file_name。