Adding new Planning Variable to the Vehicle Routing Problem - optaplanner

I'm trying to add a new variable to the Vehicle Routing Problem to represent a vehicle (bus) picking up people and let them in locations with match some facts (these resources must attend one customer each).
I have created a new class called Resource and declared a new resource variable inside the Customer class, so when a new move is made, I want the solver to select a new Customer to a Vehicle (route) and a Resource from the list (which eventually will be also in the vehicle, as well).
In the Customer.java:
#PlanningVariable(valueRangeProviderRefs = {"resourceRange"})
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
And in the VehicleRoutingSolution.java:
protected List<Resource> resourceList;
[...]
#ProblemFactCollectionProperty
#ValueRangeProvider(id = "resourceRange")
public List<Resource> getResourceList() {
return resourceList;
}
public void setResourceList(List<Resource> resourceList) {
this.resourceList = resourceList;
}
Finally I have made some changes to the vehicleRoutingSolverConfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode>-->
<solutionClass>com.ezentis.mplanner.vehiclerouting.domain.VehicleRoutingSolution</solutionClass>
<entityClass>com.ezentis.mplanner.vehiclerouting.domain.Standstill</entityClass>
<entityClass>com.ezentis.mplanner.vehiclerouting.domain.Customer</entityClass>
<entityClass>com.ezentis.mplanner.vehiclerouting.domain.timewindowed.TimeWindowedCustomer</entityClass>
<scoreDirectorFactory>
<!--<easyScoreCalculatorClass>com.ezentis.mplanner.vehiclerouting.solver.score.VehicleRoutingEasyScoreCalculator</easyScoreCalculatorClass>-->
<incrementalScoreCalculatorClass>com.ezentis.mplanner.vehiclerouting.solver.score.VehicleRoutingIncrementalScoreCalculator</incrementalScoreCalculatorClass>
<!-- scoreDrl>com/ezentis/mplanner/vehiclerouting/solver/vehicleRoutingScoreRules.drl</scoreDrl-->
<!--<assertionScoreDirectorFactory>-->
<!--<easyScoreCalculatorClass>com.ezentis.mplanner.vehiclerouting.solver.score.VehicleRoutingEasyScoreCalculator</easyScoreCalculatorClass>-->
<!--</assertionScoreDirectorFactory>-->
<initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
</scoreDirectorFactory>
<termination>
<minutesSpentLimit>5</minutesSpentLimit>
</termination>
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
<!-- <queuedEntityPlacer>
<entitySelector id="placerEntitySelector">
<entityClass>com.ezentis.mplanner.vehiclerouting.domain.Customer</entityClass>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterManner>DECREASING_DIFFICULTY</sorterManner>
</entitySelector>
<cartesianProductMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="placerEntitySelector"/>
<valueSelector variableName="vehicleRange">
<downcastEntityClass>com.ezentis.mplanner.vehiclerouting.domain.Vehicle</downcastEntityClass>
<cacheType>PHASE</cacheType> -->
<!--<selectionOrder>SORTED</selectionOrder>-->
<!--<sorterManner>INCREASING_STRENGTH</sorterManner>-->
<!-- </valueSelector>
</changeMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="placerEntitySelector"/>
<valueSelector variableName="resourceRange">
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterManner>INCREASING_STRENGTH</sorterManner>
</valueSelector>
</changeMoveSelector>
</cartesianProductMoveSelector>
</queuedEntityPlacer> -->
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<changeMoveSelector>
<entitySelector id="entitySelector1"/>
<valueSelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector1"/>
<nearbyDistanceMeterClass>com.ezentis.mplanner.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector id="entitySelector2"/>
<secondaryEntitySelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector2"/>
<nearbyDistanceMeterClass>com.ezentis.mplanner.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</secondaryEntitySelector>
</swapMoveSelector>
<tailChainSwapMoveSelector>
<entitySelector id="entitySelector3"/>
<valueSelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector3"/>
<nearbyDistanceMeterClass>com.ezentis.mplanner.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</valueSelector>
</tailChainSwapMoveSelector>
</unionMoveSelector>
<acceptor>
<lateAcceptanceSize>200</lateAcceptanceSize>
</acceptor>
<forager>
<acceptedCountLimit>1</acceptedCountLimit>
</forager>
</localSearch>
</solver>
But when I upload the problem and start the solver, I get this error:
java.lang.IllegalStateException: Multiple EntityMimicRecorders (usually EntitySelectors) have the same id (entitySelector1).
I am really stuck with this as I'm not able to include the new Planning Variable. I have tried a lot of another code configurations, although I think this is the more clear.
Any help would be really appreciated.

