Candidate#

One alternative edit to score: an id and the SchedulingChanges to try. Build a list of candidates with object initializers and pass it to Project.Evaluate or Project.EvaluateWith.

Declaration#

namespace Plen;

public sealed class Candidate : IDeepCloneable<Candidate>

Both properties are required, so new Candidate() without Id and Changes doesn't compile.

Properties#

Property Type Description
Id Id Label for the candidate. Copied unchanged into CandidateResult.Id. Uniqueness isn't checked.
Changes SchedulingChanges Edits to apply to the copy before scheduling it. An empty change set scores the plan as it is.

A string, int or double converts to Id implicitly.

For how a stale Changes.BaselineId or a rejected operation in Changes is reported, see Project.Evaluate and CandidateResult.Error.

Methods#

DeepClone#

public Candidate DeepClone()

Returns a deep copy: Changes and every list in it are copied, nothing is shared with the original.

ToString#

public override string ToString()

Returns a readable rendering of Id and Changes, for logging.

Candidate doesn't override Equals; two instances compare by reference.

Example#

Score two ways to staff task 1: assign dev1 or assign dev2.

using Plen;

var monday = Moment.FromYmdHm(2026, 8, 10, 8, 0)
    ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks = [new TaskData(1) { StartDate = monday, Duration = 2.0 }],
    Resources = [new ResourceData { Id = "dev1" }, new ResourceData { Id = "dev2" }],
};

var project = new Project();
project.Solve(data, new SolveOptions());

var candidates = new List<Candidate>();
foreach (var dev in new[] { "dev1", "dev2" })
{
    var changes = new SchedulingChanges();
    changes.Assignments.Add.Add(new AssignmentData { Task = 1, Resource = dev, Value = 1.0 });
    candidates.Add(new Candidate { Id = dev, Changes = changes });
}

var result = project.Evaluate(candidates, new EvaluateOptions());
foreach (var c in result.Candidates)
    Console.WriteLine($"{c.Id}: cost {c.Cost}");