Оптимизация с груба сила

Разработвам приложение, което използва приставки, приставките са разработени от независими разработчици. Трябва да оптимизирам параметрите за приставката с груба сила.

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

Но за съжаление не мога да измисля алгоритъм за оптимизиране на параметрите. Под груба сила, имам предвид

въведете описание на изображението тук

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

Този код работи правилно, но за съжаление, ако плъгинът за добавяне на нов параметър, кодът ще се повреди. Трябва да измисля алгоритъм, който не е чувствителен към броя на параметрите. Знам, че мога да използвам рекурсия, но тогава не мога да използвам многопоточност.


person Mitosha    schedule 29.11.2011    source източник
comment
Въпросът ви не е много ясен. Какво искаш да знаеш? Алтернативни методи за оптимизация? Как да тествам груба сила с всички възможни параметри? Как да намерите всички възможни параметри?   -  person Albin Sunnanbo    schedule 29.11.2011
comment
Опитвате ли се да тествате приставките?   -  person ChrisBD    schedule 29.11.2011


Отговори (1)


Ако разбирам правилно, имате нужда от декартови продукти на вашите списъци с параметри.

За да направите декартов продукт, можете да използвате този метод:

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

(от Изчисляване на декартов продукт с LINQ от Ерик Липерт)

След това трябва да създадете от всеки параметър списъците със стойности на параметрите и да приложите декартовия продукт към него. Тъй като изглежда, че се интересувате само от стойностите Start и Stop, можете да направите следното:

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