[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# SolveOptions

Options for [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) and [`Engine.schedule`](<https://docs.dhtmlx.com/planning-engine/java/api/engine-schedule.md>). They set which part of the project is scheduled and which extra data the [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) carries. `new SolveOptions()` schedules the whole project and reports only the changed tasks.

## Declaration

```java
public class SolveOptions extends ValueRecord implements DeepCloneable<SolveOptions>
```

Set fields with the fluent `withX` setters: `new SolveOptions().withReasons(true)`. Two instances are equal when all four fields are equal, compared by value. For how `Project#solve` uses that equality to return its cached result, see [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>).

## Constructors

### SolveOptions()

```java
public SolveOptions()
```

Creates options with every field at its default.

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `subtree` | [`Subtree`](<https://docs.dhtmlx.com/planning-engine/java/api/project/subtree.md>) | `null` | Schedules only one task's subtree and the tasks that depend on it. `null` schedules the whole project. |
| `analytics` | [`AnalyticsOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/analytics-options.md>) | `new AnalyticsOptions()` (no analytics) | Requests critical path and slack. Fills [`ScheduleResult.analytics`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>). |
| `reasons` | `boolean` | `false` | Fills [`Mutation.reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) on each update with the [`Reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/reason.md>) the task moved. |
| `includeUnchanged` | `boolean` | `false` | Also reports unchanged tasks in [`ScheduleResult.updates`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#updates>), so the result holds the full date list. |

### subtree

```java
public Subtree subtree = null;
```

Limits scheduling to the scope the [`Subtree`](<https://docs.dhtmlx.com/planning-engine/java/api/project/subtree.md>) value describes. Build the value with `new Subtree(id)`.

### analytics

```java
public AnalyticsOptions analytics = new AnalyticsOptions();
```

Turns on [`AnalyticsOptions.slack`](<https://docs.dhtmlx.com/planning-engine/java/api/project/analytics-options.md>) and [`AnalyticsOptions.criticalPath`](<https://docs.dhtmlx.com/planning-engine/java/api/project/analytics-options.md>). With both flags `false` (the default), `ScheduleResult.analytics` is `null`. With either flag set, it holds an [`Analytics`](<https://docs.dhtmlx.com/planning-engine/java/api/results/analytics.md>) value. Check its status before reading the data.

### reasons

```java
public boolean reasons = false;
```

When `true`, each [`Mutation`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) in `updates` carries a [`Reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/reason.md>) in its `reason` field. When `false`, `reason` is always `null`.

[`Mutation.reason`](<https://docs.dhtmlx.com/planning-engine/java/api/results/mutation.md>) lists the cases where it stays `null` even with `reasons = true`.

### includeUnchanged

```java
public boolean includeUnchanged = false;
```

When `false`, `updates` holds only the tasks the solve changed or that edits touched. When `true`, `updates` also holds every scheduled task that didn't change, each with `startDate`, `endDate` and `duration` set. The result is the full normalized date list for an initial load.

- Every scheduled task is reported: leaves, summaries and milestones. Unscheduled tasks are never reported.
- With `subtree`, every task in the subtree is reported, ancestors of subtree tasks included, plus the usual changed or touched updates outside the subtree.
- On a project with cycles, every scheduled task is reported in model order (`subtree` is ignored), with its stored dates and durations.
- `levelingDelay` and `pauses` are never set in these entries.

The extra entries don't affect [`ScheduleResult.baselineId`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md#baselineid>), which follows real date changes only. Every other result field matches what the same solve returns with `includeUnchanged = false`.

## Methods

### withSubtree, withAnalytics, withReasons, withIncludeUnchanged

```java
public SolveOptions withSubtree(Subtree value)
public SolveOptions withAnalytics(AnalyticsOptions value)
public SolveOptions withReasons(boolean value)
public SolveOptions withIncludeUnchanged(boolean value)
```

Each setter assigns its field and returns this instance for chaining.

**Returns** - this `SolveOptions`.

### deepClone

```java
public SolveOptions deepClone()
```

Returns a copy that shares no nested object (`subtree`, `analytics`) with this instance.

**Returns** - a new `SolveOptions` with the same values.

### copy

```java
public SolveOptions copy()
```

Returns a shallow copy. The copy shares the `subtree` and `analytics` objects with this instance.

**Returns** - a new `SolveOptions` with the same field values.

### equals, hashCode, toString

```java
public boolean equals(Object other)
public int hashCode()
public String toString()
```

Inherited from [`ValueRecord`](<https://docs.dhtmlx.com/planning-engine/java/api/support/value-record.md>). Two `SolveOptions` are equal when their public fields are equal, nested records compared by value. `toString()` lists the fields.

## Example

```java
import java.util.List;
import org.dhtmlx.plen.*;

public class SolveOptionsExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 1, 5, 8, 0);

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("design")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1")).withSource(Id.str("design")).withTarget(Id.str("build"))));

    SolveOptions options = new SolveOptions()
        .withAnalytics(new AnalyticsOptions().withCriticalPath(true))
        .withReasons(true)
        .withIncludeUnchanged(true);

    Project project = new Project();
    ScheduleResult result = project.solve(data, options);

    // Every scheduled task, changed or not.
    for (Mutation update : result.updates) {
      System.out.println(update.id + ": " + update.startDate + " - " + update.endDate + " (" + update.reason + ")");
    }
  }
}
```

## Related

- [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) - the stateful call that takes it
- [`Engine.schedule`](<https://docs.dhtmlx.com/planning-engine/java/api/engine-schedule.md>) - the one-shot call that takes it
- [`Subtree`](<https://docs.dhtmlx.com/planning-engine/java/api/project/subtree.md>) - limits scheduling to one branch
- [`AnalyticsOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/analytics-options.md>) - slack and critical path switches
- [Solve options](<https://docs.dhtmlx.com/planning-engine/java/scheduling/scheduling-a-project.md#solve-options>) - choosing the switches
