質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1012閲覧

マルチエージェントシミュレーションの様子をグラフなどによる可視化の方法

HGK

総合スコア29

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/18 09:02

編集2021/11/20 16:35

学級の様子をモデル化しています
その際に、このような好感度の分布を可視化したいと考えています(手書きですいません)
イメージ説明
現在、次のようなコードを組み、シミュレーションを行うことができています
流れは初期設定→会話相手選択→話題選択→好感度更新→影響力更新の順で行います
生徒にはクラス内の影響力、他の生徒への好感度、他の生徒同士の好感度を設定しています

Python

1import numpy as np 2import random 3 4a = 0.4 5b = 0.4 6c = 0.2 7v1 = 0.3 8v2 = 0.3 9v3 = 0.6 10w1 = 0.2 11w2 = 0.2 12w3 = 0.6 13ap = 0.3 14rm = 0.25 15q = 0.3 16 17 18def sign(x,y): 19 if x*y>0: 20 sign = 1 21 if x*y == 0: 22 sign = 0 23 if x*y<0: 24 sign = -1 25 return sign 26 27def gij(x,y,z): 28 change = v1*(sign(x,y)*(abs(x*y)**0.5)-z) 29 return change 30 31 32class Agent: 33 def __init__(self,agent_id): 34 self.id = agent_id 35 self.talk = [] 36 self.topic = [] 37 self.f = np.random.uniform(low=0.0, high=0.1, size=None) #影響力 38 self.s = {} #影響力更新で使用 39 self.friend_list = [] #友人リンク 40 self.hi_friend_list = [] #被友人リンク 41 self.exclusion_list = [] #排斥リンク 42 self.hi_exclusion_list = [] #被排斥リンク 43 self.bullying_list = [] #いじめリンク 44 self.hi_bullying_list = [] #被いじめリンク 45 self.lp = {} #lpi iu 自分からuへの好感度 46 self.lc = {} #lc iu 実際の好感度 47 self.lagent = {} #lpi ui uからの好感度 48 self.lpi = {} #lpi uj u→j 自分が思うuからjへの好感度 49 self.lx = {} #lpi ix 自分の話題xへの好感度 50 self.lxagent = {} #lpi ux 自分が思うuの話題xへの好感度 51 52 def First_set(self,agents): #初期設定 53 issues = 10 54 for agent in agents: 55 kari = {} 56 if agent is self: 57 continue 58 likability = np.random.uniform(low=-0.1, high=0.1, size=None) 59 self.lp[agent.id] = likability 60 self.lc[agent.id] = likability 61 like = np.random.uniform(low=-0.1, high=0.1, size=None) 62 self.lagent[agent.id] = like 63 for t in agents: 64 if t is agent: 65 continue 66 interested = np.random.uniform(low=-0.1, high=0.1, size=None) 67 kari[t.id] = interested 68 self.lpi[agent.id] = kari 69 70 for issue in range(issues): 71 instinct = np.random.uniform(low=-0.1, high=0.1, size=None) 72 self.lx[issue] = instinct 73 kari = {} 74 for agent in agents: 75 if issue is agent: 76 continue 77 instinct = np.random.uniform(low=-0.1, high=0.1, size=None) 78 kari[agent.id] = instinct 79 self.lxagent[issue] = kari 80 81 def decide_talk_man(self,agents): #会話相手選択 82 agents_except_me = {} 83 weights_for_me = [] 84 z = 0 85 for agent in agents: 86 if agent is self: 87 continue 88 h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) 89 h = (h+0.8)/1.6 90 z += h 91 for agent in agents: 92 if agent is self: 93 continue 94 h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) 95 h = (h+0.8)/1.6 96 weight = h / z 97 agents_except_me[agent.id] = agent.id 98 weights_for_me.append(weight) 99 self.talk = random.choices(list(agents_except_me), weights=weights_for_me) 100 return self.talk 101 102 def decide_topic(self,agents,talk): #話題選択 103 talks = self.talk[0] 104 topic_except_me = {} 105 weights_for_me = [] 106 zz = 0 107 108 for agent in agents: 109 if agent is self: 110 continue 111 if agent.id == talks: 112 for age in agents: 113 talk_f = agent.f 114 if age is agent or age is self: 115 continue 116 zz += abs(self.lp[age.id]*(1-(talk_f-self.f))+self.lpi[agent.id][age.id]*(1-(self.f-talk_f))) 117 118 for issue in range(issues): 119 for agent in agents: 120 if agent is self: 121 continue 122 if agent.id ==talks: 123 zz += abs(self.lx[issue]*(1-(talk_f-self.f))+self.lxagent[issue][agent.id]*(1-(self.f-talk_f))) 124 125 for agent in agents: 126 if agent is self: 127 continue 128 if agent.id == talks: 129 for age in agents: 130 if age is agent or age is self: 131 continue 132 r = abs(self.lp[age.id]*(1-(talk_f-self.f))+self.lpi[agent.id][age.id]*(1-(self.f-talk_f)))/zz 133 topic_except_me[age.id] = age.id 134 weights_for_me.append(r) 135 136 for issue in range(issues): 137 for agent in agents: 138 if agent is self: 139 continue 140 if agent.id ==talks: 141 r = abs(self.lx[issue]*(1-(talk_f-self.f))+self.lxagent[issue][agent.id]*(1-(self.f-talk_f)))/zz 142 issue += 31 143 topic_except_me[issue] = issue 144 weights_for_me.append(r) 145 146 self.topic = random.choices(list(topic_except_me), weights=weights_for_me) 147 return self.topic 148 149 def update_like1(self,agents,talk,topic): #好感度更新 150 talks = talk[0] 151 topics = topic[0] 152 if topics <= 30: 153 x = self.lp[talks] 154 y = self.lp[topics] 155 ran = random.choices(("A","B")) 156 if ran == "A": 157 z = self.lpi[talks][topics] 158 else: 159 z = self.lpi[topics][talks] 160 else: 161 topics -= 31 162 x = self.lx[topics] 163 y = self.lp[talks] 164 z = self.lxagent[topics][talks] 165 l = x*y*z 166 if l>=0: 167 dlu1 = gij(y,z,x) 168 dlx1 = gij(x,z,y) 169 else: 170 A = random.choices((x,y)) 171 if A == x: 172 dlu1 = gij(x,z,0) 173 dlx1 = 0 174 else: 175 dlu1 = 0 176 dlx1 = gij(y,z,0) 177 for agent in agents: 178 if agent.id is talks: 179 r = w1*self.lp[talks]+w2*self.lagent[talks]*(1-(self.f-agent.f))+w3*(self.f-agent.f) 180 r = (r+0.8)/1.6 181 break 182 weights_for_stra = {r,1-r} 183 kinds_of_stra = ["mini","same"] 184 stra = random.choices(kinds_of_stra, weights=weights_for_stra) 185 if stra == "mini": 186 dlu2 = v2*(self.lagent[talks]-self.lp[talks]) 187 else: 188 dlu2 = v3*sign(1,(self.lagent[talks]))*(abs(self.lagent[talks]+self.lp[talks])) 189 190 dlu = dlu1+dlu2 191 dlx = dlx1 192 return dlu,dlx 193 194 def update_like2(self,talk,topic,dlu,dlx): #好感度更新2 195 talks = self.talk[0] 196 topics = self.topic[0] 197 self.lp[talks] = self.lp[talks]+dlu 198 199 if self.lp[talks] > 1.0: 200 self.lp[talks] = 1.0 201 elif self.lp[talks] < -1.0: 202 self.lp[talks] = -1.0 203 204 self.lc[talks] = self.lp[talks] 205 206 if topics <= 30: 207 self.lp[topics] += dlx 208 209 if self.lp[topics] > 1.0: 210 self.lp[topics] = 1.0 211 elif self.lp[topics] < -1.0: 212 self.lp[topics] = -1.0 213 else: 214 topics -= 31 215 self.lx[topics] += dlx 216 217 if self.lx[topics] > 1.0: 218 self.lx[topics] = 1.0 219 elif self.lx[topics] < -1.0: 220 self.lx[topics] = -1.0 221 222 223 def link(self,agents): #友人リンク、排斥リンクの設定 224 for agent in agents: 225 if agent is self: 226 continue 227 if self.lc[agent.id] >= 0.20: 228 if agent.id in self.friend_list: 229 continue 230 self.friend_list.append(agent.id) 231 agent.hi_friend_list.append(self.id) 232 elif self.lc[agent.id] <= -0.12: 233 if agent.id in self.exclusion_list: 234 continue 235 self.exclusion_list.append(agent.id) 236 agent.hi_exclusion_list.append(self.id) 237 else: 238 pass 239 240 if self.lc[agent.id] < 0.20 and agent.id in self.friend_list: 241 self.friend_list.remove(agent.id) 242 agent.hi_friend_list.remove(self.id) 243 elif self.lc[agent.id] > -0.12 and agent.id in self.exclusion_list: 244 self.exclusion_list.remove(agent.id) 245 agent.hi_exclusion_list.remove(self.id) 246 247 def ijime_link(self,agents): #いじめリンク設定 248 for agent in agents: 249 if agent is self: 250 continue 251 if agent.id in self.friend_list and self.id in agent.friend_list: 252 candidate = set(self.exclusion_list) & set(agent.exclusion_list) 253 for age in agents: 254 if age is self or agent is age: 255 continue 256 if age.id in self.friend_list and self.id in age.friend_list: 257 ijime = set(candidate) & set(age.exclusion_list) 258 for ij in ijime: 259 if ij not in self.bullying_list: 260 self.bullying_list.append(ij) 261 262 for agent in agents: 263 if agent is self: 264 continue 265 if agent.id in self.bullying_list: 266 if self.id in agent.hi_bullying_list: 267 continue 268 agent.hi_bullying_list.append(self.id) 269 270 if agent.id not in self.exclusion_list and agent.id in self.bullying_list: 271 self.bullying_list.remove(agent.id) 272 agent.hi_bullying_list.remove(self.id) 273 274 275 def update_f(self,turn): #影響力更新 276 self.s[turn] = (len(self.hi_friend_list)-len(self.hi_exclusion_list)) 277 if turn > 0: 278 dr = rm*(self.s[turn]-self.s[turn-1]) 279 self.f += dr 280 281 if self.f > 1.0: 282 self.f = 1.0 283 elif self.f < 0: 284 self.f = 0 285 286 287 def updete_Pnet(self,agents): #他の生徒から他の生徒への好感度更新 288 for agent in agents: 289 for age in agents: 290 if agent is age or self is agent: 291 continue 292 E = np.random.uniform(low=-0.3, high=0.3, size=None) 293 dlp = ap*(agent.lc[age.id]-self.lpi[agent.id][age.id])+E 294 self.lpi[agent.id][age.id] += dlp 295 296 if self.lpi[agent.id][age.id] > 1.0: 297 self.lpi[agent.id][age.id] = 1.0 298 elif self.lpi[agent.id][age.id] < -1.0: 299 self.lpi[agent.id][age.id] = -1.0 300 301 302class Simulation: 303 def __init__(self): 304 self.agents = [] 305 306 def generate_agents(self, agents_num): 307 self.agents = [Agent(agent_id) for agent_id in range(agents_num)] 308 for agent in self.agents: 309 agent.First_set(self.agents) 310 311 def play_the_game(self): 312 num_agents = 31 313 turns = 4000 314 self.generate_agents(num_agents) 315 for turn in range(turns): 316 for agent in self.agents: 317 self.talk = agent.decide_talk_man(self.agents) 318 self.topic = agent.decide_topic(self.agents,self.talk) 319 dlu,dlx = agent.update_like1(self.agents,self.talk,self.topic) 320 agent.update_like2(self.talk,self.topic,dlu,dlx) 321 agent.link(self.agents) 322 agent.ijime_link(self.agents) 323 agent.update_f(turn) 324 agent.updete_Pnet(self.agents)

