0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Mesa3.xによる経済循環モデル(2)

Posted at

はじめに

前回に続きMeaa3.xでプログラム。
お題は、「貨幣の複雑性」(安富歩)の物々交換モデル(本書P59-61)です。
jupyter notebook上で動きます。
虫取りは不完全ですが、とりあえず動く状態なので、忘れないうちにアップします。

補助関数等

ロジックで共通なものを抜き出しました。

from mesa import Agent, Model
import numpy as np

import random
def random_n_except_i(n,i):
    r = random.randint(1,n-1)
    if r >= i:
        r += 1
    return r

# 配列hの数の少ない順に、配列位置を配列rに返す。
# 但し、個数の数だけ重複登録し、同数グループの順番はシャッフルする。
# 最後に配列の頭からm個を切り出す。

def select_k(h,m):
    r = []
    for i in range(1,max(h)+1):         # i = 1..配列hの最大個数
        t = []                          # t 同じ個数のグループ
        for j in range(len(h)):
            if h[j] == i:
                for k in range(1,i+1):  # 個数分だけ複製
                    t.append(j)
        random.shuffle(t)
        print(f"{i} = {t}")
        r.extend(t)
    return r[:m]

def exchange(AH,AD,BH,BD,DB):
    ks = select_k(BH,DB)
    print(ks)
    for k in ks:
        if BH[k] > 0:
            AH[k] += 1
            AD[k] -= 1
            BH[k] -= 1                  
                
        for j in range(len(BD)):
            BH[j] += BD[j]
            BD[j] = 0
    
    return ks

MoneyAgentを作成

class MoneyAgent(Agent):
    def __init__(self, model):
        super().__init__(model)
        self.w = 0      # 要求する財
        self.p = 0      # 生産する財
        self.h = []     # 所有商品
        self.d = []     # 需要
        self.u = 0.0    # 得点
        self.s = 0
    
    def step(self):
        # 1. 交換相手Bを選択する
        max_w = 0
        for b in self.model.agents:
            if b.unique_id != self.unique_id:
                hw = b.h[self.w - 1]        # bが持っている商品wの数量
                if hw > 0:
                    if hw > max_w:          # 所有数の最も大きい相手を選ぶ
                        B = b
                        max_w = hw

        if max_w > 0:           # 2. 互いの需要量を決定する
            A=self
            AW = A.w - 1        # Aの需要する商品index
            BW = B.w - 1        # Bの需要する商品index
            A.d[AW] = B.h[AW]   # Aの需要数量       
            B.d[BW] = A.h[BW]   # Bの需要数量

            DA = np.sum(A.d)    # Aの需要数量
            DB = np.sum(B.d)    # Bの需要数量

            # 交換するかどうかの判定して交換する
            if DA == DB and DB > 0:    
                for i in range(len(A.h)):
                    CA = A.d[AW] - A.d[AW]
                    CB = B.d[BW] - B.d[BW]
                    A.h[AW] += CA
                    B.h[AW] -= CA
                    B.h[AW] += CB
                    A.h[AW] -= CB           
                             
            elif DA > DB and DB > 0:
                exchange(AH,AD,BH,BD,DB)

            elif DB > DA and DA > 0:
                exchange(BH,BD,AH,AD,DA)   

            if DA > 0 and DB > 0:
                self.s += 1
                print(f"AW={AW+1} BW={BW+1} DA={DA} DB={DB}")
                print(f"A:Agent{A.unique_id} has h={A.h} d={A.d} w={A.w} and p={A.p}  u={A.u} sumD={np.sum(A.d)}")
                print(f"B:Agent{B.unique_id} has h={B.h} d={B.d} w={B.w} and p={B.p}  u={B.u} sumD={np.sum(B.d)}")   
                                 
            # 交換後、需要量を初期化
            A.d = np.zeros(len(A.h),dtype=int)
            B.d = np.zeros(len(B.h),dtype=int)         


MoneyModelの作成

class MoneyModel(Model):
    def __init__(self, n, seed=None):
        super().__init__(seed=seed)
        self.num_agents = n
        self.count = 0
        self.s = 0

        # Create n agents
        MoneyAgent.create_agents(model=self,n=n)

    def initalize(self):
        n = self.num_agents
        for a in self.agents:
            i = a.unique_id
            a.w = random_n_except_i(n,i)
            a.p = i
            a.h = np.zeros(n,dtype=int)
            a.d = np.zeros(n,dtype=int)
            a.h[i-1] = 1
            a.u = 0.0
            a.s = 0     # 取引回数
            
    def chenge_w(self):
        n = self.num_agents
        for a in self.agents:
            i = a.unique_id
            w = a.w
            a.w = random_n_except_i(n,i)
            ## print(f"Agent{i} change W from {w} to {a.w}")

    def step(self):
        self.initalize()
        self.agents.do("step")
        self.s = 0
        for a in self.agents:
            self.s += a.s
        if self.s > 0:
            print(f"success = {self.s}")
            print("***********************")

実行結果

最後は、取引回数と、取引成功の平均値です。

model = MoneyModel(5)
ss = []
for _ in range(5):
    model.step()
    ss.append(model.s)
    model.chenge_w()
print(ss)
print(np.mean(ss))

AW=4 BW=2 DA=1 DB=1
A:Agent2 has h=[0 1 0 0 0] d=[0 0 0 1 0] w=4 and p=2 u=0.0 sumD=1
B:Agent4 has h=[0 0 0 1 0] d=[0 1 0 0 0] w=2 and p=4 u=0.0 sumD=1
AW=2 BW=4 DA=1 DB=1
A:Agent4 has h=[0 0 0 1 0] d=[0 1 0 0 0] w=2 and p=4 u=0.0 sumD=1
B:Agent2 has h=[0 1 0 0 0] d=[0 0 0 1 0] w=4 and p=2 u=0.0 sumD=1
success = 2


AW=4 BW=1 DA=1 DB=1
A:Agent1 has h=[1 0 0 0 0] d=[0 0 0 1 0] w=4 and p=1 u=0.0 sumD=1
B:Agent4 has h=[0 0 0 1 0] d=[1 0 0 0 0] w=1 and p=4 u=0.0 sumD=1
AW=5 BW=2 DA=1 DB=1
A:Agent2 has h=[0 1 0 0 0] d=[0 0 0 0 1] w=5 and p=2 u=0.0 sumD=1
B:Agent5 has h=[0 0 0 0 1] d=[0 1 0 0 0] w=2 and p=5 u=0.0 sumD=1
AW=1 BW=4 DA=1 DB=1
A:Agent4 has h=[0 0 0 1 0] d=[1 0 0 0 0] w=1 and p=4 u=0.0 sumD=1
B:Agent1 has h=[1 0 0 0 0] d=[0 0 0 1 0] w=4 and p=1 u=0.0 sumD=1
AW=2 BW=5 DA=1 DB=1
A:Agent5 has h=[0 0 0 0 1] d=[0 1 0 0 0] w=2 and p=5 u=0.0 sumD=1
B:Agent2 has h=[0 1 0 0 0] d=[0 0 0 0 1] w=5 and p=2 u=0.0 sumD=1
success = 4


[2, 0, 0, 4, 0]
1.2

おわりに

力不足なので、まだ実装してない部分があります。
とりあえずは忘れない内に。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?