Оптимизация грубой силы - PullRequest
0 голосов
/ 29 ноября 2011

Я разрабатываю приложение, которое использует плагины, плагины разрабатываются независимыми разработчиками. Мне нужно оптимизировать параметры для плагина с помощью грубой силы.

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 Ответ

2 голосов
/ 29 ноября 2011

Если я правильно понимаю, вам нужны декартовы произведения из ваших списков параметров.

Чтобы сделать декартово произведение, вы можете использовать этот метод:

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})); 
}

(из Computingдекартово произведение с LINQ от Eric Lippert)

Затем вам необходимо создать из каждого параметра списки значений параметров и применить к нему декартово произведение.Поскольку, похоже, вас интересуют только значения Start и Stop, вы можете сделать следующее:

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