0

C# で、CAD プログラム (Rhino) のジオメトリを作成する遺伝的アルゴリズムを作成しました。このアルゴリズムはライブラリに含まれており、CAD プログラム用の小さな Windows フォーム プラグインを作成しました。GA.run() 関数を呼び出すと、ListBox に入力する List が返され、Item を選択すると、CAD プログラムでジオメトリが生成されます。

Windows フォーム アプリケーションで GA クラスのインスタンスを作成し、開始ボタンをクリックすると、さまざまな GA 設定がフォームから収集され、GA.run() 関数が呼び出されます。さて、これは遺伝的アルゴリズムであるため、元に戻るまでに何世代も実行されます。ただし、すべての世代を実行する前に関数を停止するオプションが必要です。プラグイン内から GA.run() 関数を停止するにはどうすればよいですか? 実行ボタンを押すと、Windows フォーム アプリケーションは GA.run() がそのリストを返すまで「一時停止」します...

GA.run() を呼び出すより良い方法があると思いますか? ..

停止ボタンのコード:

private void runBtn_Click(object sender, EventArgs e)
{
    // get rule settings
    SettingsHolder gaSettings = new SettingsHolder();
    gaSettings.GenMaxrun = (int)gensNUD.Value;
    ..

    gaAlgo = new GA(algoSettings);

    try
    {
        currentPopulation = paretoAlgo.run();
    }
    catch(Exception e)
    {
        MessageBox.Show("exc while trying run: " + e);
    }

    // iterate list and list in form
    popLB.Items.Clear();
    foreach (Chromosome c in currentPopulation)
    {
        popLB.Items.Add(new KeyValuePair<String, int> (c.present(), id));
    }
}

GA.run():

   public List<Chromosome> run()
    {
        try
        {
            initPop();

            // loop until genMaxrun or no new achieved
            do
            {
                // create geometries from chromosomes
                foreach (Chromosome chromo in population)
                {
                    chromo.embryogeny(Settings);
                }

                // step 2:Fitness

                // union the population and archive
                unionPop = new List<Chromosome>(population);
                unionPop.AddRange(archive);

                calculateDomination(unionPop);

                foreach(Chromosome chromo in unionPop)
                {
                    chromo.calculateRawFitness(unionPop);
                    chromo.calculateDensity(unionPop);
                    chromo.setFitness();
                }

                environmentalSelection();

                // increase Generation +1
                generation += 1;

                // create new population...
                population = reproduction(generation);                    
            }
            while (generation < Settings.GenMaxrun);

        }
        catch (Exception e)
        {
           throw new Exception("Error in SPEA run", e);
        }

        return archive;
    }

run() の while ループ内にチェックを追加する方法はありますか? フォーム アプリケーションの停止ボタン クリック イベントで GA のパラメータを変更できますか (run() 関数を実行しているため)、run() 関数は中止されますか? または、GA.run() から呼び出し元のパラメーターまでチェックできますか? または、スレッドを使用する必要がありますか?

もっと正確に説明する必要がある場合はお知らせください。

乾杯、エイリック

4

2 に答える 2

1

あなたの CA がタイトなループに陥っていることを確認する方法があります。Windows メッセージ ポンプが実行されていないため、ユーザーが [キャンセル] ボタンをクリックしたと言うには、GA ループ内で DoEvents を呼び出し、[キャンセル] がクリックされたことを示すフラグをポーリングする必要があります。あなたがそれをしたくないと信じてください。それは非効率的で、壊れやすく、面倒で、単体テストの完全なPIAです。

必要なのはスレッドです。また、GA が作業を行っている間にフォームを使用できるかどうかを決定する必要があります。「作業...」スタイルのフォームをモーダルにスローして、その上にcacleボタンを配置するだけではない場合。これは UI スレッドにあるため、クリックを取得してから GA スレッドを停止します。

スレッド化には他にも多くの機能がありますが、.Net には、この作業を開始するための優れた機能がいくつかあります。BackgroundWorker は、調べるのに適したものです。

于 2013-03-02T14:56:44.057 に答える
1

Application.DoEventsループ内で何かを行うことはできますが、そのコードを aTaskまたはBackgroundWorkerで実行することをお勧めします。いずれも別のスレッドで遺伝的アルゴリズムの実行を開始し、フォームをアクティブのままにします。その後Cancel、バックグラウンド処理を停止するボタンを設定できます。

BackgroundWorkerキャンセルを完全にサポートし、定期的にフォームに進行状況を報告します。そのページの例を確認してください。私はそれがあなたが望むことをすると思います。

Task新しいスレッド モデルを使用しているため、より良い解決策であると言う人もいます。一般に、Task私が実稼働プログラムに使用するのは、便利だと思う他のオプションがいくつかあるためですが、問題なくBackgroundWorker動作します。

于 2013-03-02T14:46:32.730 に答える