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

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

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

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

解決済

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

HGK
HGK

総合スコア27

Python

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

1回答

0評価

0クリップ

361閲覧

投稿2021/11/18 09:02

編集2021/11/20 16:35

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

Python

import numpy as np import random a = 0.4 b = 0.4 c = 0.2 v1 = 0.3 v2 = 0.3 v3 = 0.6 w1 = 0.2 w2 = 0.2 w3 = 0.6 ap = 0.3 rm = 0.25 q = 0.3 def sign(x,y): if x*y>0: sign = 1 if x*y == 0: sign = 0 if x*y<0: sign = -1 return sign def gij(x,y,z): change = v1*(sign(x,y)*(abs(x*y)**0.5)-z) return change class Agent: def __init__(self,agent_id): self.id = agent_id self.talk = [] self.topic = [] self.f = np.random.uniform(low=0.0, high=0.1, size=None) #影響力 self.s = {} #影響力更新で使用 self.friend_list = [] #友人リンク self.hi_friend_list = [] #被友人リンク self.exclusion_list = [] #排斥リンク self.hi_exclusion_list = [] #被排斥リンク self.bullying_list = [] #いじめリンク self.hi_bullying_list = [] #被いじめリンク self.lp = {} #lpi iu 自分からuへの好感度 self.lc = {} #lc iu 実際の好感度 self.lagent = {} #lpi ui uからの好感度 self.lpi = {} #lpi uj u→j 自分が思うuからjへの好感度 self.lx = {} #lpi ix 自分の話題xへの好感度 self.lxagent = {} #lpi ux 自分が思うuの話題xへの好感度 def First_set(self,agents): #初期設定 issues = 10 for agent in agents: kari = {} if agent is self: continue likability = np.random.uniform(low=-0.1, high=0.1, size=None) self.lp[agent.id] = likability self.lc[agent.id] = likability like = np.random.uniform(low=-0.1, high=0.1, size=None) self.lagent[agent.id] = like for t in agents: if t is agent: continue interested = np.random.uniform(low=-0.1, high=0.1, size=None) kari[t.id] = interested self.lpi[agent.id] = kari for issue in range(issues): instinct = np.random.uniform(low=-0.1, high=0.1, size=None) self.lx[issue] = instinct kari = {} for agent in agents: if issue is agent: continue instinct = np.random.uniform(low=-0.1, high=0.1, size=None) kari[agent.id] = instinct self.lxagent[issue] = kari def decide_talk_man(self,agents): #会話相手選択 agents_except_me = {} weights_for_me = [] z = 0 for agent in agents: if agent is self: continue h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) h = (h+0.8)/1.6 z += h for agent in agents: if agent is self: continue h = a*self.lp[agent.id]+b*self.lagent[agent.id]*(1-(self.f-agent.f))+c*(self.f-agent.f) h = (h+0.8)/1.6 weight = h / z agents_except_me[agent.id] = agent.id weights_for_me.append(weight) self.talk = random.choices(list(agents_except_me), weights=weights_for_me) return self.talk def decide_topic(self,agents,talk): #話題選択 talks = self.talk[0] topic_except_me = {} weights_for_me = [] zz = 0 for agent in agents: if agent is self: continue if agent.id == talks: for age in agents: talk_f = agent.f if age is agent or age is self: continue zz += abs(self.lp[age.id]*(1-(talk_f-self.f))+self.lpi[agent.id][age.id]*(1-(self.f-talk_f))) for issue in range(issues): for agent in agents: if agent is self: continue if agent.id ==talks: zz += abs(self.lx[issue]*(1-(talk_f-self.f))+self.lxagent[issue][agent.id]*(1-(self.f-talk_f))) for agent in agents: if agent is self: continue if agent.id == talks: for age in agents: if age is agent or age is self: continue r = abs(self.lp[age.id]*(1-(talk_f-self.f))+self.lpi[agent.id][age.id]*(1-(self.f-talk_f)))/zz topic_except_me[age.id] = age.id weights_for_me.append(r) for issue in range(issues): for agent in agents: if agent is self: continue if agent.id ==talks: r = abs(self.lx[issue]*(1-(talk_f-self.f))+self.lxagent[issue][agent.id]*(1-(self.f-talk_f)))/zz issue += 31 topic_except_me[issue] = issue weights_for_me.append(r) self.topic = random.choices(list(topic_except_me), weights=weights_for_me) return self.topic def update_like1(self,agents,talk,topic): #好感度更新 talks = talk[0] topics = topic[0] if topics <= 30: x = self.lp[talks] y = self.lp[topics] ran = random.choices(("A","B")) if ran == "A": z = self.lpi[talks][topics] else: z = self.lpi[topics][talks] else: topics -= 31 x = self.lx[topics] y = self.lp[talks] z = self.lxagent[topics][talks] l = x*y*z if l>=0: dlu1 = gij(y,z,x) dlx1 = gij(x,z,y) else: A = random.choices((x,y)) if A == x: dlu1 = gij(x,z,0) dlx1 = 0 else: dlu1 = 0 dlx1 = gij(y,z,0) for agent in agents: if agent.id is talks: r = w1*self.lp[talks]+w2*self.lagent[talks]*(1-(self.f-agent.f))+w3*(self.f-agent.f) r = (r+0.8)/1.6 break weights_for_stra = {r,1-r} kinds_of_stra = ["mini","same"] stra = random.choices(kinds_of_stra, weights=weights_for_stra) if stra == "mini": dlu2 = v2*(self.lagent[talks]-self.lp[talks]) else: dlu2 = v3*sign(1,(self.lagent[talks]))*(abs(self.lagent[talks]+self.lp[talks])) dlu = dlu1+dlu2 dlx = dlx1 return dlu,dlx def update_like2(self,talk,topic,dlu,dlx): #好感度更新2 talks = self.talk[0] topics = self.topic[0] self.lp[talks] = self.lp[talks]+dlu if self.lp[talks] > 1.0: self.lp[talks] = 1.0 elif self.lp[talks] < -1.0: self.lp[talks] = -1.0 self.lc[talks] = self.lp[talks] if topics <= 30: self.lp[topics] += dlx if self.lp[topics] > 1.0: self.lp[topics] = 1.0 elif self.lp[topics] < -1.0: self.lp[topics] = -1.0 else: topics -= 31 self.lx[topics] += dlx if self.lx[topics] > 1.0: self.lx[topics] = 1.0 elif self.lx[topics] < -1.0: self.lx[topics] = -1.0 def link(self,agents): #友人リンク、排斥リンクの設定 for agent in agents: if agent is self: continue if self.lc[agent.id] >= 0.20: if agent.id in self.friend_list: continue self.friend_list.append(agent.id) agent.hi_friend_list.append(self.id) elif self.lc[agent.id] <= -0.12: if agent.id in self.exclusion_list: continue self.exclusion_list.append(agent.id) agent.hi_exclusion_list.append(self.id) else: pass if self.lc[agent.id] < 0.20 and agent.id in self.friend_list: self.friend_list.remove(agent.id) agent.hi_friend_list.remove(self.id) elif self.lc[agent.id] > -0.12 and agent.id in self.exclusion_list: self.exclusion_list.remove(agent.id) agent.hi_exclusion_list.remove(self.id) def ijime_link(self,agents): #いじめリンク設定 for agent in agents: if agent is self: continue if agent.id in self.friend_list and self.id in agent.friend_list: candidate = set(self.exclusion_list) & set(agent.exclusion_list) for age in agents: if age is self or agent is age: continue if age.id in self.friend_list and self.id in age.friend_list: ijime = set(candidate) & set(age.exclusion_list) for ij in ijime: if ij not in self.bullying_list: self.bullying_list.append(ij) for agent in agents: if agent is self: continue if agent.id in self.bullying_list: if self.id in agent.hi_bullying_list: continue agent.hi_bullying_list.append(self.id) if agent.id not in self.exclusion_list and agent.id in self.bullying_list: self.bullying_list.remove(agent.id) agent.hi_bullying_list.remove(self.id) def update_f(self,turn): #影響力更新 self.s[turn] = (len(self.hi_friend_list)-len(self.hi_exclusion_list)) if turn > 0: dr = rm*(self.s[turn]-self.s[turn-1]) self.f += dr if self.f > 1.0: self.f = 1.0 elif self.f < 0: self.f = 0 def updete_Pnet(self,agents): #他の生徒から他の生徒への好感度更新 for agent in agents: for age in agents: if agent is age or self is agent: continue E = np.random.uniform(low=-0.3, high=0.3, size=None) dlp = ap*(agent.lc[age.id]-self.lpi[agent.id][age.id])+E self.lpi[agent.id][age.id] += dlp if self.lpi[agent.id][age.id] > 1.0: self.lpi[agent.id][age.id] = 1.0 elif self.lpi[agent.id][age.id] < -1.0: self.lpi[agent.id][age.id] = -1.0 class Simulation: def __init__(self): self.agents = [] def generate_agents(self, agents_num): self.agents = [Agent(agent_id) for agent_id in range(agents_num)] for agent in self.agents: agent.First_set(self.agents) def play_the_game(self): num_agents = 31 turns = 4000 self.generate_agents(num_agents) for turn in range(turns): for agent in self.agents: self.talk = agent.decide_talk_man(self.agents) self.topic = agent.decide_topic(self.agents,self.talk) dlu,dlx = agent.update_like1(self.agents,self.talk,self.topic) agent.update_like2(self.talk,self.topic,dlu,dlx) agent.link(self.agents) agent.ijime_link(self.agents) agent.update_f(turn) agent.updete_Pnet(self.agents)

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

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

can110

2021/11/18 09:25

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

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Python

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