結果をグラフで表現するにはどのようなコードを組めばよいか教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2021/11/18 09:25

どのようなグラフ、イメージを得たいのかを手書きでもよいので提示すると回答得られやすくなるかと思います。
guest

回答1

0

ベストアンサー

欲しいグラフイメージはmatplotlib.pyplot.histが近いと思います。
以下に簡単な描画例を示します。時間経過をアニメーションで描画しています。
参考:python ヒストグラムのアニメーション

Python

1 2import matplotlib.pyplot as plt 3import matplotlib.animation as animation 4import numpy as np 5 6class Agent: 7 def __init__(self, agent_id): 8 self.fav = 0 9 10 def update(self): 11 d = np.random.normal(0, 0.1) 12 self.fav += d 13 if self.fav >= 1 or self.fav <= -1: 14 self.fav = d 15 16class Simulation: 17 def __init__(self): 18 self.agents = [] 19 20 def generate_agents(self, agents_num): 21 self.agents = [Agent(agent_id) for agent_id in range(agents_num)] 22 self.ims = [] 23 24 def play_the_game(self): 25 num_agents = 31 26 turns = 4000 27 bins = 10 28 ymax = 15 29 self.generate_agents(num_agents) 30 31 for turn in range(turns): 32 favs = [] # 好感度 33 for agent in self.agents: 34 agent.update() 35 favs.append(agent.fav) 36 37 # 1回分のグラフ描画 38 n, bins, im = plt.hist(favs, bins=bins, range=(-1,1), color='black', histtype="step") 39 ax = plt.gca() 40 ax.set_ylim([0, ymax]) 41 self.ims.append(im) 42 43fig = plt.figure() 44sim = Simulation() 45sim.play_the_game() 46 47ani = animation.ArtistAnimation(fig, sim.ims, interval=10) 48plt.show()

イメージ説明

投稿2021/11/21 02:34

編集2021/11/21 02:38
can110

総合スコア38256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問