Running algorithms
Running an algorithm combines an immutable configuration with one problem and one explicit random source. Each execution starts with fresh run state.
Run inputs
Algorithm configuration
Problem
Random source
Algorithm run
Fresh execution state
Stream
Observe every state
CompleteAsync
Receive the final state
Stream or complete
Use Stream when the caller needs progress:
await foreach (var state in algorithm.Stream(problem, random, ct: cancellationToken))
{
RenderProgress(state);
}Use CompleteAsync when the final state is enough:
var finalState = await algorithm.CompleteAsync(
problem,
random,
ct: cancellationToken);Both forms represent a new run. Do not call one after the other expecting the second call to continue the first.
Stopping budgets
Prefer an algorithm's own budget for normal configuration. A genetic algorithm exposes MaximumGenerations. Other algorithms may use iterations, evaluations or a domain specific condition.
External wrappers are useful when an experiment must impose the same budget across algorithms that expose different controls. When comparing methods, evaluation count is often fairer than generation count because one generation can perform very different amounts of work.
Cancellation
Pass a cancellation token from the host application. Cancellation is for external interruption such as a user request or service shutdown. It should not replace a deterministic algorithm budget.
using var timeout = new CancellationTokenSource(TimeSpan.FromMinutes(2));
var finalState = await algorithm.CompleteAsync(problem, random, ct: timeout.Token);Reproducibility
Create the random number generator from a recorded seed:
var random = RandomNumberGenerator.Create(seed: 123);The algorithm forks that source deterministically for its work. Keep the seed, package version, algorithm configuration and problem data with every reported result.
Parallel scheduling can change completion order. Trial identity and seed derivation should not depend on that order. The experiment API handles independent trial runs for you.
Explicit runs for analysis
The direct extensions cover most applications. Create a run object when you need to attach analyzers or inspect results owned by one execution:
var run = algorithm.CreateRun(problem, random);
var finalState = await run.CompleteAsync();See Observability and analysis for an analyzer example.