style: apply CSharpier formatting to all C# sources
Repo-wide sweep with the pinned CSharpier 1.3.0 tool. Whitespace and line-wrapping only; OpenNest.Engine.Tests (109) and OpenNest.IO.Tests pass after reformat, full solution builds 0 errors. Added .csharpierignore so csproj/config XML keeps its existing layout (CSharpier's XML wrapping churns attributes with zero benefit). Formatting is now enforceable: dotnet csharpier check . passes.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
using OpenNest.Engine.Fill;
|
||||
using OpenNest.Geometry;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using OpenNest.Engine.Fill;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.Engine.Nfp
|
||||
{
|
||||
@@ -18,10 +18,14 @@ namespace OpenNest.Engine.Nfp
|
||||
private const double DefaultMinTemperature = 0.1;
|
||||
private const int DefaultMaxNoImprovement = 500;
|
||||
|
||||
public OptimizationResult Optimize(List<NestItem> items, Box workArea, NfpCache cache,
|
||||
public OptimizationResult Optimize(
|
||||
List<NestItem> items,
|
||||
Box workArea,
|
||||
NfpCache cache,
|
||||
Dictionary<int, List<double>> candidateRotations,
|
||||
IProgress<NestProgress> progress = null,
|
||||
CancellationToken cancellation = default)
|
||||
CancellationToken cancellation = default
|
||||
)
|
||||
{
|
||||
var random = new Random();
|
||||
|
||||
@@ -30,7 +34,12 @@ namespace OpenNest.Engine.Nfp
|
||||
var sequence = BuildInitialSequence(items, candidateRotations);
|
||||
|
||||
if (sequence.Count == 0)
|
||||
return new OptimizationResult { Sequence = sequence, Score = default, Iterations = 0 };
|
||||
return new OptimizationResult
|
||||
{
|
||||
Sequence = sequence,
|
||||
Score = default,
|
||||
Iterations = 0,
|
||||
};
|
||||
|
||||
// Evaluate initial solution.
|
||||
var blf = new BottomLeftFill(workArea, cache);
|
||||
@@ -42,20 +51,33 @@ namespace OpenNest.Engine.Nfp
|
||||
var currentScore = bestScore;
|
||||
|
||||
// Calibrate initial temperature so ~80% of worse moves are accepted.
|
||||
var initialTemp = CalibrateTemperature(currentSequence, workArea, cache,
|
||||
candidateRotations, random);
|
||||
var initialTemp = CalibrateTemperature(
|
||||
currentSequence,
|
||||
workArea,
|
||||
cache,
|
||||
candidateRotations,
|
||||
random
|
||||
);
|
||||
var temperature = initialTemp;
|
||||
var noImprovement = 0;
|
||||
var iteration = 0;
|
||||
|
||||
Debug.WriteLine($"[SA] Initial: {bestScore.Count} parts, density={bestScore.Density:P1}, temp={initialTemp:F2}");
|
||||
Debug.WriteLine(
|
||||
$"[SA] Initial: {bestScore.Count} parts, density={bestScore.Density:P1}, temp={initialTemp:F2}"
|
||||
);
|
||||
|
||||
ReportBest(progress, BottomLeftFill.ToNestParts(bestPlaced), workArea,
|
||||
$"NFP: initial {bestScore.Count} parts, density={bestScore.Density:P1}");
|
||||
ReportBest(
|
||||
progress,
|
||||
BottomLeftFill.ToNestParts(bestPlaced),
|
||||
workArea,
|
||||
$"NFP: initial {bestScore.Count} parts, density={bestScore.Density:P1}"
|
||||
);
|
||||
|
||||
while (temperature > DefaultMinTemperature
|
||||
&& noImprovement < DefaultMaxNoImprovement
|
||||
&& !cancellation.IsCancellationRequested)
|
||||
while (
|
||||
temperature > DefaultMinTemperature
|
||||
&& noImprovement < DefaultMaxNoImprovement
|
||||
&& !cancellation.IsCancellationRequested
|
||||
)
|
||||
{
|
||||
iteration++;
|
||||
|
||||
@@ -63,7 +85,10 @@ namespace OpenNest.Engine.Nfp
|
||||
Mutate(candidate, candidateRotations, random);
|
||||
|
||||
var candidatePlaced = blf.Fill(candidate);
|
||||
var candidateScore = FillScore.Compute(BottomLeftFill.ToNestParts(candidatePlaced), workArea);
|
||||
var candidateScore = FillScore.Compute(
|
||||
BottomLeftFill.ToNestParts(candidatePlaced),
|
||||
workArea
|
||||
);
|
||||
|
||||
var delta = candidateScore.CompareTo(currentScore);
|
||||
|
||||
@@ -79,10 +104,16 @@ namespace OpenNest.Engine.Nfp
|
||||
bestSequence = new List<SequenceEntry>(currentSequence);
|
||||
noImprovement = 0;
|
||||
|
||||
Debug.WriteLine($"[SA] New best at iter {iteration}: {bestScore.Count} parts, density={bestScore.Density:P1}");
|
||||
Debug.WriteLine(
|
||||
$"[SA] New best at iter {iteration}: {bestScore.Count} parts, density={bestScore.Density:P1}"
|
||||
);
|
||||
|
||||
ReportBest(progress, BottomLeftFill.ToNestParts(candidatePlaced), workArea,
|
||||
$"NFP: iter {iteration}, {bestScore.Count} parts, density={bestScore.Density:P1}");
|
||||
ReportBest(
|
||||
progress,
|
||||
BottomLeftFill.ToNestParts(candidatePlaced),
|
||||
workArea,
|
||||
$"NFP: iter {iteration}, {bestScore.Count} parts, density={bestScore.Density:P1}"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -111,13 +142,15 @@ namespace OpenNest.Engine.Nfp
|
||||
temperature *= DefaultCoolingRate;
|
||||
}
|
||||
|
||||
Debug.WriteLine($"[SA] Done: {iteration} iters, best={bestScore.Count} parts, density={bestScore.Density:P1}");
|
||||
Debug.WriteLine(
|
||||
$"[SA] Done: {iteration} iters, best={bestScore.Count} parts, density={bestScore.Density:P1}"
|
||||
);
|
||||
|
||||
return new OptimizationResult
|
||||
{
|
||||
Sequence = bestSequence,
|
||||
Score = bestScore,
|
||||
Iterations = iteration
|
||||
Iterations = iteration,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,7 +159,9 @@ namespace OpenNest.Engine.Nfp
|
||||
/// Each NestItem is expanded by its quantity.
|
||||
/// </summary>
|
||||
private static List<SequenceEntry> BuildInitialSequence(
|
||||
List<NestItem> items, Dictionary<int, List<double>> candidateRotations)
|
||||
List<NestItem> items,
|
||||
Dictionary<int, List<double>> candidateRotations
|
||||
)
|
||||
{
|
||||
var sequence = new List<SequenceEntry>();
|
||||
|
||||
@@ -138,7 +173,10 @@ namespace OpenNest.Engine.Nfp
|
||||
var qty = item.Quantity > 0 ? item.Quantity : 1;
|
||||
var rotation = 0.0;
|
||||
|
||||
if (candidateRotations.TryGetValue(item.Drawing.Id, out var rotations) && rotations.Count > 0)
|
||||
if (
|
||||
candidateRotations.TryGetValue(item.Drawing.Id, out var rotations)
|
||||
&& rotations.Count > 0
|
||||
)
|
||||
rotation = rotations[0];
|
||||
|
||||
for (var i = 0; i < qty; i++)
|
||||
@@ -151,8 +189,11 @@ namespace OpenNest.Engine.Nfp
|
||||
/// <summary>
|
||||
/// Applies a random mutation to the sequence.
|
||||
/// </summary>
|
||||
private static void Mutate(List<SequenceEntry> sequence,
|
||||
Dictionary<int, List<double>> candidateRotations, Random random)
|
||||
private static void Mutate(
|
||||
List<SequenceEntry> sequence,
|
||||
Dictionary<int, List<double>> candidateRotations,
|
||||
Random random
|
||||
)
|
||||
{
|
||||
if (sequence.Count < 2)
|
||||
return;
|
||||
@@ -190,13 +231,19 @@ namespace OpenNest.Engine.Nfp
|
||||
/// <summary>
|
||||
/// Changes a random part's rotation to another candidate angle.
|
||||
/// </summary>
|
||||
private static void MutateRotate(List<SequenceEntry> sequence,
|
||||
Dictionary<int, List<double>> candidateRotations, Random random)
|
||||
private static void MutateRotate(
|
||||
List<SequenceEntry> sequence,
|
||||
Dictionary<int, List<double>> candidateRotations,
|
||||
Random random
|
||||
)
|
||||
{
|
||||
var idx = random.Next(sequence.Count);
|
||||
var entry = sequence[idx];
|
||||
|
||||
if (!candidateRotations.TryGetValue(entry.DrawingId, out var rotations) || rotations.Count <= 1)
|
||||
if (
|
||||
!candidateRotations.TryGetValue(entry.DrawingId, out var rotations)
|
||||
|| rotations.Count <= 1
|
||||
)
|
||||
return;
|
||||
|
||||
var newRotation = rotations[random.Next(rotations.Count)];
|
||||
@@ -229,8 +276,11 @@ namespace OpenNest.Engine.Nfp
|
||||
/// </summary>
|
||||
private static double CalibrateTemperature(
|
||||
List<SequenceEntry> sequence,
|
||||
Box workArea, NfpCache cache,
|
||||
Dictionary<int, List<double>> candidateRotations, Random random)
|
||||
Box workArea,
|
||||
NfpCache cache,
|
||||
Dictionary<int, List<double>> candidateRotations,
|
||||
Random random
|
||||
)
|
||||
{
|
||||
const int samples = 20;
|
||||
var deltas = new List<double>();
|
||||
@@ -274,18 +324,25 @@ namespace OpenNest.Engine.Nfp
|
||||
return countDiff * 10.0 + densityDiff;
|
||||
}
|
||||
|
||||
private static void ReportBest(IProgress<NestProgress> progress, List<Part> parts,
|
||||
Box workArea, string description)
|
||||
private static void ReportBest(
|
||||
IProgress<NestProgress> progress,
|
||||
List<Part> parts,
|
||||
Box workArea,
|
||||
string description
|
||||
)
|
||||
{
|
||||
NestEngineBase.ReportProgress(progress, new ProgressReport
|
||||
{
|
||||
Phase = NestPhase.Nfp,
|
||||
PlateNumber = 0,
|
||||
Parts = parts,
|
||||
WorkArea = workArea,
|
||||
Description = description,
|
||||
IsOverallBest = true,
|
||||
});
|
||||
NestEngineBase.ReportProgress(
|
||||
progress,
|
||||
new ProgressReport
|
||||
{
|
||||
Phase = NestPhase.Nfp,
|
||||
PlateNumber = 0,
|
||||
Parts = parts,
|
||||
WorkArea = workArea,
|
||||
Description = description,
|
||||
IsOverallBest = true,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user