私は C# でアイデアをいじっています。グラフ内の多数のノードを非同期的に更新する最善の方法についてアドバイスをお願いします。そのようなことを行う方法については何も読んでいません。教科書/例で見たものはすべて、ノードが実際には変化しないグラフを使用しています。
多数のノード (数千) のグラフがあるとします。各ノードには、それぞれの隣接ノードのいくつかのパブリック プロパティに依存するいくつかの内部状態と、場合によってはいくつかの外部入力があります。
したがって、ノードは単純に次のようになります。
class Node
{
State internalState;
public State exposedState;
Input input;
List<Node> neigbors;
void Update()
{
while (true)
{
DoCalculations(input, internalState, neighbors);
exposedState = ExposedState(internalState);
}
}
State ExposedState(State state) { ... }
void DoCalculations() { ... }
}
難しいのは、ノードの入力状態が (イベントのサブスクライブまたはポーリングによって) 変化するか、隣接ノードの状態が変化するとすぐにノードを更新したいということです。これを単純な方法で同期的に実行しようとすると、明らかな問題が発生します。
Node A updates when input changes
Its neighbor B sees A has changed, updates.
Node A sees its neighbor B has changed, updates
B updates
A updates
....
Stack overflows
代わりに、すべてのノードを列挙してそれらの更新メソッドを呼び出して更新すると、ノードが一貫して更新されない可能性があります (例: A の入力が変更され、B が更新され、A の変更が表示されず、A が更新され、公開された状態が変更されます)。
最初に更新したいノードのスタックを維持しようとすることで更新できますが、次にそれらの隣接ノードを更新する必要があり、次にそれらのノードを更新する必要があります。つまり、更新サイクルごとに慎重にグラフを調べて、正しい更新順序、非常に遅くなる可能性があります...
素朴な非同期の方法は、各ノードを独自のスレッドに持つことです (または、より簡単に言えば、最初の非同期メソッド呼び出しが各ノードの update メソッドに対して発生し、while(true){...} で無期限に更新されます)。彼の問題は、何千ものスレッドを持つことは良い考えとは思えないことです!
これには簡単な解決策があるはずです。これはセルオートマトンとそれほど違いはありませんが、私が思いついた同期ソリューションは、一方の端から他方の端までメッセージを取得するためにノードの数と比較して多数回更新する必要があるか、ある種の複雑な問題を解決する必要があります複数の開始点を持つグラフ ウォーキング問題。
非同期メソッドは、数千のスレッドを持つことができれば、自明に単純に思えます...
では、このようなことを行うための最良の方法は何ですか?