mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-10-27 02:41:06 -04:00
fix(flatbar): stop the swap optimization trading identical copies
TryImprove kept a swap when the trial run looked fuller than before, but the trial charges each type's self-nesting gain again even when the run already holds that type. Trading a placed copy for an identical unplaced one therefore looked fuller by the gain and repeated forever: FlatBar ran into the benchmark's 5-minute timeout on tabbed_cog_layout once the all-edges MBR fix gave one part new rotations (it finished in 7 s before). The swap is now judged on the merged run, so every kept swap really leaves the run fuller and the loop terminates. Swaps the old test kept that do fill the run are still kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
059a873d32
commit
f901840ed0
2 files changed
+38
-1
No files matched your search
@@ -0,0 +1,31 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using OpenNest.Engine.NestingEngines.FlatBar;
|
||||
|
||||
namespace OpenNest.Engine.Tests.NestingEngines;
|
||||
|
||||
public class BarPackerTests
|
||||
{
|
||||
[Fact]
|
||||
public void SwapOptimizationStopsWhenOnlyIdenticalCopiesRemain()
|
||||
{
|
||||
// One bar holds [6, 1.5, 1.5] with 0.99 free; two 1.5 copies are left over. Trading a
|
||||
// placed copy for an unplaced one changes nothing, but a trial charges the copy's
|
||||
// self-nesting gain again and looked 0.01 fuller, so the swap used to repeat forever.
|
||||
var items = new[]
|
||||
{
|
||||
new BarItem(0, 6, 0, 0),
|
||||
new BarItem(1, 1.5, 0, 0.01),
|
||||
new BarItem(1, 1.5, 0, 0.01),
|
||||
new BarItem(1, 1.5, 0, 0.01),
|
||||
new BarItem(1, 1.5, 0, 0.01),
|
||||
};
|
||||
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
|
||||
|
||||
var plan = BarPacker.Pack(items, [10.0], 1, timeout.Token);
|
||||
|
||||
var bar = Assert.Single(plan.Bars);
|
||||
Assert.Equal(new[] { 0, 1, 1 }, bar.Items.Select(i => i.Type).OrderBy(t => t));
|
||||
Assert.Equal(2, plan.Unplaced.Count);
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,13 @@ internal static class BarPacker
|
||||
trial.Items.Add(next);
|
||||
}
|
||||
|
||||
if (trial.Remaining < before)
|
||||
// Judge the swap on the merged run: the trial charges gains again for types the
|
||||
// run already holds, so trading a copy for an identical one looks fuller and the
|
||||
// swap would repeat forever.
|
||||
var merged = new PackedSegment(segment.Capacity);
|
||||
merged.Items.AddRange(segment.Items);
|
||||
merged.Items.AddRange(trial.Items);
|
||||
if (merged.Remaining < before)
|
||||
{
|
||||
remaining.Add(removed);
|
||||
segment.Items.AddRange(trial.Items);
|
||||
|
||||
Reference in new issue
Block a user