I am not sure if this will really work but when you do something like that you won't get the error.
<valueSelector variableName="variableName">
I only need the nearbySelection for the chained variable.
If you want the nearby selection for both variables you could try to have two <changeMoveSelector> with each one nearby config.

Related

Blueprint properties placeholder

Here is my blueprint:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint https://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<bean class="ph.edu.dlsu.esb.CogMockProcessor" id="CogMockProcessor"/>
<cm:property-placeholder id="cogmock.properties"
persistent-id="custom.properties" update-strategy="reload">
<cm:default-properties>
<cm:property name="cogmock.host" value="//localhost"/>
<cm:property name="cogmock.port" value="8989"/>
<cm:property name="cogmock.path"
value="/external/grade/updatestudentgrade"/>
<cm:property name="cogmock.protocol" value="http"/>
<cm:property name="cogmock.OpenId.Token"
value="9GC1hnEeNIWVbehmxxjUwkj1Wcx2Y-P7SgOUZvVUzkM"/>
</cm:default-properties>
</cm:property-placeholder>
<camelContext id="_mockcontext" xmlns="http://camel.apache.org/schema/blueprint">
<route id="_route1">
<from id="_from1" uri="restlet:http://localhost:{{cogmock.port}}/external/grade/updatestudentgrade?restletMethod=POST">
<description>Mock the Camu Change of Grade API</description>
</from>
<process id="_process1" ref="CogMockProcessor"/>
<log id="_log1" message="I'm here"/>
</route>
</camelContext>
</blueprint>
Here is my fuse-karaf/etc/custom.properties
#
# You can place any customized configuration here.
#
cogmock.protocol=http
cogmock.host=//localhost
cogmock.port=8989
cogmock.path=/external/grade/updatestudentgrade
cogmock.OpenId.Token=9GC1hnEeNIWVbehmxxjUwkj1Wcx2Y-P7SgOUZvVUzkM
It Builds successfully but when I bundle:install -s ... I get:
Unable to start container for blueprint bundle CogMock/1.0.0.SNAPSHOT
If I take out the {{cogmock.port}} everything works fine.
What am I missing?
update-strategy="reload" can be added to your blueprint XML only when you use xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" or later. It doesn't work with xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0".
And to be clear persistent-id attribute means PID, which (when using etc/ configuration) is created from files with *.cfg extension. So if you have persistent-id="cogmock", you need $FUSE_HOME/etc/cogmock.cfg file with your properties.

Optaplanner Shadow Variable changed for every move, not every step

