HN 日本語サマリー

← 一覧へ戻る
プログラミング

友達と敵とのダンス:ボイドの群知能

Dancing with friends and enemies: boids' swarm intelligence (community.wolfram.com)

43 pointsby surprisetalk5 コメント

要約

この記事は、Wolfram言語を使用して、個々のエージェントが「友達」に向かって動き、「敵」から離れるという単純なルールに従うことで、複雑な群れの行動(ボイドの群知能)をシミュレーションするプログラムを紹介しています。各エージェントは中心に向かって収縮し、ランダムな間隔で友達と敵を再選択することで、動的な均衡と興味深いパターンが生まれます。このシミュレーションは、動物の群れの行動を説明する単純な局所的ルールという考え方を視覚的に探求したものです。

全文翻訳

友達と敵とのダンス:ボイドの群知能 Simon Woods 14年前に投稿 私が高価な数学ソフトウェアをくだらない娯楽に使う最新の方法はこれです。これを説明する方法を以下に示します。 1000人のダンサーがダンスフロアにランダムな位置をとります。それぞれがランダムに1人の「友達」と1人の「敵」を選びます。各ステップで、すべてのダンサーはフロアの中心に向かって0.5%移動し、次に友達に向かって大きく一歩、敵から離れて小さく一歩進みます。ランダムな間隔で、1人のダンサーが友達と敵を再選択します。ランダム性が意図的に注入されます。これがダンスです... n = 1000; r := RandomInteger[{1, n}]; f := (#/(.01 + Sqrt[#.#])) & /@ (x[[#]] - x) &; s := With[{r1 = r}, p[[r1]] = r; q[[r1]] = r]; x = RandomReal[{-1, 1}, {n, 2}]; {p, q} = RandomInteger[{1, n}, {2, n}]; Graphics[{PointSize[0.007], Dynamic[If[r < 100, s]; Point[x = 0.995 x + 0.02 f[p] - 0.01 f[q]]]}, PlotRange -> 2] アニメーション付きで私の代わりにこれを投稿してくれたVitaliyに感謝します :-) 背景:私はどこかで、動物の群れ(カラスの群れやニシンの群れなどを考えてください)のマクロスケールの行動は、各個体が自分の周囲の非常に単純なルールに従うことによって説明されると読んだことがあります。本質的には1)追いつこうとし、2)衝突しないようにする、というルールです。私はMathematicaでこのアイデアを試してみましたが、各粒子の最も近い近傍を特定するのはかなり遅かったです。そこで、各粒子が近接性に関係なく2つの他の粒子の位置に従って行動したらどうなるだろうかと思いました。ルールは単純に一方から離れ、もう一方に向かって移動することでした。 収縮(x = 0.995 x)は、粒子クラウドが無限に拡散したり、原点からドリフトしたりするのを防ぐために追加されました。私は、凝集する傾向と広がる傾向のバランスをとるために、「向かう」と「離れる」のステップサイズを調整しました(ステップサイズが同じだと、ハエの群れのようなものになります)。各粒子の引力と斥力が固定されているため、システムは一種の動的な均衡を見つけます。物事を変化させ続けるために、私は1つの粒子の引力と斥力を定期的に変更するルールを追加しました。最終的な調整は、非常に近い範囲の粒子に対して「力」がゼロに近づくようにすることでした。これは、非常にタイトな塊の形成を停止させるのに役立ち、また、粒子が自分自身を引力または斥力として選択したときのゼロ除算エラーを防ぎます。 システムをダンスとして説明したのは、数学的な言語を使わずに画面上の渦巻くパターンを説明しようとする試みでした。他の単純なルールでどのような「ダンス」が作成できるか見てみたいです。 投稿者:Simon Woods 返信 | フラグ 30件の返信 並べ替え:返信数いいね数最近 3 Kirill Vasin Kirill Vasin, Augsburg University 4ヶ月前に投稿 素晴らしい作品です。13年後、私の3つのコインです。GPUパイプラインを活用するGraphicsComplexをPointの代わりにリアルタイムで使用しており、WLJS Notebookフロントエンドで動作します。 ビデオをアップロードできなかったので、リンクを貼ります。 投稿者:Kirill Vasin 返信 | フラグ 0 Richard Gaylord 13年前に投稿 あなたが「くだらない娯楽」と呼ぶものを、社会科学者(社会物理学者を含む)は「真剣な研究」と呼びます。私はあなたの説明を好みますが、私の意見では、ほとんどの社会科学シミュレーションは、研究(彼らがそうしているように)と見なされる場合、ばかげた疑似科学として特定されるべきです。 投稿者:Richard Gaylord 返信 | フラグ 0 Mohamed Zaghloul Mohamed Zaghloul, ETH Zurich 13年前に投稿 @Jari Kirma: 素晴らしい、どうもありがとう 投稿者:Mohamed Zaghloul 返信 | フラグ 2 Jari Kirma 13年前に投稿 @MohamedZaghloul: 以下のようにフレームごとのデータをエクスポートできます。この場合、100フレームです。 n = 1000; r := RandomInteger[{1, n}]; f := (#/(.01 + Sqrt[#.#])) & /@ (x[[#]] - x) &; s := With[{r1 = r}, p[[r1]] = r; q[[r1]] = r]; x = RandomReal[{-1, 1}, {n, 2}]; {p, q} = RandomInteger[{1, n}, {2, n}]; Scan[If[r < 100, s]; Export["swarm_" <> ToString@# <> ".dat", x = 0.995 x + 0.02 f[p] - 0.01 f[q]] &, Range[100]] これにより、swarm_1.dat、swarm_2.dat、... swarm_100.datというファイルが生成されます。 エクスポートの形式は、ファイル拡張子(この場合はTable形式の".dat")、またはExportの3番目のパラメータによって決定されます(ドキュメントを参照)。 このような一連のファイルを再生することもできますが、この方法では少し遅くなるかもしれません。 i = 1; p = {}; Graphics[{PointSize[0.007], Dynamic[With[{f = "swarm_" <> ToString@i <> ".dat"}, If[FileExistsQ[f], i++; p = Point[Import[f]], p]]]}, PlotRange -> 2] 投稿者:Jari Kirma 返信 | フラグ 0 Safi Ahmed Safi Ahmed, National University of Sciences and Technology (NUST) 13年前に投稿 すごい!!! 投稿者:Safi Ahmed 返信 | フラグ 4 Bernat Espigulé Bernat Espigulé, Universitat de Barcelona 14年前に投稿 Manipulateの改善、2D/3Dタブ、カラー スタイル、方程式ラベル...お楽しみください! TabView[{"2D" -> Manipulate[n = 1000; r := RandomInteger[{1, n}]; f := (#/(.01 + Sqrt[#.#])) & /@ (x[[#]] - x) &; s := With[{r1 = r}, p[[r1]] = r; q[[r1]] = r]; x = RandomReal[{-1, 1}, {n, 2}]; {p, q} = RandomInteger[{1, n}, {2, n}]; Graphics[{Opacity[opacity], PointSize[size], Dynamic[If[r < 200, s]; Point[y = x; x = c*x + ps*f[p] - qs*f[q], VertexColors -> (ColorData[col][color*Norm[#]] & /@ (x - y))]]}, PlotRange -> Range, ImageSize -> {700, 600}, Background -> Black], Delimiter, Style[" 2D Dancing with friends and enemies", Bold, Large], Delimiter, Style["Equation x = c x + ps f[p] - qs f[q] where \!\(\*FormBox[\(\(f[a] = \*FractionBox[\((a - x)\), \(0.01 + \*SqrtBox[\(\(a - \x)\) . \((a - x)\)\)]\)]\)\), TraditionalForm]\) ", Bold, Medium], Delimiter, Dynamic[Graphics[{Style[ Text@TraditionalForm@ Style[Row[{"x = ", c "x + ", ps " f[p] -", qs "f[q]"}]], 15]}, ImageSize -> {240, 50}]], Delimiter, Style["Step towards their friend", Bold, Medium], {{ps, 0.02, "Step Size ps"}, 0, 1,Appearance -> "Open"}, Delimiter, Style["Step away from their enemy", Bold, Medium], {{qs, 0.01, "Step Size qs"}, 0, 1, Appearance -> "Open"}, Delimiter, {{c, 0.995, "Contraction c"}, 0.5, 1.1, Appearance -> "Open"}, Delimiter, {{size, 0.015, "Point Size"}, 0.001, 0.05}, {{Range, 1, "Plot Range"}, 0.1, 5}, {{opacity, 1, "Opacity"}, 0.1, 1}, {{color, 62, "Color Scale"}, 0, 100}, Control[{{col, "SolarColors", "Color Style"}, (# -> Row[{Show[ColorData[#, "Image"], ImageSize -> 100], Spacer[10], #}]) & /@ ColorData["Gradients"], PopupMenu}], ControlPlacement -> Left], "3D" -> Manipulate[n = 1000; r := RandomInteger[{1, n}]; f3d := (#/(.01 + Sqrt[#.#])) & /@ (x3d[[#]] - x3d) &; s := With[{r1 = r}, p[[r1]] = r; q[[r1]] = r]; x3d = RandomReal[{-1, 1}, {n, 3}]; {p, q} = RandomInteger[{1, n}, {2, n}]; Graphics3D[{Opacity[opacity], PointSize[size], Dynamic[If[r < 200, s]; Point[y = x3d; x3d = c*x3d + ps*f3d[p] - qs*f3d[q], VertexColors -> (ColorData[col][color*Norm[#]] & /@ (x3d - y))]]}, PlotRange -> Range, ImageSize -> {700, 600}, Background -> Black, Boxed -> boxed], Delimiter, Style[" 3D Dancing with friends and enemies", Bold, Large], Delimiter, Style["Equation x = c x + ps f[p] - qs f[q] where \!\(\*FormBox[\(\(f[a] = \*FractionBox[\((a - x)\), \(0.01 + \*SqrtBox[\(\(a - \x)\) . \((a - x)\)\)]\)]\)\), TraditionalForm]\) ", Bold, Medium], Delimiter, Dynamic[Graphics[{Style[ Text@TraditionalForm@ Style[Row[{"x = ", c "x + ", ps " f[p] -", qs "f[q]"}]], 15]}, ImageSize -> {240, 50}]], Delimiter, Style["Step towards their friend", Bold, Medium], {{ps, 0.02, "Step Size ps"}, 0, 1, Appearance -> "Open"}, Delimiter, Style["Step away