C#SolverFoundation查找长度的最大组合
本文关键字:组合 查找 C#SolverFoundation | 更新日期: 2023-09-27 18:30:08
我有一个括号列表,我需要找到它们的组合,最多4个括号,最适合特定长度。
这些是我的括号,例如,我需要找出在不超过120英寸的情况下,这些括号的组合最接近。
<?xml version="1.0" encoding="utf-8" ?>
<brackets>
<bracket>
<PartNumber>F0402583</PartNumber>
<Length>42.09</Length>
</bracket>
<bracket>
<PartNumber>F0402604</PartNumber>
<Length>32.36</Length>
</bracket>
<bracket>
<PartNumber>F0403826</PartNumber>
<Length>46.77</Length>
</bracket>
<bracket>
<PartNumber>F0402566</PartNumber>
<Length>44.17</Length>
</bracket>
<bracket>
<PartNumber>F0402289</PartNumber>
<Length>20.55</Length>
</bracket>
<bracket>
<PartNumber>F0402612</PartNumber>
<Length>18.46</Length>
</bracket>
<bracket>
<PartNumber>F0402606</PartNumber>
<Length>30.28</Length>
</bracket>
<bracket>
<PartNumber>F0403828</PartNumber>
<Length>22.76</Length>
</bracket>
</brackets>
我试着弄清楚SolverFoundation库,但我不是数学专业的,对它几乎没有经验…使用Excel Solver with Simplex LP求解方法,解决方案是1 30.28"括号,1 42.09"括号和1 46.77"括号,结果是119.14"
这里有一个简单的解决方案。我对数学的理解也很有限(最先进的是组合数学等!),所以我理解挑战。该解决方案遍历所有可能性,然后按有效解决方案(总长度<120的解决方案)进行筛选,按长度对其进行排序,并输出第一个结果。
我相信,如果你的解决方案需要证明对一些数学概念的理解,这不是寻找解决方案的方法,但这将使你能够轻松地检查你的解决方法。
它的运行时间是O(n^c)。
public static void Main(string[] args)
{
var lengths = new List<decimal>(new decimal[] { 42.09m, 32.36m, 46.77m, 44.17m, 20.55m, 18.46m, 30.28m, 22.76m });
var lst = new List<Solution>();
for (int i = 0; i < lengths.Count; i++) {
lst.Add(new Solution(new decimal[] { lengths[i] }));
for (int j = 0; j < lengths.Count; j++) {
lst.Add(new Solution(new decimal[] { lengths[i], lengths[j] }));
for (int k = 0; k < lengths.Count; k++) {
lst.Add(new Solution(new decimal[] { lengths[i], lengths[j], lengths[k] }));
for (int l = 0; l < lengths.Count; l++) {
lst.Add(new Solution(new decimal[] { lengths[i], lengths[j], lengths[k], lengths[l] }));
}
}
}
}
var validSolution = (from sln in lst
where sln.Value <= 120.00m
&& sln.IsValid
select sln).OrderByDescending(sln => sln.Value)
.First();
Console.WriteLine(validSolution);
}
解决方案类别:
public class Solution : IComparable<Solution>
{
public readonly int MaxLengths = 4;
public readonly decimal Value;
public readonly decimal MaxValue = 120.00m;
public readonly bool IsValid;
public readonly decimal[] Lengths;
public Solution(decimal[] lengths)
{
this.Lengths = lengths;
if (lengths.Length > 4)
throw new ArgumentException("Too many lengths.");
foreach (var dec in lengths) {
if (dec <= 0.00m)
throw new ArgumentException();
Value += dec;
}
IsValid = Value < 120.00m;
}
public int CompareTo(Solution other)
{
if (this.Value > other.Value) return 1;
else if (this.Value == other.Value) return 0;
else return -1;
}
public override string ToString()
{
var value = string.Format("[Solution] Lengths:");
foreach (var d in Lengths) {
value += d + ", ";
}
value += this.Value;
return value.ToString();
}
}