I have a planning entity with a genuine variable
#PlanningEntity
public class PlannerTaskResourceAllocation extends AbstractDto {
...
#PlanningVariable(valueRangeProviderRefs = "resources")
public TaskResource getResource() {
return resource;
}
...
}
and one with a genuine variable and a shadow variable
#PlanningEntity
public class PlannerActivity extends AbstractEntity {
...
#PlanningVariable(valueRangeProviderRefs = "possibleDates")
public Integer getStartIndex() {
return startIndex;
}
...
#CustomShadowVariable(variableListenerClass = TaskResourceVariableListener.class,
sources = { #CustomShadowVariable.Source(entityClass = PlannerTaskResourceAllocation.class,
variableName = "resource") })
public Integer getLength() {
return length;
and a custom variable listener that changes the length property (shadow var) of the second planning entity based on changes in the first planning entity's resource property (genuine var), and under certain conditions. my problem is is that it seems that the listener does it's change for every move, while as i understood it is supposed to do it for every step. as in if we look at the log below, there were 5 steps being tried for that move, when only one of them was accepted, but the change on the shadow variable happened 5 times. to simplify testing it i made a simpler method in the listener that simply extends the length by one:
public class TaskResourceVariableListener implements VariableListener<PlannerTaskResourceAllocation> {
#Override
public void afterEntityAdded(ScoreDirector scoreDirector, PlannerTaskResourceAllocation entity) {
lengthenActivities(scoreDirector, entity);
}
#Override
public void beforeVariableChanged(ScoreDirector scoreDirector, PlannerTaskResourceAllocation entity) {
}
#Override
public void afterVariableChanged(ScoreDirector scoreDirector, PlannerTaskResourceAllocation entity) {
lengthenActivities(scoreDirector, entity);
}
private void lengthenActivities(ScoreDirector scoreDirector, PlannerTaskResourceAllocation allocation) {
for (PlannerActivity plannerActivity : ((ActivitySolution) scoreDirector.getWorkingSolution())
.getActivities()) {
scoreDirector.beforeVariableChanged(plannerActivity, "length");
plannerActivity.setLength(plannerActivity.getLength() + 1);
scoreDirector.afterVariableChanged(plannerActivity, "length");
break;
}
}
so between these two steps, the activity was lengthened 5 times, instead of one.
log output:
2017-05-15 16:30:33.834 DEBUG --- [ main] o.o.c.i.l.DefaultLocalSearchPhase : LS step (3971), time spent (56826), score (0hard/-15120soft), best score (0hard/-15070soft), accepted/selected move count (1/1), picked move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=47, created=2017-05-15 16:29:34.18, lastModified=2017-05-15 16:29:34.18), resource=dave2 daveson (ATV Driver)) {dave2 daveson (ATV Driver) -> dave daveson (ATV Driver)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (0) not doable, ignoring move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=46, created=2017-05-15 16:29:34.142, lastModified=2017-05-15 16:29:34.142), resource=Product(name=oil1)) {Product(name=oil1) -> Product(name=oil1)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (1) not doable, ignoring move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=47, created=2017-05-15 16:29:34.18, lastModified=2017-05-15 16:29:34.18), resource=atv1 (atv)) {atv1 (atv) -> atv1 (atv)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (2) not doable, ignoring move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=47, created=2017-05-15 16:29:34.18, lastModified=2017-05-15 16:29:34.18), resource=steve steveson (Spreader Driver)) {steve steveson (Spreader Driver) -> steve steveson (Spreader Driver)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (3), score (-1hard/-15120soft), accepted (false), move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=46, created=2017-05-15 16:29:34.142, lastModified=2017-05-15 16:29:34.142), resource=subguy subguyson (Tractor Driver)) {subguy subguyson (Tractor Driver) -> joe2 joeson (Tractor Driver)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (4) not doable, ignoring move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=46, created=2017-05-15 16:29:34.142, lastModified=2017-05-15 16:29:34.142), resource=spreader2 (spreader)) {spreader2 (spreader) -> spreader2 (spreader)}).
2017-05-15 16:30:33.834 TRACE --- [ main] o.o.c.i.l.decider.LocalSearchDecider : Move index (5), score (0hard/-15110soft), accepted (true), move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=47, created=2017-05-15 16:29:34.18, lastModified=2017-05-15 16:29:34.18), resource=atv2 (atv)) {atv2 (atv) -> atv1 (atv)}).
2017-05-15 16:30:33.834 DEBUG --- [ main] o.o.c.i.l.DefaultLocalSearchPhase : LS step (3972), time spent (56826), score (0hard/-15110soft), best score (0hard/-15070soft), accepted/selected move count (1/2), picked move (PlannerTaskResourceAllocation(activity=AbstractEntity(id=47, created=2017-05-15 16:29:34.18, lastModified=2017-05-15 16:29:34.18), resource=atv2 (atv)) {atv2 (atv) -> atv1 (atv)}).
here's my solver config:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!-- <environmentMode>FULL_ASSERT</environmentMode> -->
<!-- Domain model configuration -->
<solutionClass>com.rdthree.plenty.services.activities.planner.ActivitySolution</solutionClass>
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerActivity</entityClass>
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerTaskResourceAllocation</entityClass>
<!-- Score configuration -->
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>com/rdthree/plenty/services/activities/planner/activity-scoring.drl</scoreDrl>
<initializingScoreTrend>ANY</initializingScoreTrend>
</scoreDirectorFactory>
<!-- Optimization algorithms configuration -->
<termination>
<terminationCompositionStyle>OR</terminationCompositionStyle>
<bestScoreLimit>0hard/0soft</bestScoreLimit>
<secondsSpentLimit>60</secondsSpentLimit>
</termination>
<constructionHeuristic>
<queuedEntityPlacer>
<entitySelector id="resourceAllocationSelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerTaskResourceAllocation</entityClass>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterManner>DECREASING_DIFFICULTY_IF_AVAILABLE</sorterManner>
</entitySelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="resourceAllocationSelector" />
<valueSelector>
<variableName>resource</variableName>
<cacheType>PHASE</cacheType>
</valueSelector>
</changeMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<constructionHeuristic>
<queuedEntityPlacer>
<entitySelector id="activityIndexSelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerActivity</entityClass>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterManner>DECREASING_DIFFICULTY_IF_AVAILABLE</sorterManner>
</entitySelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="activityIndexSelector" />
<valueSelector>
<variableName>startIndex</variableName>
<cacheType>PHASE</cacheType>
</valueSelector>
</changeMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<localSearch>
<!-- run it with exhaustive search -->
<unionMoveSelector>
<changeMoveSelector>
<fixedProbabilityWeight>1000.0</fixedProbabilityWeight>
<entitySelector id="taskResourceAllocationSelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerTaskResourceAllocation</entityClass>
</entitySelector>
<valueSelector>
<variableName>resource</variableName>
</valueSelector>
<filterClass>com.rdthree.plenty.services.activities.planner.filters.ResourceTypeMismatchFilter</filterClass>
</changeMoveSelector>
<changeMoveSelector>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
<entitySelector id="activityelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.PlannerActivity</entityClass>
</entitySelector>
<valueSelector>
<variableName>startIndex</variableName>
</valueSelector>
</changeMoveSelector>
</unionMoveSelector>
<acceptor>
<simulatedAnnealingStartingTemperature>0hard/1000soft</simulatedAnnealingStartingTemperature>
</acceptor>
<forager>
<acceptedCountLimit>1</acceptedCountLimit>
</forager>
</localSearch>
</solver>
Am i missing something?

