[rules-users] [planner][5.3.0.Final] Benchmark
I'm trying to upgrade from drools 5.2.0 to 5.3.0 and having some difficulties with the planner benchmark. I'd like to make a set of move factories common to all local search solvers, by adding them to inheritedSolverBenchmark block. But it seems that the localSearch environment always requires a selector, so I can't specify the localSearch environment for the solverBenchmark's without providing a selector. Here's a piece of code that gives runtime error: http://paste.ubuntu.com/718806/ The error is: Exception in thread main java.lang.IllegalArgumentException: A selector requires configuration, for example a moveFactoryClass. --- Note --- If I understood correcly, the following configuration from examination examples: examinationStepLimitSolverBenchmarkConfig.xml contains a bug, because it specifies a maximum step count for a general solver termination maximumStepCount70/maximumStepCount /termination This gave the following exception: Exception in thread main java.lang.UnsupportedOperationException: StepCountTermination can only be used for phase termination. Thanks, ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] [planner] Performance question
2011/10/19 Geoffrey De Smet ge0ffrey.s...@gmail.com ** Op 19-10-11 15:00, Guilherme Kunigami schreef: In this use case, that is probably a bad idea in my experience. Why? Well I hope this makes any sense: *You need to allow the optimization algorithms to break it now and then to tunnel through a bad search space into another good search space.* If it doesn't, don't worry. Hmm, I think I understood it. Allowing infeasible solutions may help to scape from local minima in the space of feasible solutions for example. Yep :) rule Avoid conflicting activities when Assignment($room1 : room, $act1: activity, $id : activity.id) Assignment(room== $room1, room != null, $act2 : activity, activity.id $id) Conflict(act1 == $act1, act2 == $act2) I would put Conflict first. But try it this way too and let me know which works better ;) I don't know. Stated differently: Instead of checking every 2 simultaneous assignments if they are a conflict, I would check if every 2 conflict assignments are simultaneous (like in examinationScoreRules.drl). Ok! I will perform some stress tests to verify which one works better. Nice, please report your results to this mailing list. It doesn't matter if they are worse, better or equal: it's interesting to know. Look for stepLimit in the examples to see how I do very short stress tests when adding extra constraints. I've made a test with each model limited to 70 steps. I've attached a graph comparing both runs using drools planner benchmark. It seems that using Conflict first is indeed faster :) ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users attachment: solution2Statistic.png___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] [planner] Performance question
Consider I have a set of N activities with a given start and end times and I want to assign them to a set of rooms. One of the main rules is to avoid two activities that have time conflicts, to be assigned to the same room. I devised three modelling options: [1] Do it entirely in Java code, checking whether there will be a conflict before allowing an Assignment move. This way, all solutions that the algorithm works with are feasible. [2] Do it using drools rules, like the following: rule Avoid conflicting activities when Assignment($room1: room, $act1: activity, $id : activity.id) Assignment(room == $room1, room!= null, $act2 : activity, activity.id $id) eval(Activity.conflict($act1, $act2)) then insertLogical(new IntConstraintOccurrence(conflictingActivities, ConstraintType.NEGATIVE_HARD, 10, null)); end Here I'm using Assignment as the only planning entity. There's an assignment for each activity and it may point to a room or to null in the case the activity is not assigned. In the case above, I have a static function that checks whether two activities conflicts. This way, solutions may be infeasible but with high penalties the best solution found will eventually be feasible. I also thought of a third option, which is to insert a fact Conflict for each pair of conflicting activities in a preprocessing phase. This way we would end up with: rule Avoid conflicting activities when Assignment($room1 : room, $act1: activity, $id : activity.id) Assignment(room== $room1, room != null, $act2 : activity, activity.id $id) Conflict(act1 == $act1, act2 == $act2) then insertLogical(new IntConstraintOccurrence(conflictingActivities, ConstraintType.NEGATIVE_HARD, 10, null)); end The problem is that there may be up to O(N^2) such objects. I do not know the rules engine algorithm in depth, so I'd like to know: Is any of these approaches more efficient than the others? Thanks! ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] [planner] Performance question
2011/10/19 Geoffrey De Smet ge0ffrey.s...@gmail.com ** Op 19-10-11 14:16, Guilherme Kunigami schreef: Consider I have a set of N activities with a given start and end times and I want to assign them to a set of rooms. One of the main rules is to avoid two activities that have time conflicts, to be assigned to the same room. I devised three modelling options: [1] Do it entirely in Java code, checking whether there will be a conflict before allowing an Assignment move. This way, all solutions that the algorithm works with are feasible. In the manual that's called a build-in hard constraint. Look for it. In this use case, that is probably a bad idea in my experience. Why? Well I hope this makes any sense: *You need to allow the optimization algorithms to break it now and then to tunnel through a bad search space into another good search space.* If it doesn't, don't worry. Hmm, I think I understood it. Allowing infeasible solutions may help to scape from local minima in the space of feasible solutions for example. [2] Do it using drools rules, like the following: rule Avoid conflicting activities when Assignment($room1: room, $act1: activity, $id : activity.id) Assignment(room == $room1, room!= null, $act2 : activity, activity.id $id) eval(Activity.conflict($act1, $act2)) Why calculate it every time if you can cache it? [3] then insertLogical(new IntConstraintOccurrence(conflictingActivities, ConstraintType.NEGATIVE_HARD, 10, null)); end Here I'm using Assignment as the only planning entity. There's an assignment for each activity and it may point to a room or to null in the case the activity is not assigned. In the case above, I have a static function that checks whether two activities conflicts. This way, solutions may be infeasible but with high penalties the best solution found will eventually be feasible. [3] I also thought of a third option, which is to insert a fact Conflict for each pair of conflicting activities in a preprocessing phase. This way we would end up with: This is the recommended way. It's called cached problem facts in the manual. See the TopicConflict use in the examinationScoreRules.drl and Examination.getProblemFacts() in the examples. rule Avoid conflicting activities when Assignment($room1 : room, $act1: activity, $id : activity.id) Assignment(room== $room1, room != null, $act2 : activity, activity.id $id) Conflict(act1 == $act1, act2 == $act2) I would put Conflict first. But try it this way too and let me know which works better ;) I don't know. Stated differently: Instead of checking every 2 simultaneous assignments if they are a conflict, I would check if every 2 conflict assignments are simultaneous (like in examinationScoreRules.drl). Ok! I will perform some stress tests to verify which one works better. Thanks again, then insertLogical(new IntConstraintOccurrence(conflictingActivities, ConstraintType.NEGATIVE_HARD, 10, null)); end The problem is that there may be up to O(N^2) such objects. I do not know the rules engine algorithm in depth, so I'd like to know: Is any of these approaches more efficient than the others? [3] is definitely faster than [2]. Thanks! ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] [planner] Problem setting configuration file
Hi, 2011/10/14 Geoffrey De Smet ge0ffrey.s...@gmail.com ** I was wondering now if I can achieve the same with the drools rule file. That's a bit harder, but not that hard. Look in the Drools Planner manual for setRuleBase() (as an alternative to using scoreDrl's in your SolverConfig.xml) and look in the Drools Expert manual on how to create a RuleBase. Great, that worked too! Just for future reference, I used the following tutorial to create a rule base: http://hydrogen.informatik.tu-cottbus.de/wiki/index.php/How_to_create_and_execute_a_Drools_rulebase And http://docs.jboss.org/drools/release/5.2.0.Final/drools-planner-docs/html/ch04.html#d0e1566 to set the rule base. Thank you for the help! Op 13-10-11 15:37, Guilherme Kunigami schreef: Geoffrey, Thank you, that worked! I was wondering now if I can achieve the same with the drools rule file. The method below wouldn't work because it's not me who load the file (I think it's at AbstractSolverConfig.buildRuleBase, which seems to use getResourceAsStream too). 2011/10/11 Geoffrey De Smet ge0ffrey.s...@gmail.com Hi Guilharme, There's an overloaded method called configure(InputStream in) and configure(Reader reader) too, use either of those instead: try { InputStream in = new FileInputStream( /path/to/xml/file/SolverConf.xml); configurer.configure(in); } finally { IOUtils.closeSilently(in); } Op 11-10-11 15:01, Guilherme Kunigami schreef: Hi, I'm trying to load a configuration file (namely SolverConf.xml) into XmlSolver with the code below: XmlSolverConfigurer configurer = new XmlSolverConfigurer(); configurer.configure(SOLVER_CONFIG); Solver solver = configurer.buildSolver(); If I bundle SolverConf.xml file with the application .jar file, then using SOLVER_CONFIG as /path/to/xml/file/SolverConf.xml works fine. But I want to use SolverConf.xml outside the .jar, so I can easiliy edit it, but I don't know what path should I pass to it. I know it's a Java related question, but I was wondering if anyone had a similar problem when configuring drools planner. (I've asked on stackoverflow, but none of the answers worked for me: http://stackoverflow.com/questions/7718807/can-getresourceasstream-find-files-outside-the-jar-file ) (Supposing my .jar is in /some/path and the SolverConf.xml will be on /some/path/conf for example) Thanks, ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] [planner] The presumed score is corrupted
2011/10/14 Geoffrey De Smet ge0ffrey.s...@gmail.com ** In your doMove you're doing: crew.addActivity(activity); remainingActivities.remove(activity); If crew and/or remainingActivities are used by your score rules, the working memory should be notified of their changes. That's causing the corruption Hmm, actually the only object that are being used by the score rules is an activity. Here's the corresponding .drl: rule remainingActivitiesCount when $remainingCount : Number() from accumulate( $activity : ActivityBundle(), sum(1) ) then insertLogical(new IntConstraintOccurrence(remainingActivitiesCount, ConstraintType.NEGATIVE_HARD, $remainingCount.intValue(), null)); end Extra advice: I think you're making your moves too complex and your domain model too complex. If you upgrade to 5.3, it will be hard to identify the planning entities. There will be many (and I doubt you need more than 1). Read http://docs.jboss.org/drools/release/5.3.0.CR1/drools-planner-docs/html_single/index.html#d0e1411 and specificly this note in that chapter: *Do not create unnecessary planning entity classes.* This leads to difficult Move implementations and slower score calculation. For example, do not create a planning entity class to hold the total free time of a teacher, which needs to be kept up to date as the Lectureplanning entities change. Instead, calculate the free time in the score constraints and put the result per teacher into a logically inserted score object. If historic data needs to be considered too, then create problem fact to hold the historic data up to, but *not including*, the planning window (so it doesn't change when a planning entity changes) and let the score constraints take it into account. Thanks for the advice. I'll rethink my model and try to use a single planning entity. Op 14-10-11 15:48, Guilherme Kunigami schreef: 2011/10/14 Geoffrey De Smet ge0ffrey.s...@gmail.com Probably you forgot to notify the workingMemory.update in the doMove method: public void doMove(WorkingMemory workingMemory) { FactHandle factHandle = workingMemory.getFactHandle(activity); activity.setAssignee(...); workingMemory.update(factHandle, activity); } Op 14-10-11 09:21, Geoffrey De Smet schreef: A corrupted score normally indicates a problem with the Move implementation (or sometimes the score drl). Basically this happened: for a number of moves, it did the move, calculated the score and undo the move. One of those move was associated with a score -10hard/0soft, that was the best one. Now, it does that move (which is now called the step) and when it calculates the score it's a different score 0hard/0soft. Try TRACE environment and see if it crashes sooner. Copy paste your Move implementation here. Using the TRACE environment gave the same results of DEBUG. Here's my move implementation, as well as the snipet of drools rule file that calculates the score based on remaining activities: http://pastebin.mozilla.org/1355014 In Planner 5.4 there will be 2 out-of-the-box Move implementations to use, so writing Move's become optional. Cool! By the way, I'm using Drools 5.2.0 final. Thanks, Op 13-10-11 16:37, Guilherme Kunigami schreef: Hi, I've implemented a very simple application using drools planner consisting of a bunch of activities. My rule file is very simple too and just counts the number of activities not assigned. When I run Solver.solve(), I get the following error message: Exception in thread AWT-EventQueue-0 java.lang.IllegalStateException: The presumedScore (-10hard/0soft) is corrupted because it is not the realScore (0hard/0soft). Presumed workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (11). Real workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (0). I've tracked down this message and found this piece of code @DefaultLocalSearchSolver.solveImplementation(): // there is no need to recalculate the score, but we still need to set it localSearchSolverScope.getWorkingSolution().setScore(localSearchStepScope.getScore()); if (assertStepScoreIsUncorrupted) { localSearchSolverScope.assertWorkingScore(localSearchStepScope.getScore()); } It seems that the working score is never updated along the algorithm, but the score in the working memory changes. Thus, when we use the DEBUG environment, assertStepScoreIsUncorrupted is turned on and the assertion fails. Should the score be updated or am I using the library incorrectly? Thanks, ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet
Re: [rules-users] [planner] The presumed score is corrupted
2011/10/14 Geoffrey De Smet ge0ffrey.s...@gmail.com ** Probably you forgot to notify the workingMemory.update in the doMove method: public void doMove(WorkingMemory workingMemory) { FactHandle factHandle = workingMemory.getFactHandle(activity); activity.setAssignee(...); workingMemory.update(factHandle, activity); } Op 14-10-11 09:21, Geoffrey De Smet schreef: A corrupted score normally indicates a problem with the Move implementation (or sometimes the score drl). Basically this happened: for a number of moves, it did the move, calculated the score and undo the move. One of those move was associated with a score -10hard/0soft, that was the best one. Now, it does that move (which is now called the step) and when it calculates the score it's a different score 0hard/0soft. Try TRACE environment and see if it crashes sooner. Copy paste your Move implementation here. Using the TRACE environment gave the same results of DEBUG. Here's my move implementation, as well as the snipet of drools rule file that calculates the score based on remaining activities: http://pastebin.mozilla.org/1355014 In Planner 5.4 there will be 2 out-of-the-box Move implementations to use, so writing Move's become optional. Cool! By the way, I'm using Drools 5.2.0 final. Thanks, Op 13-10-11 16:37, Guilherme Kunigami schreef: Hi, I've implemented a very simple application using drools planner consisting of a bunch of activities. My rule file is very simple too and just counts the number of activities not assigned. When I run Solver.solve(), I get the following error message: Exception in thread AWT-EventQueue-0 java.lang.IllegalStateException: The presumedScore (-10hard/0soft) is corrupted because it is not the realScore (0hard/0soft). Presumed workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (11). Real workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (0). I've tracked down this message and found this piece of code @DefaultLocalSearchSolver.solveImplementation(): // there is no need to recalculate the score, but we still need to set it localSearchSolverScope.getWorkingSolution().setScore(localSearchStepScope.getScore()); if (assertStepScoreIsUncorrupted) { localSearchSolverScope.assertWorkingScore(localSearchStepScope.getScore()); } It seems that the working score is never updated along the algorithm, but the score in the working memory changes. Thus, when we use the DEBUG environment, assertStepScoreIsUncorrupted is turned on and the assertion fails. Should the score be updated or am I using the library incorrectly? Thanks, ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] [planner] Problem setting configuration file
Geoffrey, Thank you, that worked! I was wondering now if I can achieve the same with the drools rule file. The method below wouldn't work because it's not me who load the file (I think it's at AbstractSolverConfig.buildRuleBase, which seems to use getResourceAsStream too). 2011/10/11 Geoffrey De Smet ge0ffrey.s...@gmail.com ** Hi Guilharme, There's an overloaded method called configure(InputStream in) and configure(Reader reader) too, use either of those instead: try { InputStream in = new FileInputStream( /path/to/xml/file/SolverConf.xml); configurer.configure(in); } finally { IOUtils.closeSilently(in); } Op 11-10-11 15:01, Guilherme Kunigami schreef: Hi, I'm trying to load a configuration file (namely SolverConf.xml) into XmlSolver with the code below: XmlSolverConfigurer configurer = new XmlSolverConfigurer(); configurer.configure(SOLVER_CONFIG); Solver solver = configurer.buildSolver(); If I bundle SolverConf.xml file with the application .jar file, then using SOLVER_CONFIG as /path/to/xml/file/SolverConf.xml works fine. But I want to use SolverConf.xml outside the .jar, so I can easiliy edit it, but I don't know what path should I pass to it. I know it's a Java related question, but I was wondering if anyone had a similar problem when configuring drools planner. (I've asked on stackoverflow, but none of the answers worked for me: http://stackoverflow.com/questions/7718807/can-getresourceasstream-find-files-outside-the-jar-file ) (Supposing my .jar is in /some/path and the SolverConf.xml will be on /some/path/conf for example) Thanks, ___ rules-users mailing listrules-users@lists.jboss.orghttps://lists.jboss.org/mailman/listinfo/rules-users -- With kind regards, Geoffrey De Smet ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] [planner] The presumed score is corrupted
Hi, I've implemented a very simple application using drools planner consisting of a bunch of activities. My rule file is very simple too and just counts the number of activities not assigned. When I run Solver.solve(), I get the following error message: Exception in thread AWT-EventQueue-0 java.lang.IllegalStateException: The presumedScore (-10hard/0soft) is corrupted because it is not the realScore (0hard/0soft). Presumed workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (11). Real workingMemory: Score rule (remainingActivitiesCount) has count (1) and weight total (0). I've tracked down this message and found this piece of code @DefaultLocalSearchSolver.solveImplementation(): // there is no need to recalculate the score, but we still need to set it localSearchSolverScope.getWorkingSolution().setScore(localSearchStepScope.getScore()); if (assertStepScoreIsUncorrupted) { localSearchSolverScope.assertWorkingScore(localSearchStepScope.getScore()); } It seems that the working score is never updated along the algorithm, but the score in the working memory changes. Thus, when we use the DEBUG environment, assertStepScoreIsUncorrupted is turned on and the assertion fails. Should the score be updated or am I using the library incorrectly? Thanks, ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] [planner] Problem setting configuration file
Hi, I'm trying to load a configuration file (namely SolverConf.xml) into XmlSolver with the code below: XmlSolverConfigurer configurer = new XmlSolverConfigurer(); configurer.configure(SOLVER_CONFIG); Solver solver = configurer.buildSolver(); If I bundle SolverConf.xml file with the application .jar file, then using SOLVER_CONFIG as /path/to/xml/file/SolverConf.xml works fine. But I want to use SolverConf.xml outside the .jar, so I can easiliy edit it, but I don't know what path should I pass to it. I know it's a Java related question, but I was wondering if anyone had a similar problem when configuring drools planner. (I've asked on stackoverflow, but none of the answers worked for me: http://stackoverflow.com/questions/7718807/can-getresourceasstream-find-files-outside-the-jar-file ) (Supposing my .jar is in /some/path and the SolverConf.xml will be on /some/path/conf for example) Thanks, ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users