窓辺のナマケモノ

日曜プログラマーの徒然草

社会シミュレーター

兵庫県知事選や衆院選などテレビでは政治家もコメンテーターも自称専門家も口角泡を飛ばし論戦をはっている。そんな光景を見るたびに思うことがある。彼らは何を根拠に自分の政策が正しいと言い切っているのだろうか。自分の学んだこと、経験。そんなものは日々変化する社会情勢についていけないと思うのは私だけだろうか。何かに頼るとすればシミュレーションだと私は言いたい。

1940年。戦時下の日本において内閣総理大臣直轄の研究所として発足した総力戦研究所。官庁、陸海軍、民間から若手エリートが集められ日米戦争がシミュレートされた。結果は現実の日米戦争の戦局推移とほぼ合致。
コンピュータのない時代でもこれだけのことができたのだ。現代のハードウェア、ソフトウェアを駆使すれば社会シミュレーターを作ることだって夢じゃないだろう。

で、さっそくChatGPTにお願いして作ってもらったプログラムがこれ。

 

  1. import random
  2.  
  3. # 人間クラス
  4. class Citizen:
  5.     def __init__(self, name, age, job, income):
  6.         self.name = name
  7.         self.age = age
  8.         self.job = job
  9.         self.income = income
  10.         self.happiness = 50
  11.         self.health = 100
  12.         self.education_level = 0
  13.         self.social_status = "中流"
  14.         self.political_satisfaction = 50
  15.  
  16.     def work(self):
  17.         self.income += random.randint(1000, 3000)
  18.         self.happiness -= random.randint(5, 15)
  19.         print(f"{self.name} は働いて {self.income} の収入を得ました。")
  20.  
  21.     def consume(self, amount):
  22.         if self.income >= amount:
  23.             self.income -= amount
  24.             self.happiness += random.randint(5, 20)
  25.             print(f"{self.name} は {amount} を消費し、幸福度が上がりました。")
  26.         else:
  27.             print(f"{self.name} は消費する資金が不足しています。")
  28.  
  29. # 政府クラス
  30. class Government:
  31.     def __init__(self):
  32.         self.policies = {"税率": 0.2, "社会保障": 1000}
  33.         self.budget = 0
  34.  
  35.     def collect_taxes(self, population):
  36.         total_tax = 0
  37.         for person in population:
  38.             tax = person.income * self.policies["税率"]
  39.             self.budget += tax
  40.             person.income -= tax
  41.             total_tax += tax
  42.         print(f"政府は総額 {total_tax} の税金を徴収しました。")
  43.  
  44.     def distribute_welfare(self, population):
  45.         if self.budget >= len(population) * self.policies["社会保障"]:
  46.             for person in population:
  47.                 person.income += self.policies["社会保障"]
  48.                 person.happiness += 5
  49.             self.budget -= len(population) * self.policies["社会保障"]
  50.             print("社会保障を配布しました。")
  51.         else:
  52.             print("予算不足のため、社会保障の配布はできませんでした。")
  53.  
  54. # 社会クラス
  55. class Society:
  56.     def __init__(self, population_size):
  57.         self.population = [Citizen(f"市民{i}", random.randint(18, 65), "労働者", random.randint(10000, 50000))
  58.                            for i in range(population_size)]
  59.         self.government = Government()
  60.  
  61.     def update(self):
  62.         # 社会の更新処理
  63.         for person in self.population:
  64.             person.work()
  65.             person.consume(random.randint(500, 2000))
  66.         self.government.collect_taxes(self.population)
  67.         self.government.distribute_welfare(self.population)
  68.  
  69.  
  70. # シミュレーションの実行
  71. society = Society(100) # 人口100人の社会を構築
  72. for i in range(10):
  73.     print(i," -------------------")
  74.     society.update()


こんなプログラムで複雑な人間社会のシミュレーションなどできるはずがないと思う人も多いだろう。
では政治家や専門家はどうやって政策を案出しているのだろう。過去の事例と自分の経験と勘ぐらいしか頼れず、1億国民の幸不幸を決める決断を下しているではないか。もちろんこのままのプログラムではない。個々の人間の性格、家族の嗜好、天象気象の影響、技術の発展予想、数え上げればきりがないほどのパラメーターが思いつく。だからこそシミュレーションが必要だと思う。人間の頭ではこれらのパラメーターを駆使できるほどの処理能力はない。