Problems with the solver configuration for two planning entity classes

I'm working on a solution of a problem that is close to the Nurse Rostering Example in optaplanner .
Employees are assigned to shifts as in the Nurse Roster but the main difference is that there are also skill requirements (assignments) that last lets say 20 minutes. An employee can be assigned to a skill requirement if he gets assigned to a shift that covers the given skill requirement time. Lets say we have a skill requirement for Skill1 from 12:00 to 12:20 and an employee is assigned on a shift from 08:00 to 16:00 then he can be assigned to that skill requirement only if he has that skill.
I have 2 planning entity classes. The default shift assignment in the example, and i have implemented 2 more classes SkillRequirement class which will hold one skill requirement in the given time frame (this will be a planning fact) , and the second planning entity class will be between the Employee and the SkillRequirement class and the name of it will be EmployeeSkillRequirement.
By now i think i have done everything good i annotated the EmployeeSkillRequirement
class as #PlanningEntity and the planning variable with the appropriate value range, in the planning solution i added the lists for the skill requirements(which are facts and also go into drools working memory) and the list of employees on skill requirements which are the planning entities and are properly annotated with #PlanningEntitySolutionProperty
I'm having a hard time configuring the solver, i have tried many different solver configurations, i read in the documentation that when there are more planning entities and/or planning variables a union of move selectors should be used where you tell OptaPlanner the name of the planning entity class and planning variable, because it cant find it by default.
None seem to work and i get this exception all the time
Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/nurserostering/solver/nurseRosteringSolverConfig.xml) fails.
Here are the configurations i' have been trying to use:
Config 1:
In this configuration the default move selectors are used for the
planning entity shift assignment class in local search and move
selectors
are added for the planning entity class
"EmployeeSkillRequirement" and everything is combined in a
and the construction heuristic is replaced with move selectors combined in a union to.
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode> -->
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster
</solutionClass>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>org/optaplanner/examples/nurserostering/solver/nurseRosteringScoreRules.drl
</scoreDrl>
</scoreDirectorFactory>
<termination>
<!-- Official benchmark secondsSpentLimit allowed on: - ge0ffrey's main
pc: sprint 11, medium 700, long 42000 -->
<secondsSpentLimit>700</secondsSpentLimit>
<!--<bestScoreLimit>-0hard/-999999soft</bestScoreLimit> -->
</termination>
<constructionHeuristic>
<queuedEntityPlacer>
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
</unionMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<!-- Move Selectors for ShiftAssignment this was the default configuration
from the example -->
<moveListFactory>
<cacheType>PHASE</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.EmployeeChangeMoveFactory
</moveListFactoryClass>
</moveListFactory>
<moveListFactory>
<cacheType>PHASE</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSwapMoveFactory
</moveListFactoryClass>
</moveListFactory>
<moveListFactory>
<cacheType>STEP</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentPillarPartSwapMoveFactory
</moveListFactoryClass>
</moveListFactory>
<!-- The move selectors for the second plannig entity class EmployeeSkillRequirement -->
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
</unionMoveSelector>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>800</acceptedCountLimit>
</forager>
</localSearch>
Config 2:
Second i looked at the documentation and found this hint that says that it is easier to deal with multiple planning entity classes if there are two different construction heuristic parts for each of them
http://docs.jboss.org/optaplanner/release/6.3.0.Final/optaplanner-docs/html_single/index.html#allocateEntityFromQueueMultipleEntityClasses
so i tried this configuration too.
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode> -->
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster
</solutionClass>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>org/optaplanner/examples/nurserostering/solver/nurseRosteringScoreRules.drl
</scoreDrl>
</scoreDirectorFactory>
<termination>
<!-- Official benchmark secondsSpentLimit allowed on: - ge0ffrey's main
pc: sprint 11, medium 700, long 42000 -->
<secondsSpentLimit>700</secondsSpentLimit>
<!--<bestScoreLimit>-0hard/-999999soft</bestScoreLimit> -->
</termination>
<constructionHeuristic>
<queuedEntityPlacer>
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
</unionMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<constructionHeuristic>
<queuedEntityPlacer>
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
</unionMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<!-- Move Selectors for ShiftAssignment this was the default configuration
from the example -->
<moveListFactory>
<cacheType>PHASE</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.EmployeeChangeMoveFactory
</moveListFactoryClass>
</moveListFactory>
<moveListFactory>
<cacheType>PHASE</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSwapMoveFactory
</moveListFactoryClass>
</moveListFactory>
<moveListFactory>
<cacheType>STEP</cacheType>
<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentPillarPartSwapMoveFactory
</moveListFactoryClass>
</moveListFactory>
<!-- besides this default configuration from optaplaner i also tried this here
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>-->
<!-- The move selectors for the second plannig entity class EmployeeSkillRequirement -->
<changeMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector>
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</entityClass>
</entitySelector>
<valueSelector>
<downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement
</downcastEntityClass>
<variableName>employee</variableName>
</valueSelector>
</swapMoveSelector>
</unionMoveSelector>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>800</acceptedCountLimit>
</forager>
</localSearch>
I also tried some other configurations that are similar to these ones, still, no luck.
How can i fix this and make it working?
Edit:
Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/nurserostering/solver/nurseRosteringSolverConfig.xml) fails.
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:114)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:66)
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.createSolver(NurseRosteringApp.java:50)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:90)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:77)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:73)
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.main(NurseRosteringApp.java:38)
Caused by: " com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelectorConfig.valueSelector
---- Debugging information ----
field : valueSelector
class : org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelect orConfig
required-type : org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelect orConfig
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 98
class[1] : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSel ectorConfig
class[2] : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
class[3] : org.optaplanner.core.config.solver.SolverConfig
version : 1.4.7
-------------------------------
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:114)
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:66)
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.createSolver(NurseRosteringApp.java:50)
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:90)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:77)
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:73)
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.main(NurseRosteringApp.java:38)
A common mistake is to add whitespace in classname properties that doesn't get parsed correctly. This fails during parsing:
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster
</solutionClass>
but this succeeds in getting parsed:
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster</solutionClass>

