次の関数を使用して、すべての可能な操作のセット ({-,-,-,-}、{-、-、-、+}、{-、-、+、-} など) を含むセットを生成できます。 true と false が + と - を表す bool 配列のリストを出力します。vars
パラメータは、結合される変数の数を示します。5つの変数の場合、5つの変数を組み合わせるときに4つの演算子しかないため(最初の変数を否定できないと仮定して)、16の組み合わせしかないことに注意してください(あなたが述べたように32ではありません):
public List<bool[]> GetOperators(int vars)
{
var result = new List<bool[]>();
for (var i = 0; i < 1 << vars-1; i++)
{
var item = new bool[vars - 1];
for (var j = 0; j < vars-1; j++)
{
item[j] = ((i >> j) & 1) != 0;
}
result.Add(item);
}
return result;
}
このリストを取得したら、それを使用して、可能なすべての方法で変数を組み合わせることができます。最初に、一連の変数と単一のbool[]
組み合わせを取得して適用するヘルパー関数を定義します (渡された変数の数の組み合わせに正しい数の要素があると想定しています)。
private double Combine(double[] vars, bool[] combination)
{
var sum = vars[0];
for (var i = 1; i< vars.Length; i++)
{
sum = combination[i - 1] ? sum + vars[i] : sum - vars[i];
}
return sum;
}
次を使用して、組み合わせを適切にフォーマットすることもできます。
private string FormatCombination(double[] vars, bool[] combination)
{
var result = vars[0].ToString("0.00##");
for (var i = 1; i < vars.Length; i++)
{
result = string.Format("{0} {1} {2:0.00##}", result, combination[i - 1] ? "+" : "-", vars[i]);
}
return result;
}
すべてをまとめて、考えられるすべての組み合わせをテストします。
var vars = new []
{
1.23, // A
0.02, // B1
0.11, // B2
0.05, // C1
1.26 // C2
};
foreach (var combination in GetOperators(vars.Length))
{
var combined = Combine(vars, combination);
// Perform your operations on "combined" here...
Console.WriteLine("{0} = {1}", FormatCombination(vars, combination), combined);
}
これは出力されます:
1.23 - 0.02 - 0.11 - 0.05 - 1.26 = -0.21
1.23 + 0.02 - 0.11 - 0.05 - 1.26 = -0.17
1.23 - 0.02 + 0.11 - 0.05 - 1.26 = 0.01
1.23 + 0.02 + 0.11 - 0.05 - 1.26 = 0.05
1.23 - 0.02 - 0.11 + 0.05 - 1.26 = -0.11
1.23 + 0.02 - 0.11 + 0.05 - 1.26 = -0.07
1.23 - 0.02 + 0.11 + 0.05 - 1.26 = 0.11
1.23 + 0.02 + 0.11 + 0.05 - 1.26 = 0.15
1.23 - 0.02 - 0.11 - 0.05 + 1.26 = 2.31
1.23 + 0.02 - 0.11 - 0.05 + 1.26 = 2.35
1.23 - 0.02 + 0.11 - 0.05 + 1.26 = 2.53
1.23 + 0.02 + 0.11 - 0.05 + 1.26 = 2.57
1.23 - 0.02 - 0.11 + 0.05 + 1.26 = 2.41
1.23 + 0.02 - 0.11 + 0.05 + 1.26 = 2.45
1.23 - 0.02 + 0.11 + 0.05 + 1.26 = 2.63
1.23 + 0.02 + 0.11 + 0.05 + 1.26 = 2.67
編集:
あなたの質問への変更により、回答を更新しました。他の人が述べたように、このような完全な検索を使用する必要はないかもしれませんが、とにかくこの方法が役立つ場合があります。
GetOperators()
(以前のように2 n-1ではなく) 2 nの組み合わせを返すようにわずかに変更します。
public List<bool[]> GetOperators(int vars)
{
var result = new List<bool[]>();
for (var i = 0; i < 1 << vars; i++)
{
var item = new bool[vars];
for (var j = 0; j < vars; j++)
{
item[j] = ((i >> j) & 1) != 0;
}
result.Add(item);
}
return result;
}
メソッドは、Combine()
使用される変数と組み合わせに加えて一連のインクリメントを取るように変更されます。組み合わせの各要素について、 の場合true
は増分が変数に追加され、 false の場合は減算されます。
private double[] Combine(double[] vars, double[] increments, bool[] combination)
{
// Assuming here that vars, increments and combination all have the same number of elements
var result = new double[vars.Length];
for (var i = 0; i < vars.Length; i++)
{
result[i] = combination[i] ? vars[i] + increments[i] : vars[i] - increments[i];
}
// Returns an array of the vars and increments combined per the given combination
// E.g. if there are 5 vars and the combination is: {true, false, true, true, false}
// The result will be {var1 + inc1, var2 - inc2, var3 + inc3, var4 + inc4, var 5 - inc5}
return result;
}
またFormatCombination()
、新しい組み合わせスタイルを表示するように更新されます。
private string FormatCombination(double[] vars, double[] increments, bool[] combination)
{
var result = new List<string>(vars.Length);
var combined = Combine(vars, increments, combination);
for (var i = 0; i < vars.Length; i++)
{
result.Add(string.Format("{0:0.00##} {1} {2:0.00##} = {3:0.00##}", vars[i], combination[i] ? "+" : "-", increments[i], combined[i]));
}
return string.Join(", ", result.ToArray());
}
すべてを一緒に入れて:
var vars = new[]
{
1.23, // A
0.02, // B
0.11, // C
0.05, // D
1.26, // E
};
var increments = new[]
{
0.04, // incA
0.11, // incB
0.01, // incC
0.37, // incD
0.85, // incD
};
foreach (var combination in GetOperators(vars.Length))
{
var combined = Combine(vars, increments, combination);
// Perform operation on combined here...
Console.WriteLine(FormatCombination(vars, increments, combination));
}
出力 (要約):
1.23 - 0.04 = 1.19、0.02 - 0.11 = -0.09、0.11 - 0.01 = 0.10、0.05 - 0.37 = -0.32、1.26 - 0.85 = 0.41
1.23 + 0.04 = 1.27、0.02 - 0.11 = -0.09、0.11 - 0.01 = 0.10、0.05 - 0.37 = -0.32、1.26 - 0.85 = 0.41
1.23 - 0.04 = 1.19、0.02 + 0.11 = 0.13、0.11 - 0.01 = 0.10、0.05 - 0.37 = -0.32、1.26 - 0.85 = 0.41
1.23 + 0.04 = 1.27、0.02 + 0.11 = 0.13、0.11 - 0.01 = 0.10、0.05 - 0.37 = -0.32、1.26 - 0.85 = 0.41
...