やってみなければ分からない。
かつてフラスコの中に水、メタン、アンモニアを入れ原始大気の代わりとし、雷に似せた放電を加えたスタンリー・ミラー。この実験はあまりに単純すぎて、そこから有意なものは生ずるはずがないと誰もが考えただろうが、実際には驚くことに数種のアミノ酸ができてしまった。

電磁波が存在することを実験で証明して見せたハインリッヒ・ヘルツは「たぶん何の役にも立たないだろう。」と言った。1888年のことである。その12年後にはマルコーニが国際海洋通信会社を設立し海上の客船との通信事業に乗り出している。

現在のめざましいAI発展の先鞭をつけたウォーレン・マカロックだって自分たちの考えた単純なニューロンモデルが1000億規模になってChatGPTのような実社会で役立つAIに育つとは思っていなかっただろう。
やってみなければ分からないのだよ。

誰か政策決定に社会シミュレーターを取り込む提案をしてくれないかな。



SDGsに思う


人類はアフリカで誕生し中東、ヨーロッパ、アジア、シベリアから北米、南米へとその版図を広げてきた。しかもその先々で狩猟により多くの種を絶滅に追いやってきた。
狩るものがなくなるまで狩り、なくなったら移動する。つまり人類は自然破壊する性を背負っているから全地球に広がることができた。

北米では人類が到達した以降、マンモスやバイソン数種が絶滅。同じことは他の大陸でも数限りなく繰り返されたことだろう。
人類は進出した土地で獲物を狩りつくし、そしてさらに移動を続ける。人間の飽くなき欲望とそれを実現するだけの知能こそが人類をして生物の頂点に至らしめた。そう考えると他の生物にとって人類とは知能という魔力を手にした悪魔と言えるだろう。いくらSDGsを呪文のように唱えたところで人類の性が利用できるものを利用し尽くす運命を変えれないのではないか。レジ袋を有料にしたところでプラスチックの環境汚染が無くなるとは思えない。

しかし今後もし天体衝突などの大災害があった場合、これを乗り切るには高度な科学と実際に作り出す産業がなければならない。その時人類は地球の様々な種を助けるノアとなり、初めて悪魔の称号を返上できるだろう。

窓辺の小犬

わが家には子犬が一匹いる。実はすでに17才なので人間でいえば80を超えているだろうから子犬ではないのだが小型犬なので子犬ではなくても少なくとも小犬ではあるだろう。


かつてガラス玉のように透き通った瞳は今は白く濁り、体のあちらこちらに浮腫ができ、足腰もたよりなく、外に出しても歩きもしなくなった。
それでも食欲だけは衰えず、決まった時刻の1時間も前からねだる声に悩まされ、躾のいたらなさに後悔の毎日を送っている。
彼女(メス犬である)を見ていると老いることの醜さを知るとともに、それでも懸命に生きようとする逞しさをも見る思いがする。哲学を語るつもりはないが、生きることとは何かを考えずにはおれない。目が見えないためにトイレの場所が分からず、所かまわず用を足すようになったので仕方なくずっとおむつをしたままの生活。かつては私が帰ってくると気も狂わんばかりに飛び跳ねて喜びを表現していた引き締まったばねのような体は今は見る影もなくだらしなく緊張をゆるめている。呼んでも応えず遊ぶこともしない。食事と用を足す以外はほとんど寝たきりのような生活であっても、昔と同じ量を食べることだけは変わることがない。彼女が死んで後、渋谷のハチ公のように銅像が立つわけでもなく、本になることも、映画になることもない。我々の記憶にしか残らないその生には何の意味があるのだろう。


それは私自身も同じだ。この後よほど大罪を犯さないかぎり死んで名を遺す可能性はゼロに等しく、我が子らの記憶から消えたらそれっきり。私の人生はこの小犬と何ら変わらない。それを知っていても私も彼女と同じく、毎日の食事を楽しみ、やはり今日を生きている。徹頭徹尾凡人であった私の人生に意味などあるはずもない。それでも笑ったり泣いたり怒ったり、感動したり、感謝したり、恨んだり。こんな私でさえ思い起こせばドラマチックな場面はいくらでも湧いてくる。だからといってそこに意味はない。でもそれでいいんだとしたら、人生は何かを残すためではなく、味わうためのものだと言えるのではないか。様々なことがらを思い出すたび、二度と戻らぬ時間と出会いに感傷にひたる自分がいる。

 