How do you run Multiple XMLA Alter Commands at the same time?

I have the following two XMLA alter commands that individually work fine. I would like to run them at the same time in SQL Management studio. I have tried wrapping them in command, batch, and a number of other elements. I can't seem to get anything to work correctly.
<Alter AllowCreate="true" ObjectExpansion="ObjectProperties" xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Object>
<DatabaseID>DB1</DatabaseID>
<RoleID>Role</RoleID>
</Object>
<ObjectDefinition>
<Role xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ddl2="http://schemas.microsoft.com/analysisservices/2003/engine/2" xmlns:ddl2_2="http://schemas.microsoft.com/analysisservices/2003/engine/2/2" xmlns:ddl100_100="http://schemas.microsoft.com/analysisservices/2008/engine/100/100" xmlns:ddl200="http://schemas.microsoft.com/analysisservices/2010/engine/200" xmlns:ddl200_200="http://schemas.microsoft.com/analysisservices/2010/engine/200/200" xmlns:ddl300="http://schemas.microsoft.com/analysisservices/2011/engine/300" xmlns:ddl300_300="http://schemas.microsoft.com/analysisservices/2011/engine/300/300" xmlns:ddl400="http://schemas.microsoft.com/analysisservices/2012/engine/400" xmlns:ddl400_400="http://schemas.microsoft.com/analysisservices/2012/engine/400/400">
<ID>Role</ID>
<Name>ReadersRole</Name>
<Members>
<Member>
<Name>Domain\ReaderUserName</Name>
</Member>
</Members>
</Role>
</ObjectDefinition>
</Alter>
<Alter AllowCreate="true" ObjectExpansion="ObjectProperties" xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<Object>
<DatabaseID>DB2</DatabaseID>
<RoleID>Role</RoleID>
</Object>
<ObjectDefinition>
<Role xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ddl2="http://schemas.microsoft.com/analysisservices/2003/engine/2" xmlns:ddl2_2="http://schemas.microsoft.com/analysisservices/2003/engine/2/2" xmlns:ddl100_100="http://schemas.microsoft.com/analysisservices/2008/engine/100/100" xmlns:ddl200="http://schemas.microsoft.com/analysisservices/2010/engine/200" xmlns:ddl200_200="http://schemas.microsoft.com/analysisservices/2010/engine/200/200" xmlns:ddl300="http://schemas.microsoft.com/analysisservices/2011/engine/300" xmlns:ddl300_300="http://schemas.microsoft.com/analysisservices/2011/engine/300/300" xmlns:ddl400="http://schemas.microsoft.com/analysisservices/2012/engine/400" xmlns:ddl400_400="http://schemas.microsoft.com/analysisservices/2012/engine/400/400">
<ID>Role</ID>
<Name>ReadersRole</Name>
<Members>
<Member>
<Name>Domain\ReaderUserName</Name>
</Member>
</Members>
</Role>
</ObjectDefinition>
</Alter>
Can you try just putting a
<Batch xmlns="http://schemas.microsoft.com/analysisservices/2003/engine"></Batch>
tag around them?

