在某些情况下,但并非总是如此,看似随机,并且使用完全相同的配置,Optaplanner在它的secondsSpentLimit课程之后不会终止。它只是挂起了" INFO --- [main] .cicDefaultConstructionHeuristicPhase:构建启发式阶段(1)结束:步骤总计(0),花费的时间(1507),最佳得分(-9hard / 0soft)和#34 ;
这是我的配置:
<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.TaskPlannerDto</entityClass>
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.TaskResourceAllocationPlannerDto</entityClass>
<!-- Score configuration -->
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>com/rdthree/plenty/services/activities/planner/activity-scoring.drl</scoreDrl>
<initializingScoreTrend>ONLY_DOWN</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.TaskResourceAllocationPlannerDto</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="taskSelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.TaskPlannerDto</entityClass>
<cacheType>PHASE</cacheType>
<selectionOrder>SORTED</selectionOrder>
<sorterManner>DECREASING_DIFFICULTY_IF_AVAILABLE</sorterManner>
</entitySelector>
<changeMoveSelector>
<entitySelector mimicSelectorRef="taskSelector" />
<filterClass>com.rdthree.plenty.services.activities.planner.TaskLengthChnageFilter</filterClass>
<valueSelector>
<variableName>interval</variableName>
<cacheType>PHASE</cacheType>
</valueSelector>
</changeMoveSelector>
</queuedEntityPlacer>
</constructionHeuristic>
<localSearch>
<unionMoveSelector>
<moveListFactory>
<moveListFactoryClass>com.rdthree.plenty.services.activities.planner.MoveResourceAllocationMoveFactory</moveListFactoryClass>
</moveListFactory>
<changeMoveSelector>
<fixedProbabilityWeight>1.0</fixedProbabilityWeight>
<filterClass>com.rdthree.plenty.services.activities.planner.TaskLengthChnageFilter</filterClass>
<entitySelector id="taskMoveSelector">
<entityClass>com.rdthree.plenty.services.activities.helpers.dtos.TaskPlannerDto</entityClass>
</entitySelector>
<valueSelector>
<variableName>interval</variableName>
</valueSelector>
</changeMoveSelector>
</unionMoveSelector>
<acceptor>
<valueTabuSize>7</valueTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>2000</acceptedCountLimit>
</forager>
</localSearch>
我还有一个移动过滤器:
public class TaskLengthChnageFilter implements SelectionFilter<ChangeMove> {
@SuppressWarnings("unchecked")
@Override
public boolean accept(ScoreDirector scoreDirector, ChangeMove selection) {
// get the solution
Solution<HardSoftScore> solution = scoreDirector.getWorkingSolution();
List<TaskRequirementsMapper> taskRequirementsMappers = new ArrayList<>();
// find the taskRequirementsMappers in the problem facts
for (Object fact : solution.getProblemFacts()) {
if (fact instanceof TaskRequirementsMapper) {
taskRequirementsMappers.add((TaskRequirementsMapper) fact);
}
}
for (Object obj : selection.getPlanningEntities()) {
TaskPlannerDto task;
Interval interval = null;
// get a task move
if (TaskPlannerDto.class.equals(obj.getClass())) {
// get the planning value (i.e the resource that is being changed in the allocation)
for (Object thePvalue : selection.getPlanningValues()) {
// the collection should only hold one value so take it and break
interval = (Interval) thePvalue;
break;
}
task = (TaskPlannerDto) obj;
// iterate over all the task requirement mappers
for (TaskRequirementsMapper taskRequirementsMapper : taskRequirementsMappers) {
// and find the one relevant for this allocation
if (task.getId().equals(taskRequirementsMapper.getTaskId())) {
// check
int newLength = interval.toPeriod().getDays();
int oldLength = taskRequirementsMapper.getLength();
if (newLength != oldLength) {
return false;
} else {
return true;
}
}
}
}
else {
return false;
}
}
return true;
}
}
这里是使用kill -3 PID杀死进程后的线程转储。此外,跟踪日志消息:
2015-09-18 12:36:05.079 INFO --- [ main] o.d.c.k.builder.impl.KieRepositoryImpl : KieModule was added:MemoryKieModule[ ReleaseId=org.default:artifact:1.0.0-SNAPSHOT]
2015-09-18 12:36:05.414 INFO --- [ main] o.o.core.impl.solver.DefaultSolver : Solving started: time spent (155), best score (-9hard/0soft), environment mode (FULL_ASSERT), random (JDK with seed 0).
2015-09-18 12:36:05.425 INFO --- [ main] o.o.c.a.s.event.SolverEventListener : New Best Solution Found with score : -9hard/0soft
2015-09-18 12:36:05.426 INFO --- [ main] .c.i.c.DefaultConstructionHeuristicPhase : Construction Heuristic phase (0) ended: step total (0), time spent (167), best score (-9hard/0soft).
2015-09-18 12:36:05.436 INFO --- [ main] o.o.c.a.s.event.SolverEventListener : New Best Solution Found with score : -9hard/0soft
2015-09-18 12:36:05.436 INFO --- [ main] .c.i.c.DefaultConstructionHeuristicPhase : Construction Heuristic phase (1) ended: step total (0), time spent (177), best score (-9hard/0soft).
2015-09-18 12:36:05.446 TRACE --- [ main] .m.f.MoveListFactoryToMoveSelectorBridge : Created cachedMoveList: size (60), moveSelector (MoveListFactory(class com.rdthree.plenty.services.activities.planner.MoveResourceAllocationMoveFactory)).
2015-09-18 12:39:16
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.79-b02 mixed mode):
"WeakCollectionCleaner" daemon prio=5 tid=0x00007f954e143800 nid=0xd507 in Object.wait() [0x0000000115f09000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007840964c0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x00000007840964c0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at org.geotools.util.WeakCollectionCleaner.run(WeakCollectionCleaner.java:77)
"GT authority factory disposer" daemon prio=5 tid=0x00007f954ca1e800 nid=0xd207 in Object.wait() [0x0000000116093000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007840ea820> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000007840ea820> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"AWT-AppKit" daemon prio=5 tid=0x00007f954e552800 nid=0x713 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"java-sdk-http-connection-reaper" daemon prio=5 tid=0x00007f954d69a000 nid=0x5b03 waiting on condition [0x0000000115667000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.amazonaws.http.IdleConnectionReaper.run(IdleConnectionReaper.java:112)
"Abandoned connection cleanup thread" daemon prio=5 tid=0x00007f954e0b5800 nid=0x5903 in Object.wait() [0x0000000115bba000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007816e4b98> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x00000007816e4b98> (a java.lang.ref.ReferenceQueue$Lock)
at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)
"Tomcat JDBC Pool Cleaner[1625026637:1442568952184]" daemon prio=5 tid=0x00007f954e11e800 nid=0x5807 in Object.wait() [0x00000001157d3000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007814885e0> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:552)
- locked <0x00000007814885e0> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:505)
"ReaderThread" prio=5 tid=0x00007f954e08d800 nid=0x5103 runnable [0x00000001152ed000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
- locked <0x000000078056f568> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
- locked <0x000000078056f568> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner$ReaderThread.run(RemoteTestRunner.java:135)
"Service Thread" daemon prio=5 tid=0x00007f954e011000 nid=0x4d03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007f954c089000 nid=0x4b03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007f954c072000 nid=0x4903 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007f954c02a000 nid=0x3c13 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007f954c06f800 nid=0x3503 in Object.wait() [0x00000001125db000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000078056a588> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x000000078056a588> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" daemon prio=5 tid=0x00007f954c06f000 nid=0x3303 in Object.wait() [0x00000001124d8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000780597940> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
- locked <0x0000000780597940> (a java.lang.ref.Reference$Lock)
"main" prio=5 tid=0x00007f954c02c800 nid=0x1303 runnable [0x0000000103374000]
java.lang.Thread.State: RUNNABLE
at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMoveSelector$RandomChangeMoveIterator.createUpcomingSelection(ChangeMoveSelector.java:166)
at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMoveSelector$RandomChangeMoveIterator.createUpcomingSelection(ChangeMoveSelector.java:129)
at org.optaplanner.core.impl.heuristic.selector.common.iterator.UpcomingSelectionIterator.hasNext(UpcomingSelectionIterator.java:40)
at org.optaplanner.core.impl.heuristic.selector.move.decorator.FilteringMoveSelector$JustInTimeFilteringMoveIterator.createUpcomingSelection(FilteringMoveSelector.java:90)
at org.optaplanner.core.impl.heuristic.selector.move.decorator.FilteringMoveSelector$JustInTimeFilteringMoveIterator.createUpcomingSelection(FilteringMoveSelector.java:77)
at org.optaplanner.core.impl.heuristic.selector.common.iterator.UpcomingSelectionIterator.hasNext(UpcomingSelectionIterator.java:40)
at org.optaplanner.core.impl.heuristic.selector.move.composite.UnionMoveSelector$RandomUnionMoveIterator.refreshMoveIteratorMap(UnionMoveSelector.java:183)
at org.optaplanner.core.impl.heuristic.selector.move.composite.UnionMoveSelector$RandomUnionMoveIterator.hasNext(UnionMoveSelector.java:159)
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.rdthree.plenty.services.activities.auto_scheduler.AutoSchedulerServiceBean.autoSchedule(AutoSchedulerServiceBean.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy227.autoSchedule(Unknown Source)
at com.rdthree.plenty.threads.SchedulerThread.run(SchedulerThread.java:104)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at com.rdthree.plenty.services.notifications.TestNotificationService.testSchedulerThreadFailNotification(TestNotificationService.java:578)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at com.rdthree.plenty.PlentyGeneralTest$RetryRule$1.eval(PlentyGeneralTest.java:46)
at com.rdthree.plenty.PlentyGeneralTest$RetryRule$1.evaluate(PlentyGeneralTest.java:56)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
"VM Thread" prio=5 tid=0x00007f954d00d800 nid=0x3103 runnable
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007f954c038800 nid=0x2103 runnable
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007f954c039000 nid=0x2303 runnable
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007f954c03a000 nid=0x2503 runnable
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007f954c03a800 nid=0x2703 runnable
"GC task thread#4 (ParallelGC)" prio=5 tid=0x00007f954d000800 nid=0x2903 runnable
"GC task thread#5 (ParallelGC)" prio=5 tid=0x00007f954d001000 nid=0x2b03 runnable
"GC task thread#6 (ParallelGC)" prio=5 tid=0x00007f954d001800 nid=0x2d03 runnable
"GC task thread#7 (ParallelGC)" prio=5 tid=0x00007f954d002800 nid=0x2f03 runnable
"VM Periodic Task Thread" prio=5 tid=0x00007f954e010000 nid=0x4f03 waiting on condition
JNI global references: 697
Heap
PSYoungGen total 698880K, used 154259K [0x00000007d5500000, 0x0000000800000000, 0x0000000800000000)
eden space 698368K, 22% used [0x00000007d5500000,0x00000007deba4f78,0x00000007fff00000)
from space 512K, 0% used [0x00000007fff00000,0x00000007fff00000,0x00000007fff80000)
to space 512K, 0% used [0x00000007fff80000,0x00000007fff80000,0x0000000800000000)
ParOldGen total 349696K, used 92182K [0x0000000780000000, 0x0000000795580000, 0x00000007d5500000)
object space 349696K, 26% used [0x0000000780000000,0x0000000785a05be8,0x0000000795580000)
PSPermGen total 131072K, used 85162K [0x0000000700000000, 0x0000000708000000, 0x0000000780000000)
object space 131072K, 64% used [0x0000000700000000,0x000000070532ab80,0x0000000708000000)
答案 0 :(得分:0)
我敢打赌它不是随机的:如果在构造启发式结束之前满足终止条件,它将终止。但是,如果它到达本地搜索阶段(或本地搜索阶段的特定移动选择器),它就会卡住。
我看到2个场景:
如果您的自定义MoveListFactory
或自定义MoveFilter
卡在无限循环中,则OptaPlanner不会终止。当JVM 线程转储(在控制台中使用ctrl-break,或IntelliJ控制台中的那个按钮)时,如果它没有终止以查找当前运行代码的堆栈跟踪,那么这样做。
如果您的自定义MoveFilter
不接受任何移动,则不会选择任何移动,因此不评估移动。打开警告xor跟踪日志记录(请参阅optaplanner文档)。在警告日志记录中,如果发生这种情况,它将显示救助警告。在跟踪日志记录中,它将显示当它被卡住时没有评估任何移动(因此没有跟踪消息)。