0

在 C# 中,我编写了一个为 CAD 程序 (Rhino) 创建几何图形的遗传算法。该算法包含在一个库中,我为 CAD 程序编写了一个小型 Windows 窗体插件。调用 GA.run() 函数将返回一个列表,该列表填充一个列表框,选择一个项目将在 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.运行():

   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

尽管您可以Application.DoEvents在循环中执行某些操作,但最好让该代码在 aTaskBackgroundWorker中运行。其中任何一个都将启动在单独线程上运行的遗传算法,使表单保持活动状态。然后,您可以拥有一个Cancel停止后台处理的按钮。

BackgroundWorker完全支持取消并定期向表单报告进度。查看该页面上的示例。我想它会做你想要的。

有人说这Task是一个更好的解决方案,因为它使用了新的线程模型。一般来说,Task这是我用于生产程序的,因为它有一些我觉得有用的其他选项,但BackgroundWorker工作得很好。

于 2013-03-02T14:46:32.730 回答
1

有一种方法可以使您的 CA 处于紧密循环中。Windows 消息泵未执行,因此要说用户刚刚单击了取消按钮,您必须在 GA 循环中调用 DoEvents,然后轮询已单击取消的标志。相信我,你不想这样做,它效率低下、脆弱、凌乱,而且单元测试完全是 PIA。

你需要的是一个线程。您还需要决定您的表格是否可以在 GA 工作时使用。如果不只是模态地抛出一个“工作......”风格的表格并在其上放置一个 cacle 按钮。那在你的 UI 线程中,所以它会得到点击,然后你停止 GA 线程。

线程还有很多东西,但是.Net 有一些很好的东西可以用来处理这些东西。BackgroundWorker 将是一个很好的查找。

于 2013-03-02T14:56:44.057 回答