我正在开发一个使用插件的应用程序,插件是由独立开发人员开发的。我需要使用强力来优化插件的参数。
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));
}
}
此代码可以正常工作,但不幸的是,如果添加新参数的插件代码将中断。我需要发明一种对参数数量不敏感的算法。 我知道我可以使用递归但是我不能使用多线程。
答案 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});