2

私は単純な進化的アルゴリズムに取り組んでいます。

使い方:

すべてのセルが空白、植物、草食動物のいずれかであるグリッド マップがあります。植物と草食動物は生き物なので (植物はそうではありません)、どちらもエネルギーと色を持っています。クリーチャーは数ミリ秒ごとに処理を行います (タイマーが起動したとき)。植物は絶えずエネルギーを充電しますが、草食動物はエネルギーを失います。植物が完全に再充電されると、ランダムな方向 (北、南、東、または西) を見て、その方向の隣接セルが空白の場合、植物はそのセルに繁殖します。草食動物は植物を食べることでエネルギーを回復します。草食動物が何かをする番になると、ランダムに隣接するセルを調べます。空の場合、草食動物はそこに移動します。それが植物であれば、草食動物はそれを食べてそこに移動しようとします。草食動物の色が植物の色に近いほど、草食動物が成功する可能性が高くなります。草食動物はエネルギーが 0 になると死亡します。草食動物が最大エネルギーに達すると、繁殖も行います。子孫は常に親とはわずかに異なる色をしています。

ここに写真があります:

ここに画像の説明を入力

これは、内部から食べられている多くの植物です。

しばらくすると、システムは正常化します。

ここに画像の説明を入力

大きな斑点が消え、いつでもいくつかの色が現れます。もちろん、これは想定内です。

だから、私は今働くプログラムを持っています。しかし、シングルスレッドで実行されているので、マルチスレッド化したいと考えています。マップ上のすべてのセルにスレッドを作成するところまで行く予定です。

やり過ぎなのはわかっているけど、とにかくやりたい。そうすれば、これらの小さなアトミックピースである細胞を手に入れることができ、それらはすべて非同期で動作し、まるでパズルのピースを組み立てるかのように、その場で相互に接続することができます.

それが基本的な考え方です。細胞をできるだけ自律的にしたい。私はこれを実装しようとしました:私はすべてのセルにスイングタイマーを作成し、タイマーが起動すると、セルが動作するスレッドを開始しました。複数のネイバーが同じセルにアクセスしようとします。これの問題は、セルが何かをしようとするたびに新しいスレッドが呼び出されることです。これは非常にリソースを消費することを知っているので(直接の経験)、どうにかしてすべてのセルに対して永続的なスレッドを作成したいと考えています。各スレッドは、独自のセルのタイマー、アクション リスナーを処理し、タイマーが起動したときにそのセルのアクションを実行します。これらのスレッドは、基本的に停止することはありません。このようなシステムを実装する方法がわからないので、これについて助けが必要です。

編集:質問を明確にする:タイマーイベントをリッスンし、タイマーが起動したときに何かを実行するスレッドの例が必要です。これはすべてスレッド内で発生するはずです。

4

4 に答える 4

2

sの数を増やすことは、ThreadCPU コアを増やす場合にのみ意味があると思います。ハイパースレッディングを考慮に入れることができます。たとえば、HT が有効なクアッドコア CPU を使用している場合、同時に 8Thread秒を処理できます。

もう1つのことは、これは通常別の方法で行われるということです. 10 個のオブジェクト (植物、草食動物など) があるとします。それぞれに のようなメソッドがありcalculateNextState()ます。10 個のオブジェクトのループ内のすべての状態を計算するだけで済み、それらすべての新しい状態が得られたら、GUI を更新します。あなたはこれを無限に行います。計算にかかった時間を考慮するだけでよいため、タイマーは必要ありません。

例:

10 単位の速度 (x 軸上) で移動する草食動物がいます。その位置は前回(2,4)の計算から経過した時間で、200msです。その位置を に更新します。等々...now()(4,4)

並列化に関しては、 a を作成してs をそれにThreadPoolプッシュできます。RunnableそれぞれRunnableは、実際には次の状態を計算するための関数ですGameObject(私はあなたが持っているクリーチャーに名前を付けただけです)。すべてThreadPoolの が作業を終了したら、GUI を更新できます。

主なことは、計算に固定時間を設定すると、設定した時間よりも時間がかかる可能性があるため、GUI で任意の数のオブジェクトを実際に更新することはできないということです

