Refactored BestCombination.FindFrom2
This commit is contained in:
@@ -6,99 +6,110 @@ namespace SawCut
|
|||||||
{
|
{
|
||||||
public static BestComboResult FindFrom2(double length1, double length2, double stockLength)
|
public static BestComboResult FindFrom2(double length1, double length2, double stockLength)
|
||||||
{
|
{
|
||||||
var result = new BestComboResult();
|
var result = InitializeResult(length1, length2);
|
||||||
result.Item1Length = length1;
|
|
||||||
result.Item2Length = length2;
|
|
||||||
|
|
||||||
stockLength += Tolerance.Epsilon;
|
stockLength += Tolerance.Epsilon;
|
||||||
|
|
||||||
if (length1 > stockLength)
|
if (length1 > stockLength)
|
||||||
{
|
{
|
||||||
if (length2 > stockLength)
|
if (length2 > stockLength)
|
||||||
{
|
|
||||||
//throw new Exception($"Either {nameof(length1)} or {nameof(length2)} must be less than or equal to the {nameof(stockLength)}");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
result.Item1Count = 0;
|
return CalculateSingleItemResult(result, length2, stockLength, false);
|
||||||
result.Item2Count = (int)Math.Floor(stockLength / length2);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
else if (length2 > stockLength)
|
||||||
if (length2 > stockLength)
|
|
||||||
{
|
{
|
||||||
result.Item1Count = (int)Math.Floor(stockLength / length1);
|
return CalculateSingleItemResult(result, length1, stockLength, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CalculateOptimalCombination(result, length1, length2, stockLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BestComboResult InitializeResult(double length1, double length2)
|
||||||
|
{
|
||||||
|
return new BestComboResult
|
||||||
|
{
|
||||||
|
Item1Length = length1,
|
||||||
|
Item2Length = length2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BestComboResult CalculateSingleItemResult(BestComboResult result, double length, double stockLength, bool isItem1)
|
||||||
|
{
|
||||||
|
if (isItem1)
|
||||||
|
{
|
||||||
|
result.Item1Count = (int)Math.Floor(stockLength / length);
|
||||||
result.Item2Count = 0;
|
result.Item2Count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Item1Count = 0;
|
||||||
|
result.Item2Count = (int)Math.Floor(stockLength / length);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static BestComboResult CalculateOptimalCombination(BestComboResult result, double length1, double length2, double stockLength)
|
||||||
|
{
|
||||||
var maxCountLength1 = (int)Math.Floor(stockLength / length1);
|
var maxCountLength1 = (int)Math.Floor(stockLength / length1);
|
||||||
|
|
||||||
result.Item1Count = maxCountLength1;
|
result.Item1Count = maxCountLength1;
|
||||||
result.Item2Count = 0;
|
result.Item2Count = 0;
|
||||||
|
|
||||||
var remnant = stockLength - maxCountLength1 * length1;
|
var remnant = stockLength - maxCountLength1 * length1;
|
||||||
|
|
||||||
if (remnant.IsEqualTo(0))
|
|
||||||
return result;
|
|
||||||
|
|
||||||
for (int countLength1 = 0; countLength1 <= maxCountLength1; ++countLength1)
|
for (int countLength1 = 0; countLength1 <= maxCountLength1; ++countLength1)
|
||||||
{
|
{
|
||||||
var remnant1 = stockLength - countLength1 * length1;
|
var remnant1 = stockLength - countLength1 * length1;
|
||||||
|
|
||||||
if (remnant1 >= length2)
|
if (remnant1 >= length2)
|
||||||
{
|
remnant = UpdateResultForTwoItems(result, length2, remnant1, remnant, countLength1);
|
||||||
var countLength2 = (int)Math.Floor(remnant1 / length2);
|
|
||||||
var remnant2 = remnant1 - length2 * countLength2;
|
|
||||||
|
|
||||||
if (!(remnant2 < remnant))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
result.Item1Count = countLength1;
|
|
||||||
result.Item2Count = countLength2;
|
|
||||||
|
|
||||||
if (remnant2.IsEqualTo(0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
remnant = remnant2;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
remnant = UpdateResultForOneItem(result, remnant1, remnant, countLength1);
|
||||||
if (!(remnant1 < remnant))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
result.Item1Count = countLength1;
|
if (remnant.IsEqualTo(0))
|
||||||
result.Item2Count = 0;
|
|
||||||
|
|
||||||
if (remnant1.IsEqualTo(0))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
remnant = remnant1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static double UpdateResultForTwoItems(BestComboResult result, double length2, double remnant1, double currentRemnant, int countLength1)
|
||||||
|
{
|
||||||
|
var countLength2 = (int)Math.Floor(remnant1 / length2);
|
||||||
|
var remnant2 = remnant1 - countLength2 * length2;
|
||||||
|
|
||||||
|
if (remnant2 < currentRemnant)
|
||||||
|
{
|
||||||
|
result.Item1Count = countLength1;
|
||||||
|
result.Item2Count = countLength2;
|
||||||
|
return remnant2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRemnant;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double UpdateResultForOneItem(BestComboResult result, double remnant1, double currentRemnant, int countLength1)
|
||||||
|
{
|
||||||
|
if (remnant1 < currentRemnant)
|
||||||
|
{
|
||||||
|
result.Item1Count = countLength1;
|
||||||
|
result.Item2Count = 0;
|
||||||
|
return remnant1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRemnant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BestComboResult
|
public class BestComboResult
|
||||||
{
|
{
|
||||||
public double Item1Length { get; set; }
|
public double Item1Length { get; set; }
|
||||||
|
|
||||||
public int Item1Count { get; set; }
|
public int Item1Count { get; set; }
|
||||||
|
public double Item1TotalLength => Item1Length * Item1Count;
|
||||||
public double Item1TotalLength
|
|
||||||
{
|
|
||||||
get { return Item1Length * Item1Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public double Item2Length { get; set; }
|
public double Item2Length { get; set; }
|
||||||
|
|
||||||
public int Item2Count { get; set; }
|
public int Item2Count { get; set; }
|
||||||
|
public double Item2TotalLength => Item2Length * Item2Count;
|
||||||
public double Item2TotalLength
|
|
||||||
{
|
|
||||||
get { return Item2Length * Item2Count; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user