Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions core/src/build/revapi-differences.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@
"old": "field ai.timefold.solver.core.config.heuristic.selector.move.generic.AbstractPillarMoveSelectorConfig<Config_ extends ai.timefold.solver.core.config.heuristic.selector.move.generic.AbstractPillarMoveSelectorConfig<Config_>>.subPillarSequenceComparatorClass",
"new": "field ai.timefold.solver.core.config.heuristic.selector.move.generic.AbstractPillarMoveSelectorConfig<Config_ extends ai.timefold.solver.core.config.heuristic.selector.move.generic.AbstractPillarMoveSelectorConfig<Config_>>.subPillarSequenceComparatorClass",
"justification": "Internal protected fields; safe."
},
{
"ignore": true,
"code": "java.annotation.attributeValueChanged",
"old": "class ai.timefold.solver.core.config.phase.PhaseConfig<Config_ extends ai.timefold.solver.core.config.phase.PhaseConfig<Config_>>",
"new": "class ai.timefold.solver.core.config.phase.PhaseConfig<Config_ extends ai.timefold.solver.core.config.phase.PhaseConfig<Config_>>",
"annotationType": "jakarta.xml.bind.annotation.XmlSeeAlso",
"attribute": "value",
"oldValue": "{ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig.class, ai.timefold.solver.core.config.phase.custom.CustomPhaseConfig.class, ai.timefold.solver.core.config.exhaustivesearch.ExhaustiveSearchPhaseConfig.class, ai.timefold.solver.core.config.localsearch.LocalSearchPhaseConfig.class, ai.timefold.solver.core.config.partitionedsearch.PartitionedSearchPhaseConfig.class}",
"newValue": "{ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig.class, ai.timefold.solver.core.config.phase.custom.CustomPhaseConfig.class, ai.timefold.solver.core.config.exhaustivesearch.ExhaustiveSearchPhaseConfig.class, ai.timefold.solver.core.config.localsearch.LocalSearchPhaseConfig.class, ai.timefold.solver.core.config.evolutionaryalgorithm.EvolutionaryAlgorithmPhaseConfig.class, ai.timefold.solver.core.config.partitionedsearch.PartitionedSearchPhaseConfig.class}",
"justification": "Add new evolutionary config"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ static EventProducerId partitionedSearch(int phaseIndex) {
return new PhaseEventProducerId(PhaseType.PARTITIONED_SEARCH, phaseIndex);
}

static EventProducerId evolutionaryAlgorithm(int phaseIndex) {
return new PhaseEventProducerId(PhaseType.EVOLUTIONARY_ALGORITHM, phaseIndex);
}

static EventProducerId customPhase(int phaseIndex) {
return new PhaseEventProducerId(PhaseType.CUSTOM_PHASE, phaseIndex);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package ai.timefold.solver.core.config.evolutionaryalgorithm;

import java.util.function.Consumer;

import jakarta.xml.bind.annotation.XmlType;

import ai.timefold.solver.core.config.phase.PhaseConfig;
import ai.timefold.solver.core.config.util.ConfigUtils;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@XmlType(propOrder = {
"populationConfig",
"workerConfig",
})
@NullMarked
public class EvolutionaryAlgorithmPhaseConfig extends PhaseConfig<EvolutionaryAlgorithmPhaseConfig> {

public static final String XML_ELEMENT_NAME = "evolutionaryAlgorithm";

@Nullable
private EvolutionaryPopulationConfig populationConfig = null;

@Nullable
private EvolutionaryWorkerConfig workerConfig = null;

// ************************************************************************
// Constructors and simple getters/setters
// ************************************************************************

public @Nullable EvolutionaryPopulationConfig getPopulationConfig() {
return populationConfig;
}

public void setPopulationConfig(@Nullable EvolutionaryPopulationConfig populationConfig) {
this.populationConfig = populationConfig;
}

public @Nullable EvolutionaryWorkerConfig getWorkerConfig() {
return workerConfig;
}

public void setWorkerConfig(@Nullable EvolutionaryWorkerConfig workerConfig) {
this.workerConfig = workerConfig;
}

// ************************************************************************
// With methods
// ************************************************************************

public EvolutionaryAlgorithmPhaseConfig withPopulationConfig(EvolutionaryPopulationConfig populationConfig) {
setPopulationConfig(populationConfig);
return this;
}

public EvolutionaryAlgorithmPhaseConfig withWorkerConfig(EvolutionaryWorkerConfig workerConfig) {
setWorkerConfig(workerConfig);
return this;
}

@Override
public EvolutionaryAlgorithmPhaseConfig inherit(EvolutionaryAlgorithmPhaseConfig inheritedConfig) {
super.inherit(inheritedConfig);
populationConfig = ConfigUtils.inheritConfig(populationConfig, inheritedConfig.getPopulationConfig());
workerConfig = ConfigUtils.inheritConfig(workerConfig, inheritedConfig.getWorkerConfig());
return this;
}

@Override
public EvolutionaryAlgorithmPhaseConfig copyConfig() {
return new EvolutionaryAlgorithmPhaseConfig().inherit(this);
}

@Override
public void visitReferencedClasses(Consumer<@Nullable Class<?>> classVisitor) {
if (populationConfig != null) {
populationConfig.visitReferencedClasses(classVisitor);
}
if (workerConfig != null) {
workerConfig.visitReferencedClasses(classVisitor);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ai.timefold.solver.core.config.evolutionaryalgorithm;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlType;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import ai.timefold.solver.core.api.solver.phase.PhaseCommand;
import ai.timefold.solver.core.config.constructionheuristic.ConstructionHeuristicPhaseConfig;
import ai.timefold.solver.core.config.phase.PhaseConfig;
import ai.timefold.solver.core.config.util.ConfigUtils;
import ai.timefold.solver.core.impl.io.jaxb.JaxbCustomPropertiesAdapter;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@XmlType(propOrder = {
"customPhaseCommandClassList",
"customProperties",
"constructionHeuristic"
})
@NullMarked
public class EvolutionaryIndividualGeneratorConfig extends PhaseConfig<EvolutionaryIndividualGeneratorConfig> {

@XmlElement(name = "customPhaseCommandClass")
@Nullable
private List<Class<? extends PhaseCommand>> customPhaseCommandClassList = null;

@XmlJavaTypeAdapter(JaxbCustomPropertiesAdapter.class)
@Nullable
private Map<String, String> customProperties = null;

@Nullable
private ConstructionHeuristicPhaseConfig constructionHeuristic = null;

// ************************************************************************
// Constructors and simple getters/setters
// ************************************************************************

public @Nullable List<Class<? extends PhaseCommand>> getCustomPhaseCommandClassList() {
return customPhaseCommandClassList;
}

public void setCustomPhaseCommandClassList(
@Nullable List<Class<? extends PhaseCommand>> customPhaseCommandClassList) {
this.customPhaseCommandClassList = customPhaseCommandClassList;
}

public @Nullable Map<String, String> getCustomProperties() {
return customProperties;
}

public void setCustomProperties(@Nullable Map<String, String> customProperties) {
this.customProperties = customProperties;
}

public @Nullable ConstructionHeuristicPhaseConfig getConstructionHeuristic() {
return constructionHeuristic;
}

public void setConstructionHeuristic(@Nullable ConstructionHeuristicPhaseConfig constructionHeuristic) {
this.constructionHeuristic = constructionHeuristic;
}

// ************************************************************************
// With methods
// ************************************************************************

public EvolutionaryIndividualGeneratorConfig withCustomPhaseCommandClassList(
List<Class<? extends PhaseCommand>> customPhaseCommandClassList) {
setCustomPhaseCommandClassList(customPhaseCommandClassList);
return this;
}

public EvolutionaryIndividualGeneratorConfig withCustomProperties(Map<String, String> customProperties) {
setCustomProperties(customProperties);
return this;
}

public EvolutionaryIndividualGeneratorConfig
withConstructionHeuristic(@Nullable ConstructionHeuristicPhaseConfig constructionHeuristic) {
setConstructionHeuristic(constructionHeuristic);
return this;
}

@Override
public EvolutionaryIndividualGeneratorConfig inherit(EvolutionaryIndividualGeneratorConfig inheritedConfig) {
super.inherit(inheritedConfig);
customPhaseCommandClassList = ConfigUtils.inheritMergeableListProperty(customPhaseCommandClassList,
inheritedConfig.getCustomPhaseCommandClassList());
customProperties = ConfigUtils.inheritMergeableMapProperty(customProperties, inheritedConfig.getCustomProperties());
constructionHeuristic = ConfigUtils.inheritConfig(constructionHeuristic, inheritedConfig.getConstructionHeuristic());
return this;
}

@Override
public EvolutionaryIndividualGeneratorConfig copyConfig() {
return new EvolutionaryIndividualGeneratorConfig().inherit(this);
}

@Override
public void visitReferencedClasses(Consumer<@Nullable Class<?>> classVisitor) {
if (customPhaseCommandClassList != null) {
customPhaseCommandClassList.forEach(classVisitor);
}
if (constructionHeuristic != null) {
constructionHeuristic.visitReferencedClasses(classVisitor);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ai.timefold.solver.core.config.evolutionaryalgorithm;

import java.util.function.Consumer;

import jakarta.xml.bind.annotation.XmlType;

import ai.timefold.solver.core.config.localsearch.LocalSearchPhaseConfig;
import ai.timefold.solver.core.config.phase.PhaseConfig;
import ai.timefold.solver.core.config.util.ConfigUtils;

import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@XmlType(propOrder = {
"localSearch",
})
@NullMarked
public class EvolutionaryLocalSearchConfig extends PhaseConfig<EvolutionaryLocalSearchConfig> {

@Nullable
private LocalSearchPhaseConfig localSearch = null;

// ************************************************************************
// Constructors and simple getters/setters
// ************************************************************************

public @Nullable LocalSearchPhaseConfig getLocalSearch() {
return localSearch;
}

public void setLocalSearch(@Nullable LocalSearchPhaseConfig localSearch) {
this.localSearch = localSearch;
}

// ************************************************************************
// With methods
// ************************************************************************

public EvolutionaryLocalSearchConfig withLocalSearch(LocalSearchPhaseConfig localSearch) {
setLocalSearch(localSearch);
return this;
}

@Override
public EvolutionaryLocalSearchConfig inherit(EvolutionaryLocalSearchConfig inheritedConfig) {
super.inherit(inheritedConfig);
localSearch = ConfigUtils.inheritConfig(localSearch, inheritedConfig.getLocalSearch());
return this;
}

@Override
public EvolutionaryLocalSearchConfig copyConfig() {
return new EvolutionaryLocalSearchConfig().inherit(this);
}

@Override
public void visitReferencedClasses(Consumer<@Nullable Class<?>> classVisitor) {
if (localSearch != null) {
localSearch.visitReferencedClasses(classVisitor);
}
}
}
Loading
Loading