例: 「1 秒ごとに 1 更新したい」と言うが、5.000.000 オブジェクトがある場合、計算に 2 秒かかる場合があります。そのため、私が説明したモデルを使用することをお勧めします。スレッド間で作業を分散できるように、すべての状態計算は並列化できる必要があります。

ただし、注意点があります。2 つの異なる植物/草食動物が、前の計算後に空だった同じセルに展開しようとする場合を考慮する必要があります。

于 2013-10-12T16:23:20.200 に答える
1

私自身の答えを書くこともできます。

まず第一に、純粋なエンティティごとのスレッド、タイマーベースのアプローチを使用して、シミュレーションの世界を正確に表現することはできません

理由は次のとおりです。

ワールドモデルとCPUモデル

もちろん、左側はワールド モデルであり、右側は実装の単純化されたスレッド モデルであり、アプローチに基づいています。

ここで、指摘すべき重要な点は次のとおりです。

  • シミュレーションモデル で:
    1. 各エンティティの状態は完全に内部化されています。草食動物や植物などには、それ自体が機能するために必要なすべての情報が含まれています。
    2. すべてのエンティティは自律的です。エンティティは、他の何かが動いているか、食べられているかなど、または他のエンティティが同時に何個あるかを気にしません。
    3. すべてのエンティティはリアルタイムで動作します。それらが内部状態に従ってどのように見えるかは、それらが世界でどのように見えるかです。
  • 実際の実装モデルでは:
    1. メインメモリにはグローバルな状態があります。すべてのエンティティは、スレッドのローカル状態をグローバル状態と同期する必要があります。そうしないと、矛盾が発生します。
      • エンティティ スレッドは、限られた CPU リソースをめぐって競合します。スレッドはいつでも非アクティブ状態にすることができます。「あなたの」スレッドでさえ起動できません! 他に実行中のスレッドの数が非常に重要になります
      • エンティティ スレッドは、メイン メモリ アクセスを競合します。1 つのスレッドが共通ロックをロックすると、もう 1 つのスレッドはロックが解除されるまで待機する必要があります。
    2. エンティティ スレッドは、その表示方法 (つまり、GUI ビューア) から完全に切り離されて動作します。

この 3 点だけで、モデルに互換性がないことは明らかだと思います。

ワールド モデルをスレッド モデルに適合させようとするかもしれませんが、そうすると、実装に合わせてワールドを変更するという問題に直面することになります。たとえば、あなたが言及したロック-アプローチに応じて、世界の仕組みが変わります。

もちろん、この特定のケースでこれで問題ない場合は、先に進んでください(つまり、通常、膨大な数のスレッドに伴う速度の低下や、それに伴うすべての素晴らしい問題にも問題がないことを意味します)。同期)。

ただし、一般的には、仕様に従って実装を選択する必要があり、その逆ではありません。

上記に注意すれば、多くのオプションがあります。そのほとんどは、Adam Aroldによって記述され、 clwhiskによって洗練された個別のシミュレーション ステップに依存しています。これらのモデルは次のとおりです。

  • ThreadPoolExecutorまたはForkJoinPoolを使用して作業単位を処理する限られた数のワーカー スレッド
  • グリッド モデルを一連の方程式としてエンコードし、
  • などなど
于 2013-10-12T18:44:16.977 に答える
0

永続スレッドが何を意味するのかを定義していません。

プロセスのようなスレッドは、現在のマシンとオペレーティング システムでは永続的ではありません(アプリケーションのチェックポイントについて読んでください)。たとえば、Javaの意味でシリアライズ可能ではありません。

(スレッドではなく) 計算の持続性の独自の実装を実装する必要があります。継続渡しスタイルでプログラムを設計すると役立つ場合があります。永続的な計算の独自の概念を持ちます (たとえば、各スレッドで小さなループを実行し、その状態が永続的でシリアライズ可能であることによって)。

数千 (または数百) のスレッドがあるとは考えないでください。それらは高価なリソースです。小さなスレッド プール(多くても数十スレッド) を用意することを検討してください。スレッド プールのサイズは構成可能である必要があり、データ (または計算している問題) のサイズに依存してはなりません。

futures と promisesの観点から考えたい場合があります。たとえば、Java futures (小さなサイズのスレッド プールでスレッドを共有する) などです。

于 2013-10-12T16:19:05.577 に答える