蛮力优化

时间:2011-11-29 09:27:09

标签: c# optimization plugins brute-force

我正在开发一个使用插件的应用程序,插件是由独立开发人员开发的。我需要使用强力来优化插件的参数。

public class Parameter
{
    public double Start { get; set; }
    public double Step { get; set; }
    public double Stop { get; set; }
    public double Value { get; set; }
}

public class Plugin
{
    public List<Parameter> Parameters { get; private set; }

    public Plugin()
    {
        Parameters = new List<Parameter>()
        {
            new Parameter() { Start = 1, Step = 1, Stop = 2 },
            new Parameter() { Start = 3, Step = 1, Stop = 4 }
        };
    }

    public void Execute()
    {
        double sum = 0;
        foreach (var parameter in Parameters)
        {
            sum += parameter.Value;
        }
        Console.WriteLine("Sum = " + sum);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var test = new Plugin();
        test.Parameters[0].Value = test.Parameters[0].Start;
        test.Parameters[1].Value = test.Parameters[1].Start;
        test.Execute();
        Console.ReadLine();
    }
}

但遗憾的是我无法发明参数优化算法。 蛮力,我的意思是

enter image description here

Parameter1 = 1
Parameter2 = 3

Parameter1 = 1
Parameter2 = 4

Parameter1 = 2
Parameter2 = 3

Parameter1 = 2
Parameter2 = 4

主要问题在于插件中的参数数量可以是任意数量。 也许你可以建议在这种情况下使用哪种算法。

P.S。:对不起我的英语不好。

- - - - 加成--------

换句话说。

我做了一个新的例子,说明我想做什么。

class Program
{
    static void Main(string[] args)
    {
        var test = new Plugin();

        for (double parameter_0 = test.Parameters[0].Start; parameter_0 <= test.Parameters[0].Stop; parameter_0+= test.Parameters[0].Step)
        {
            for (double parameter_1 = test.Parameters[1].Start; parameter_1 <= test.Parameters[1].Stop; parameter_1 += test.Parameters[1].Step)
            {
                test.Parameters[0].Value = parameter_0;
                test.Parameters[1].Value = parameter_1;
                test.Execute();
            }
        }
        Console.ReadLine();
    }
}

public class Plugin
{
    public List<Parameter> Parameters { get; private set; }

    public Plugin()
    {
        Parameters = new List<Parameter>()
        {
            new Parameter() { Start = 1, Value = 1, Step = 1, Stop = 2 },
            new Parameter() { Start = 3, Value = 3, Step = 1, Stop = 4 }
        };
    }

    public void Execute()
    {
        Console.WriteLine(Convert.ToString(Parameters[0].Value) + " " + Convert.ToString(Parameters[1].Value));
    }
}

此代码可以正常工作,但不幸的是,如果添加新参数的插件代码将中断。我需要发明一种对参数数量不敏感的算法。 我知道我可以使用递归但是我不能使用多线程。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您需要参数列表中的笛卡尔积。

要制作笛卡尔积,您可以使用此方法:

static IEnumerable<IEnumerable<T>> 
              CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
  IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
  return sequences.Aggregate( 
    emptyProduct, 
    (accumulator, sequence) => 
      from accseq in accumulator 
      from item in sequence 
      select accseq.Concat(new[] {item})); 
}

(来自Eric Lippert的Computing a Cartesian Product with LINQ

然后,您需要在每个参数中创建参数值列表,并将笛卡尔积应用于它。由于看起来您只对Start和Stop值感兴趣,因此您可以执行以下操作:

var combinations = 
    CartesianProduct<double>(parameters.Select(x=> new [] {x.Start, x.Stop});