Error in nearbySelectorConfig for Local Search - optaplanner

I got this error trying to implement NearbySelector in Local Search.
The Local Search configuration. I tried with both random and original selection orders:
<changeMoveSelector>
<entitySelector id="entitySelector1"/>
<selectionOrder>ORIGINAL</selectionOrder>
<valueSelector>
<nearbySelection>
<originEntitySelector mimicSelectorRef="entitySelector1"/>
<nearbyDistanceMeterClass>NearbyGrainMeter</nearbyDistanceMeterClass>
<parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
</nearbySelection>
</valueSelector>
</changeMoveSelector>
Error:
java.lang.IllegalArgumentException: The nearbySelectorConfig (NearbySelectionConfig()) with randomSelection (false) has distribution parameters.
at org.optaplanner.core.config.heuristic.selector.common.nearby.NearbySelectionConfig.buildNearbyRandom(NearbySelectionConfig.java:226)
at org.optaplanner.core.config.heuristic.selector.common.nearby.NearbySelectionConfig.applyNearbyValueSelector(NearbySelectionConfig.java:205)
at org.optaplanner.core.config.heuristic.selector.value.ValueSelectorConfig.buildValueSelector(ValueSelectorConfig.java:293)
at org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig.buildBaseMoveSelector(ChangeMoveSelectorConfig.java:84)
at org.optaplanner.core.config.heuristic.selector.move.MoveSelectorConfig.buildMoveSelector(MoveSelectorConfig.java:252)
at org.optaplanner.core.config.heuristic.selector.move.MoveSelectorConfig.buildMoveSelector(MoveSelectorConfig.java:241)
at org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig.buildBaseMoveSelector(UnionMoveSelectorConfig.java:77)
at org.optaplanner.core.config.heuristic.selector.move.MoveSelectorConfig.buildMoveSelector(MoveSelectorConfig.java:252)
at org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig.buildMoveSelector(LocalSearchPhaseConfig.java:289)
at org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig.buildDecider(LocalSearchPhaseConfig.java:155)
at org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig.buildPhase(LocalSearchPhaseConfig.java:141)
at org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig.buildPhase(LocalSearchPhaseConfig.java:54)
at org.optaplanner.core.config.solver.SolverConfig.buildPhaseList(SolverConfig.java:446)
at org.optaplanner.core.config.solver.SolverConfig.buildSolver(SolverConfig.java:349)
at org.optaplanner.core.impl.solver.AbstractSolverFactory.buildSolver(AbstractSolverFactory.java:61)
at App.main(App.java:168)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:282)
at java.lang.Thread.run(Thread.java:748)```
Does anyone understand what is happening?

The nearby selection requires a RANDOM selection order, while your configuration of the ChangeMoveSelector specifies <selectionOrder>ORIGINAL</selectionOrder>.
Would you try changing it to: <selectionOrder>RANDOM</selectionOrder> ?

Related

Construction Heuristic Slow

My construction heuristic's calculation speed decreases alot over time, takes more than 5 minutes to run. I have about 25 resources to allocate 450 tasks. My current configuration for the construction heuristic is the following:
<constructionHeuristic>
<queuedValuePlacer>
<entityClass>pt.ferreiradesa.plantufting.planner.domain.Robot</entityClass>
<valueSelector id="1" variableName="prods">
</valueSelector>
<changeMoveSelector>
<filterClass>pt.ferreiradesa.plantufting.planner.domain.solver.ProdAssignMoveFilter</filterClass>
<selectedCountLimit>1</selectedCountLimit>
<valueSelector mimicSelectorRef="1" />
</changeMoveSelector>
</queuedValuePlacer>
</constructionHeuristic>
What I noticed is this configuration only uses about 3 of the 25 resources. So to try to randomize it a bit I tried the following configuration:
<constructionHeuristic>
<queuedEntityPlacer>
<entitySelector id="placerEntitySelector">
<entityClass>pt.ferreiradesa.plantufting.planner.domain.Robot</entityClass>
<cacheType>JUST_IN_TIME</cacheType>
<selectionOrder>RANDOM</selectionOrder>
</entitySelector>
<changeMoveSelector>
<filterClass>pt.ferreiradesa.plantufting.planner.domain.solver.ProdAssignMoveFilter</filterClass>
<entitySelector mimicSelectorRef="placerEntitySelector"/>
<valueSelector>
<cacheType>JUST_IN_TIME</cacheType>
<selectionOrder>RANDOM</selectionOrder>
<selectedCountLimit>1</selectedCountLimit>
</valueSelector>
</changeMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
But that throws me an error that it can't cast ListAssignMove to ListChangeMove. Even if I remove the filterclass, it throws me an indexoutofrange exception.
I'm using chained through time, so all I needed was to assign the tasks to the resources quickly in the construction heuristic. I even tried removing all the constraints, but the speed remains the same.

addProblemFactChange() stops working after "Bailing out of neverEnding selector (..) to avoid infinite loop."

I have in solverConfig.xml defined filterClasses
<localSearch>
<unionMoveSelector>
<changeMoveSelector>
<filterClass>...</filterClass>
</changeMoveSelector>
<swapMoveSelector>
<filterClass>...</filterClass>
</swapMoveSelector>
<tailChainSwapMoveSelector>
<filterClass>...</filterClass>
</tailChainSwapMoveSelector>
</unionMoveSelector>
(...)
<localSearch>
And in some cases, when there is no moves in log I can see WARN's:
Bailing out of neverEnding selector (..) to avoid infinite loop.
Which is fine, but after some changes are made and addProblemFactChange is called algoritms do not start working again. Restarting works fine, so it is some problem with this method.
solver.isSolving() is returning true.
What could be the reason for this behavior?

Effects of nested unionMoveSelectors in optaPlanner

During testing and benchmarking, I unintentionally introduced an additional level of unionMoveSelector in my xml solver configuration file:
<unionMoveSelector>
<unionMoveSelector>
<changeMoveSelector>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
<valueSelector variableName="start"/>
</changeMoveSelector>
<changeMoveSelector>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
<valueSelector variableName="duration"/>
</changeMoveSelector>
<swapMoveSelector>
<filterClass>io.solvice.shift.domain.ShiftAssignmentSwapFilter</filterClass>
<fixedProbabilityWeight>0.1</fixedProbabilityWeight>
</swapMoveSelector>
<swapMoveSelector>
<filterClass>io.solvice.shift.domain.EmployeeSwapFilter</filterClass>
<fixedProbabilityWeight>0.1</fixedProbabilityWeight>
</swapMoveSelector>
<moveIteratorFactory>
<fixedProbabilityWeight>0.1</fixedProbabilityWeight>
<moveIteratorFactoryClass>customMoveIteratorFactory1</moveIteratorFactoryClass>
</moveIteratorFactory>
<moveIteratorFactory>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
<moveIteratorFactoryClass>customMoveIteratorFactory2</moveIteratorFactoryClass>
</moveIteratorFactory>
</unionMoveSelector>
</unionMoveSelector>
Extensive testing (albeit on a single, hard-to-tackle instance) has shown that my solver performs better with this additional level than without.
Can someone please explain to me what this does and why it might outperform the other situation?

Nearby selection with subChainChangeMoveSelector or subChainSwapMoveSelector

Is there any way to enable nearby selection in Optaplanner for the subChainChangeMoveSelector or subChainSwapMoveSelector?
I have successfully enabled it for the tail move selector as follows:
<tailChainSwapMoveSelector>
<entitySelector id="tcsm1"/>
<valueSelector>
<variableName>prevReq</variableName>
<nearbySelection>
<originEntitySelector mimicSelectorRef="tcsm1"/>
<nearbyDistanceMeterClass>NearbyMeterTransportChain</nearbyDistanceMeterClass>
</nearbySelection>
</valueSelector>
</tailChainSwapMoveSelector>
However, the same config for any of the two chained movemenents returns an XStream error, explaining that neither of them can have a entitySelector.
I just checked, the docs chapter "Move and Neighborhood Selection" does document the advanced configuration of subchain change/swap move selectors. Take a look.

Multiple ValueSelector for one MoveSelector

How can i set multiple value selectors for one move selector in Optaplanner? the documentation says clearly that: "A MoveSelector is often composed out of EntitySelectors, ValueSelectors or even other MoveSelectors, which can be configured individually if desired", which i assume means multiple value selectors can be assigned to one move selector, which makes sense to me, however i get an unmarshalling error when trying that.
<unionMoveSelector>
<changeMoveSelector>
<entitySelector>
<entityClass>com.rdthree.plenty.domain.activity.Activity</entityClass>
</entitySelector>
<valueSelector>
<variableName>startTime</variableName>
</valueSelector>
<valueSelector>
<variableName>endTime</variableName>
</valueSelector> <--this is the line where the error stems from
<filterClass>myclass(don't want to say the name of it)</filterClass>
</changeMoveSelector>
</unionMoveSelector>
error:
java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (activitySolverConfig.xml) fails.
cause:
Caused by: com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field valueSelectorConfig
---- Debugging information ----
field : valueSelectorConfig
class : org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig
required-type : org.optaplanner.core.config.heuristic.selector.move.generic.ChangeMoveSelectorConfig
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
line number : 36
class[1] : org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSelectorConfig
class[2] : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig
class[3] : org.optaplanner.core.config.solver.SolverConfig
version : 1.4.7
-------------------------------
i'm not copying the entire error text but i can assure you it's referring to the fact that i have two value selectors.
A changeMoveSelector can only have 1 valueSelector currently.
I presume you want a cartesian product (otherwise you can use a unionMoveSelector) over those 2 changeMoveSelectors, so:
<cartesianProductMoveSelector>
<changeMoveSelector>
<entitySelector id="cartesianProductEntitySelector"/>>
<valueSelector>
<variableName>startTime</variableName>
</valueSelector>
</changeMoveSelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="cartesianProductEntitySelector"/>
<valueSelector>
<variableName>endTime</variableName>
</valueSelector>
</changeMoveSelector>
</cartesianProductMoveSelector>
This means that a single move (a CompositeMove) changes both the startTime and the endTime of 1 (and the same) entity. See docs section about cartesianProductMoveSelector and mimic selection for more info.
Note that this cartesianProductMoveSelector can be nested in a unionMoveSelector if desired to union those CompositeMoves with other moves.