幼いころよりキリギリスよりアリの方が偉いと教えられてきたが、毛布の上にくるまって寝ている小犬のしずかな息遣いを見ていると、今はキリギリスも応援したくなる今日この頃である。

 

NASへのバックアップ

新しくNAS(BUFFALO リンクステーション LS710D/N)を買ったので自動でPCのファイルをバックアップできるようセットアップした。

考慮事項は次のとおり。

・バッファローのNAS Navigator2にはフォルダ同期機能はあるものの、動いているのか止まっているのか判別不可でうまく同期しない。
・さらにCUIでも実行できないためWindowsのschtasksで動かすことも不可能。
・BunBackupを使うにはD、パスワードでアクセスできないため、共有フォルダをアクセス制限なしにする必要がある。
・FTPならアクセス制限フォルダでもIDとパスワードを設定してコピーできるのでひとつのオプションではある。

・robocopy:IDとパスワードでアクセスできるし早い。最良策と判断。

 

ということでrobocopyをベースに自動でバックアップする環境を整えることにした。日曜プログラマーの隙間時間作業なので参考にする際は事故責でお願いします。

 

まずはrobocopyを起動するためのバッチファイル

(robocopy_bat.batってひどいネーミングだね)

  1. echo "Backup Procedure Processing by robocopy_bat.bat"
  2. echo %1
  3. set src=%1
  4. set dst=%2
  5. set log=MyLog
  6. net use %dst% /user:<UserName> <Password>
  7.  
  8. robocopy %src% %dst% /s /e /xo /r:1 /w:1 /LOG+:"%log%_Robocopy.log"

 

さて、このベースをどうやって必要なフォルダに対して設定した時刻に自動で起動するようにするか。ということでChat-GPT先生にお尋ねしながら作ったのがdo_robocopy.py。

 

  1. import subprocess
  2. import csv
  3.  
  4. # CSVファイルAからデータを読み込み、条件に合う行を抽出
  5. def extract_data_from_csv(file_a):
  6.     source_folders =
  7.     destin_folders =
  8.     
  9.     with open(file_a, mode='r', encoding='utf-8') as f: # UTF-8-SIGを使用(BOM対応)
  10.         reader = csv.reader(f)
  11.         for row in reader:
  12.             source_folders.append(row[0])
  13.             destin_folders.append(row[1])
  14.     return source_folders, destin_folders
  15.     
  16.  
  17. def exec_robocopy_bat(source_folders, destin_folders):
  18.     for i in range(len(source_folders)):
  19.         try:
  20.             result = subprocess.run(["robocopy_bat.bat",source_folders[i],destin_folders[i]])
  21.             print("result:",result)
  22.         except:
  23.             print("error")
  24.         
  25.     
  26. if __name__=="__main__":
  27.     folder_def_file_name = "copy_folder_def.txt"
  28.     source_folders, destin_folders = extract_data_from_csv(folder_def_file_name)
  29.     exec_robocopy_bat(source_folders, destin_folders)

 

このプログラムが参照するcopy_foloder_def.txtはつぎのような内容のファイルとなっている。

<コピー元フォルダのパス1>,<コピー先フォルダのパス1>

<コピー元フォルダのパス2>,<コピー先フォルダのパス2>

             ・

             ・

             ・

これだけでも動くが、これをschtasksに登録するためのバッチファイル(BackUp.bat)を作っておく。

  1. cd <do_robocopy.pyなどが入ったフォルダへのパス>
  2. del MyLog_Robocopy.log
  3. python do_robocopy.py
  4. pause

 

最後にschtasksを使ってこのバッチファイルをタスクに登録する。

 

  1. schtasks /create /tn "<タスク名>" /tr <バッチファイルへのパス> /sc weekly /d wed /st 18:00

 

さて、これでしばらく運用してみて様子を見よう。

それにしてもChat-GPTが使えるようになって素人のプログラミング環境は劇的に改善した。ありがたいありがたい。