Using nearbySelection in VehicleRouting results in a Mimic exception

I'm trying to implement a CVRPTW based on the Optaplanner Vehiclerouting example (6.2.0-CR4).
Optaplanner is a great project to work with!
To speed up the search for a decent solution I started to experiment with nearbyselection. But when I configure the use of the CustomerNearbyDistanceMeter the following exception is thrown:
Exception in thread "1271a58a-a134-4b68-b485-f6e678307357" java.lang.IllegalStateException: Replay must occur after record. The recordingEntitySelector (Recording(Filtering(FromSolutionEntitySelector(Customer))))'s next() has not been called yet.
at org.optaplanner.core.impl.heuristic.selector.entity.mimic.MimicReplayingEntitySelector$ReplayingEntityIterator.next(MimicReplayingEntitySelector.java:104)
at org.optaplanner.core.impl.heuristic.selector.entity.nearby.NearEntityNearbyEntitySelector$RandomNearbyEntityIterator.next(NearEntityNearbyEntitySelector.java:203)
at org.optaplanner.core.impl.heuristic.selector.entity.decorator.FilteringEntitySelector$JustInTimeFilteringEntityIterator.createUpcomingSelection(FilteringEntitySelector.java:107)
at org.optaplanner.core.impl.heuristic.selector.common.iterator.UpcomingSelectionIterator.hasNext(UpcomingSelectionIterator.java:40)
at org.optaplanner.core.impl.heuristic.selector.common.iterator.AbstractRandomSwapIterator.(AbstractRandomSwapIterator.java:35)
at org.optaplanner.core.impl.heuristic.selector.move.generic.SwapMoveSelector$2.(SwapMoveSelector.java:125)
at org.optaplanner.core.impl.heuristic.selector.move.generic.SwapMoveSelector.iterator(SwapMoveSelector.java:125)
at org.optaplanner.core.impl.heuristic.selector.move.composite.UnionMoveSelector$RandomUnionMoveIterator.(UnionMoveSelector.java:140)
at org.optaplanner.core.impl.heuristic.selector.move.composite.UnionMoveSelector.iterator(UnionMoveSelector.java:125)
at org.optaplanner.core.impl.localsearch.decider.LocalSearchDecider.decideNextStep(LocalSearchDecider.java:112)
at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:66)
at org.optaplanner.core.impl.solver.DefaultSolver.runPhases(DefaultSolver.java:213)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:176)
at com.itmatic.optimisations.app.VehicleRoutingTask.run(VehicleRoutingTask.java:103)
I configured things as follows:
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<changeMoveSelector>
<entitySelector id="entitySelector1"/>
<filterClass>com.vos.optimisations.solver.move.CustomerChangeMoveFilter</filterClass>
<valueSelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector1"/>
<nearbyDistanceMeterClass>com.vos.optimisations.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<linearDistributionSizeMaximum>1000</linearDistributionSizeMaximum>
</nearbySelection>
</valueSelector>
</changeMoveSelector>
<swapMoveSelector>
<entitySelector id="entitySelector2"/>
<filterClass>com.vos.optimisations.solver.move.CustomerSwapMoveFilter</filterClass>
<secondaryEntitySelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector2"/>
<nearbyDistanceMeterClass>com.vos.optimisations.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
<linearDistributionSizeMaximum>1000</linearDistributionSizeMaximum>
</nearbySelection>
</secondaryEntitySelector>
</swapMoveSelector>
<swapMoveSelector/>
<subChainChangeMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
</subChainChangeMoveSelector>
<subChainSwapMoveSelector>
<selectReversingMoveToo>true</selectReversingMoveToo>
</subChainSwapMoveSelector>
</unionMoveSelector>
<acceptor>
<lateAcceptanceSize>600</lateAcceptanceSize>
</acceptor>
<forager>
<acceptedCountLimit>10</acceptedCountLimit>
</forager>
</localSearch>
</solver>
What does the exception mean and why is it being thrown?
UPDATE: I removed the filterclasses but the mimic exception is still being thrown.
The exception occures only when the SwapMoveSelector is in place!!