Add max iteration cap

This commit is contained in:
Asriel Camora
2024-07-27 13:17:09 -07:00
parent 83e7ca8cf1
commit 14458344c7
5 changed files with 42 additions and 10 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ public class Bench
var solver = new MCTS(config, State); var solver = new MCTS(config, State);
var progress = 0; var progress = 0;
solver.Search(Config.Data.Iterations, ref progress, CancellationToken.None); solver.Search(Config.Data.Iterations, Config.Data.MaxIterations, ref progress, CancellationToken.None);
var solution = solver.Solution(); var solution = solver.Solution();
return (solver.MaxScore, solution); return (solver.MaxScore, solution);
+25 -2
View File
@@ -89,6 +89,15 @@ public sealed class Settings : Window, IDisposable
} }
} }
} }
else
{
var newValue = T.Clamp(value, min, max);
if (value != newValue)
{
setter(newValue);
isDirty = true;
}
}
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
ImGuiUtils.TooltipWrapped(tooltip); ImGuiUtils.TooltipWrapped(tooltip);
} }
@@ -505,7 +514,7 @@ public sealed class Settings : Window, IDisposable
); );
DrawOption( DrawOption(
"Iterations", "Target Iterations",
"The total number of iterations to run per crafting step. " + "The total number of iterations to run per crafting step. " +
"Higher values require more computational power. Higher values " + "Higher values require more computational power. Higher values " +
"also may decrease variance, so other values should be tweaked " + "also may decrease variance, so other values should be tweaked " +
@@ -517,6 +526,20 @@ public sealed class Settings : Window, IDisposable
ref isDirty ref isDirty
); );
DrawOption(
"Max Iterations",
"The solver may go about the target iteration value if the craft " +
"is sufficiently difficult, and it wasn't able to find any way to " +
"complete it yet. In rare cases, the solver might go on for a very " +
"long time. This maximum is here to prevent the solver from stealing " +
"all your RAM.",
config.MaxIterations,
config.Iterations,
5000000,
v => config = config with { MaxIterations = v },
ref isDirty
);
DrawOption( DrawOption(
"Max Step Count", "Max Step Count",
"The maximum number of crafting steps; this is generally the only " + "The maximum number of crafting steps; this is generally the only " +
@@ -995,7 +1018,7 @@ public sealed class Settings : Window, IDisposable
"Enforces a maximum number of steps to display in the synth helper to " + "Enforces a maximum number of steps to display in the synth helper to " +
"get rid of clutter.", "get rid of clutter.",
Config.SynthHelperMaxDisplayCount, Config.SynthHelperMaxDisplayCount,
1, Config.SynthHelperStepCount,
100, 100,
v => Config.SynthHelperMaxDisplayCount = v, v => Config.SynthHelperMaxDisplayCount = v,
ref isDirty ref isDirty
+6 -2
View File
@@ -253,14 +253,16 @@ public sealed class MCTS
} }
[SkipLocalsInit] [SkipLocalsInit]
public unsafe void Search(int iterations, ref int progress, CancellationToken token) public unsafe void Search(int iterations, int maxIterations, ref int progress, CancellationToken token)
{ {
maxIterations = Math.Max(iterations, maxIterations);
var simulator = new Simulator(config.ActionPool, config.MaxStepCount, rootNode.State.State); var simulator = new Simulator(config.ActionPool, config.MaxStepCount, rootNode.State.State);
var random = rootNode.State.State.Input.Random; var random = rootNode.State.State.Input.Random;
var staleCounter = 0; var staleCounter = 0;
var i = 0; var i = 0;
Span<ActionType> actionBuffer = stackalloc ActionType[Math.Min(config.MaxStepCount, config.MaxRolloutStepCount)]; Span<ActionType> actionBuffer = stackalloc ActionType[Math.Min(config.MaxStepCount, config.MaxRolloutStepCount)];
for (; i < iterations || MaxScore == 0; i++) for (; (i < iterations || MaxScore == 0); i++)
{ {
var selectedNode = Select(); var selectedNode = Select();
var (endNode, score) = ExpandAndRollout(random, simulator, selectedNode, actionBuffer); var (endNode, score) = ExpandAndRollout(random, simulator, selectedNode, actionBuffer);
@@ -268,6 +270,8 @@ public sealed class MCTS
{ {
if (endNode == selectedNode) if (endNode == selectedNode)
{ {
if (i >= maxIterations)
return;
if (staleCounter++ >= StaleProgressThreshold) if (staleCounter++ >= StaleProgressThreshold)
{ {
staleCounter = 0; staleCounter = 0;
+8 -5
View File
@@ -139,6 +139,7 @@ public sealed class Solver : IDisposable
private async Task<SolverSolution> SearchStepwiseGenetic() private async Task<SolverSolution> SearchStepwiseGenetic()
{ {
var iterCount = Config.Iterations / Config.ForkCount; var iterCount = Config.Iterations / Config.ForkCount;
var maxIterCount = Math.Max(Config.Iterations, Config.MaxIterations) / Config.ForkCount;
maxProgress = iterCount * Config.ForkCount; maxProgress = iterCount * Config.ForkCount;
var definiteActionCount = 0; var definiteActionCount = 0;
@@ -165,7 +166,7 @@ public sealed class Solver : IDisposable
await semaphore.WaitAsync(Token).ConfigureAwait(false); await semaphore.WaitAsync(Token).ConfigureAwait(false);
try try
{ {
solver.Search(iterCount, ref progress, Token); solver.Search(iterCount, maxIterCount, ref progress, Token);
} }
finally finally
{ {
@@ -256,6 +257,7 @@ public sealed class Solver : IDisposable
private async Task<SolverSolution> SearchStepwiseForked() private async Task<SolverSolution> SearchStepwiseForked()
{ {
var iterCount = Config.Iterations / Config.ForkCount; var iterCount = Config.Iterations / Config.ForkCount;
var maxIterCount = Math.Max(Config.Iterations, Config.MaxIterations) / Config.ForkCount;
maxProgress = iterCount * Config.ForkCount; maxProgress = iterCount * Config.ForkCount;
var actions = new List<ActionType>(); var actions = new List<ActionType>();
@@ -278,7 +280,7 @@ public sealed class Solver : IDisposable
await semaphore.WaitAsync(Token).ConfigureAwait(false); await semaphore.WaitAsync(Token).ConfigureAwait(false);
try try
{ {
solver.Search(iterCount, ref progress, Token); solver.Search(iterCount, maxIterCount, ref progress, Token);
} }
finally finally
{ {
@@ -329,7 +331,7 @@ public sealed class Solver : IDisposable
var solver = new MCTS(MCTSConfig, state); var solver = new MCTS(MCTSConfig, state);
var s = Stopwatch.StartNew(); var s = Stopwatch.StartNew();
solver.Search(Config.Iterations, ref progress, Token); solver.Search(Config.Iterations, Config.MaxIterations, ref progress, Token);
s.Stop(); s.Stop();
OnLog?.Invoke($"{s.Elapsed.TotalMilliseconds:0.00}ms {progress / s.Elapsed.TotalSeconds / 1000:0.00} kI/s"); OnLog?.Invoke($"{s.Elapsed.TotalMilliseconds:0.00}ms {progress / s.Elapsed.TotalSeconds / 1000:0.00} kI/s");
@@ -350,6 +352,7 @@ public sealed class Solver : IDisposable
private async Task<SolverSolution> SearchOneshotForked() private async Task<SolverSolution> SearchOneshotForked()
{ {
var iterCount = Config.Iterations / Config.ForkCount; var iterCount = Config.Iterations / Config.ForkCount;
var maxIterCount = Math.Max(Config.Iterations, Config.MaxIterations) / Config.ForkCount;
maxProgress = iterCount * Config.ForkCount; maxProgress = iterCount * Config.ForkCount;
using var semaphore = new SemaphoreSlim(0, Config.MaxThreadCount); using var semaphore = new SemaphoreSlim(0, Config.MaxThreadCount);
@@ -362,7 +365,7 @@ public sealed class Solver : IDisposable
await semaphore.WaitAsync(Token).ConfigureAwait(false); await semaphore.WaitAsync(Token).ConfigureAwait(false);
try try
{ {
solver.Search(iterCount, ref progress, Token); solver.Search(iterCount, maxIterCount, ref progress, Token);
} }
finally finally
{ {
@@ -394,7 +397,7 @@ public sealed class Solver : IDisposable
var solver = new MCTS(MCTSConfig, State); var solver = new MCTS(MCTSConfig, State);
var s = Stopwatch.StartNew(); var s = Stopwatch.StartNew();
solver.Search(Config.Iterations, ref progress, Token); solver.Search(Config.Iterations, Config.MaxIterations, ref progress, Token);
s.Stop(); s.Stop();
OnLog?.Invoke($"{s.Elapsed.TotalMilliseconds:0.00}ms {progress / s.Elapsed.TotalSeconds / 1000:0.00} kI/s"); OnLog?.Invoke($"{s.Elapsed.TotalMilliseconds:0.00}ms {progress / s.Elapsed.TotalSeconds / 1000:0.00} kI/s");
+2
View File
@@ -17,6 +17,7 @@ public enum SolverAlgorithm
public readonly record struct SolverConfig public readonly record struct SolverConfig
{ {
public int Iterations { get; init; } public int Iterations { get; init; }
public int MaxIterations { get; init; }
public float MaxScoreWeightingConstant { get; init; } public float MaxScoreWeightingConstant { get; init; }
public float ExplorationConstant { get; init; } public float ExplorationConstant { get; init; }
public int MaxStepCount { get; init; } public int MaxStepCount { get; init; }
@@ -38,6 +39,7 @@ public readonly record struct SolverConfig
public SolverConfig() public SolverConfig()
{ {
Iterations = 100_000; Iterations = 100_000;
MaxIterations = 1_500_000;
MaxScoreWeightingConstant = 0.1f; MaxScoreWeightingConstant = 0.1f;
ExplorationConstant = 4; ExplorationConstant = 4;
MaxStepCount = 30; MaxStepCount = 30;