Today I have started to work with OptaPlanner. To say the truth, I already started reading the documentation a few days ago. But today I wanted to start implementing a first application.
So what is OptaPlanner and why do I want to test it. My first contact with OptaPlanner had been a few weeks ago, when looking for planning and optimization frameworks based on Java. Currently the system I am developing is using a Java implementation of FF planner - the implementation is pure and very hard to maintain. This is the reason I am looking for a better more flexible solution of a planning system. I am not sure if OptaPlanner fulfills the requirements. At the moment I am formulating my problems using PDDL (Planning Domain Definition Language). But I will talk about this later.
So now lets get started - or rather lets get the examples running. First we create a new eclipse maven project. Next we add the optaplanner core dependency:
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>${optaplanner.version}</version>
</dependency>
The version I am using is 6.0.0.Beta3. Next thing I wanted to do is to add the example sources of the optaplanner homepage. So after downloading and extracting the archive, we just copy the source code into the eclipse project... and get a lot of problems.
One problem is the missing XStreamScoreConverter class, which is part of the optaplanner-benchmark module. Hence, we add this one to the project, which solve some of our problems. But still we have some more errors. Some missing classes of the org.jdom package are the problem. So we have to add one more dependency (I got the version information from the example module of optaplanner).
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
...and finally no more problems. Getting the examples to work require two more things. First you have to copy the resources into your eclipse resource folder. Second you have to copy the example data (the folder is named data as well) into your project. That's it. Now I could finally run the examples and inspect the source code. As you can see in the following picture everything works fine for me now.
So that's it for now... more to come... I will try to understand what is happing and how it works.
Java Programming Experiences
Donnerstag, 6. Juni 2013
Mittwoch, 5. Juni 2013
Drools presentation
When I started writing about Drools in this blog, I wrote that I have to prepare a presentation. And this presentation is finally done. I uploaded it to slideshare. You can watch it here - beware it is in German.
If you like it, or you want to use some of the stuff inside, I would be very happy if you could inform me and also add a reference to my blog. If you want to have a PDF version just contact me.
If you like it, or you want to use some of the stuff inside, I would be very happy if you could inform me and also add a reference to my blog. If you want to have a PDF version just contact me.
Drools Part 4 - Decision Tables
When taking a look at the Drools documentation, the second chapter deals with decision tables. So I thought, it is time to take a look into this topic. Instead of using the previously presented DRL files and the MVEL-syntax to formulate rules, Drools also supports so called decision tables. Refering to the documentation "Decision tables are a 'precise yet compact' (ref. Wikipedia) way of representing conditional logic, and are well
suited to business level rules". If you want to get more detailled information just take a look at chapter 2.4 of the Drools documentation or go on with reading this post.
So I took a deeper look into this function. After a first look it seems to be a really interesting and compact way to formulate rules. In my sensor scenario I wanted to use this feature, to identify different "levels" of a measurement. Starting with a simple example it should be something like:
A decision table consists of a rule set that contains the definition of the used types, imports etc. and the rule tables. The rule set looks like shown in the picture:
It is as easy as it looks. The rule table is also very easy to set up. The following picture shows the solution for the above rule set.
That’s all what we have to do. Now let’s change our source code, so that the decision table is loaded instead. We have to start the same way as before by creating the KnowledgeBuilder.
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
Next we have to add the resource. Because we are using a decision table, the resource path as well as the type of the resource has to be updated. The rest is similar to the initialization of a knowledge base.
kbuilder.add(ResourceFactory.newClassPathResource(
"/dt_example.xls", ResourceType.DTABLE, dtc);
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
One important thing is the dtc variable. This one contains the so-called decision table configuration. It is created using the KnowledgeBuilderFactory.
DecisionTableConfiguration dtc =
KnowledgeBuilderFactory.newDecisionTableConfiguration();
dtc.setInputType(DecisionTableInputType.XLS);
dtc.setWorksheetName(“Sheet 1”);
That’s it. Have fun.
So I took a deeper look into this function. After a first look it seems to be a really interesting and compact way to formulate rules. In my sensor scenario I wanted to use this feature, to identify different "levels" of a measurement. Starting with a simple example it should be something like:
- when measured value > 0 and <= 50 then set quality level to normal and debug
- when measured value > 50 and <= 100 then set quality level to high and debug
- when measured value > 101 then set quality level to critical and debug
A decision table consists of a rule set that contains the definition of the used types, imports etc. and the rule tables. The rule set looks like shown in the picture:
It is as easy as it looks. The rule table is also very easy to set up. The following picture shows the solution for the above rule set.
That’s all what we have to do. Now let’s change our source code, so that the decision table is loaded instead. We have to start the same way as before by creating the KnowledgeBuilder.
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
Next we have to add the resource. Because we are using a decision table, the resource path as well as the type of the resource has to be updated. The rest is similar to the initialization of a knowledge base.
kbuilder.add(ResourceFactory.newClassPathResource(
"/dt_example.xls", ResourceType.DTABLE, dtc);
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
One important thing is the dtc variable. This one contains the so-called decision table configuration. It is created using the KnowledgeBuilderFactory.
DecisionTableConfiguration dtc =
KnowledgeBuilderFactory.newDecisionTableConfiguration();
dtc.setInputType(DecisionTableInputType.XLS);
dtc.setWorksheetName(“Sheet 1”);
That’s it. Have fun.
Donnerstag, 23. Mai 2013
Drools Part 3 - The Power of rules
Currently I am quite happy.
This was easier as expected. When I first took a look at the JBoss Drools
Website I just got the impression, that this could be something cool, but I did
not get the point where to start? But as I said this is not the first time I am
using Drools. So I have been there and after some internet research I found
multiple examples to get some small examples running.
Enough gibberish let's start to check out other things about rules. So what I did not like about the previous rule and test was that we have to set the limit value in the test as well as in the rule. Normally such a value should be configurable, so it has to be set. Therefore, we can use global variables in Drools. Taking a look at the documentation at http://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html/ch04.html#d0e4569 you get the idea behind global variabless and also some possibilities to misuse them :-).
global Double ALERTVALUE
rule "Critical value"
when
$v : SensorValue ( value > ALERTVALUE)
then
System.err.println("Critical sensor value");
end
No we can inject the value of alertValue into the rule, by using the setGlobal method of our session.
ksession.setGlobal("ALERTVALUE", 50.0);
When testing this rule, I also tried double and int as data types, as for example suggested by Jeremy, other books and some blogs. For me it did not work. I do not know why, but I got a parsing exception (unknown class).
Another thing is that we can bind variables:
rule "Critical value"
when
SensorValue ($id : sensorId)
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value in " + $id);
end
As you can see, it is possible to bind the sensor id to the variable §id and use it in the consequence. This rule shows another interesting thing about rules. When firing rules, the number of fired rules is returned as result of the method call. When using this rule, I got 10000 fired rules, but I only inserted 100 sensor values. The reason for this behavior is the cross product which is the result of the join. So instead of writing rules this way, the size of the cross product should be minimized.
global Double alertValue
rule "Critical value"
when
$v : SensorValue ( value > alertValue, $id : sensorId )
then
System.err.println("Critical sensor value in " + $id);
end
Another possibility is to use the getter of the bound object.
System.err.println("Critical sensor value in " +
$v.getSensorId());
Well, there is so much more about rules and their configuration. I will extend this post in the future, but there are other things to explore, for example decision tables.
Enough gibberish let's start to check out other things about rules. So what I did not like about the previous rule and test was that we have to set the limit value in the test as well as in the rule. Normally such a value should be configurable, so it has to be set. Therefore, we can use global variables in Drools. Taking a look at the documentation at http://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html/ch04.html#d0e4569 you get the idea behind global variabless and also some possibilities to misuse them :-).
global Double ALERTVALUE
rule "Critical value"
when
$v : SensorValue ( value > ALERTVALUE)
then
System.err.println("Critical sensor value");
end
No we can inject the value of alertValue into the rule, by using the setGlobal method of our session.
ksession.setGlobal("ALERTVALUE", 50.0);
When testing this rule, I also tried double and int as data types, as for example suggested by Jeremy, other books and some blogs. For me it did not work. I do not know why, but I got a parsing exception (unknown class).
Another thing is that we can bind variables:
rule "Critical value"
when
SensorValue ($id : sensorId)
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value in " + $id);
end
As you can see, it is possible to bind the sensor id to the variable §id and use it in the consequence. This rule shows another interesting thing about rules. When firing rules, the number of fired rules is returned as result of the method call. When using this rule, I got 10000 fired rules, but I only inserted 100 sensor values. The reason for this behavior is the cross product which is the result of the join. So instead of writing rules this way, the size of the cross product should be minimized.
global Double alertValue
rule "Critical value"
when
$v : SensorValue ( value > alertValue, $id : sensorId )
then
System.err.println("Critical sensor value in " + $id);
end
Another possibility is to use the getter of the bound object.
System.err.println("Critical sensor value in " +
$v.getSensorId());
Well, there is so much more about rules and their configuration. I will extend this post in the future, but there are other things to explore, for example decision tables.
Drools Post 2 - The first Drool rule
I said, I will use Eclipse as IDE (or more precisely I will use Spring Tool Suite (STS) because I am using Spring quite often). Besides, Maven is required. Now lets start.
I just installed the JBoss Drools Plugin using the update site (http://download.jboss.org/drools/release/5.5.0.Final/org.drools.updatesite/). As you can see I am using 5.5.0.Final and not 6.0.0 because currently it has BETA status. Also there seems to be some problems when using Java 7, because the plugin is not working with compiled classes of the newest Java version.
After the installation of the plugin there should be some new possibilities. For example when you create a new file in your project, it should be possible to select Drools resources.
Now lets use on of these new possibilites. Lets create a new "Drools Project". I named it "drools-playground". I hate if some framework or library requires the creation of a project. Perhaps I want to use different frameworks or tools within one project... but lets see. We have to create a new Drools Runtime (seems to be some kind of library folder). After this is done we have our project. I just added the Spring nature (which works fine), but after I tried to add a Maven nature to the project nothing works :) - or perhaps I just have to wait.
It seems that Jeremy (from the book) had the same idea, so instead of creating a Drools Project, he creates a maven project from the scratch. I think, this is what I should have done from the beginning.
So lets do it... for me its always interesting which artifacts are required to get started, so I will post them here. Remember this is just to get started with drools:
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools.version}</version>
</dependency>
I use a property to set the version of drools. Just to make it complete, here is it:
<properties>
<drools.version>5.5.0.Final</drools.version>
</properties>
This is more the way I like it. So whats next, we should start with a small example right.So what do I want to do... well because I am doing lots of stuff in production industry lets use an example from this domain. I want to monitor sensor values. So just a simple rule:
Finally I have to classes SensorValue and SensorSimulator. A sensor value has a timestamp, a value and an id. Just to make it a little bit more interesting the type of the value is generic. The sensor simulator simple creates a sensor value each time his method nextValue() is called. After I cleanup my stuff I will upload the source code, so if anyone out there reads this and wants to use the produced stuff feel free :-).
package net.meisen.sensor
import net.meisen.sensor.simulation.SensorValue
rule "Critical value"
when
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value state.");
end
That was very easy. The rule is formulated using the MVFLEX Expresison Language. It consists of a package name, the required imports (in my case the POJO) and the rules. A rule contains a when part and a then part.
public class RuleTest {
private BasicSensorSimulator<Double> simulator;
private StatefulKnowledgeSession ksession;
@Before
public void init() {
simulator = new BasicSensorSimulator<Double>();
simulator.setRange(new DoubleRange(51.0, 100.0));
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("/rules
/sensor_value_rule.drl", SensorValue.class),
ResourceType.DRL);
if (kbuilder.hasErrors()) {
System.err.println(kbuilder.getErrors().toString());
fail();
}
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.
getKnowledgePackages());
ksession = kbase.newStatefulKnowledgeSession();
}
@Test
public void testRule() {
ksession.insert(simulator.nextValue());
ksession.fireAllRules();
ksession.dispose();
}
Very simple, but it does what it has to do. I get the expected warning:
Critical sensor value state.
What have I done? First I created a KnowledgeBuilder, which is responsible, as far as I understand, for loading and transforming the rules, so that the knowlege packages become available. These packages are used to create the knowledge base or more precisely to initializes it. Finally, this knowledge base can provide us with session. One important thing is that, in the example, I am using a stateful session. In contradiction to a stateless session such a session remembers changes when rules are fired and checks if such a change result in new evaluation results for already checked rules.
During the test I just insert some data into the session and trigger the rule engine to fire the different rules. Firing a rule means to check if the conditions are fulfilled and if something has to be done.As Jeremy points out: "Whenever you work with a session, it's important to always remember to use the dispose() function to dispose of it when you're done. If you don't, the garbage collector won't be able to free up the resources for you, and that means problems."
I just installed the JBoss Drools Plugin using the update site (http://download.jboss.org/drools/release/5.5.0.Final/org.drools.updatesite/). As you can see I am using 5.5.0.Final and not 6.0.0 because currently it has BETA status. Also there seems to be some problems when using Java 7, because the plugin is not working with compiled classes of the newest Java version.
After the installation of the plugin there should be some new possibilities. For example when you create a new file in your project, it should be possible to select Drools resources.
Now lets use on of these new possibilites. Lets create a new "Drools Project". I named it "drools-playground". I hate if some framework or library requires the creation of a project. Perhaps I want to use different frameworks or tools within one project... but lets see. We have to create a new Drools Runtime (seems to be some kind of library folder). After this is done we have our project. I just added the Spring nature (which works fine), but after I tried to add a Maven nature to the project nothing works :) - or perhaps I just have to wait.
It seems that Jeremy (from the book) had the same idea, so instead of creating a Drools Project, he creates a maven project from the scratch. I think, this is what I should have done from the beginning.
So lets do it... for me its always interesting which artifacts are required to get started, so I will post them here. Remember this is just to get started with drools:
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools.version}</version>
</dependency>
I use a property to set the version of drools. Just to make it complete, here is it:
<properties>
<drools.version>5.5.0.Final</drools.version>
</properties>
This is more the way I like it. So whats next, we should start with a small example right.So what do I want to do... well because I am doing lots of stuff in production industry lets use an example from this domain. I want to monitor sensor values. So just a simple rule:
- when a sensor measures a value greater than 50.0 then show a warning message
Finally I have to classes SensorValue and SensorSimulator. A sensor value has a timestamp, a value and an id. Just to make it a little bit more interesting the type of the value is generic. The sensor simulator simple creates a sensor value each time his method nextValue() is called. After I cleanup my stuff I will upload the source code, so if anyone out there reads this and wants to use the produced stuff feel free :-).
A first rule
Now the interesting part begins. After doing the necessary POJO and programming stuff, I want to formulate the rule. First a so called DRL file has to be generated. This can either be done in the simple way, by using the Eclipse Text Editor or by using the more comfortable Eclipse PlugIn. Because I installed the plugin and I wanted to see what this plugin can do, I will use this method. I also created a folder src/main/rules to store my rules at this location. So here is the rule:package net.meisen.sensor
import net.meisen.sensor.simulation.SensorValue
rule "Critical value"
when
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value state.");
end
That was very easy. The rule is formulated using the MVFLEX Expresison Language. It consists of a package name, the required imports (in my case the POJO) and the rules. A rule contains a when part and a then part.
Getting it to work
Now to test my little rule, I want to use a test. So I have an initialization and the tests.public class RuleTest {
private BasicSensorSimulator<Double> simulator;
private StatefulKnowledgeSession ksession;
@Before
public void init() {
simulator = new BasicSensorSimulator<Double>();
simulator.setRange(new DoubleRange(51.0, 100.0));
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("/rules
/sensor_value_rule.drl", SensorValue.class),
ResourceType.DRL);
if (kbuilder.hasErrors()) {
System.err.println(kbuilder.getErrors().toString());
fail();
}
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.
getKnowledgePackages());
ksession = kbase.newStatefulKnowledgeSession();
}
@Test
public void testRule() {
ksession.insert(simulator.nextValue());
ksession.fireAllRules();
ksession.dispose();
}
Very simple, but it does what it has to do. I get the expected warning:
Critical sensor value state.
What have I done? First I created a KnowledgeBuilder, which is responsible, as far as I understand, for loading and transforming the rules, so that the knowlege packages become available. These packages are used to create the knowledge base or more precisely to initializes it. Finally, this knowledge base can provide us with session. One important thing is that, in the example, I am using a stateful session. In contradiction to a stateless session such a session remembers changes when rules are fired and checks if such a change result in new evaluation results for already checked rules.
During the test I just insert some data into the session and trigger the rule engine to fire the different rules. Firing a rule means to check if the conditions are fulfilled and if something has to be done.As Jeremy points out: "Whenever you work with a session, it's important to always remember to use the dispose() function to dispose of it when you're done. If you don't, the garbage collector won't be able to free up the resources for you, and that means problems."
Drools Post 1 - What is Drools
The website says Drools is
a Business Rule Management System, but well what is that. It also talks
about the Rete algorithm, which you can look up at wikipedia [Wikipedia:Rete_algorithm].
As I said I bought a book to get the answers. Jeremy Ary says that
"Drools is a collection of tools which allow us to separate and reason
over logic and data found within businss processes". He continues that this
is quite not the answer someone wants to get - just from my point of
view - he is right :-).
So one important thing that we have are rules. And well we want to use these rules to build a rule-driven system. More precisely we want to tell our system how to react if some conditions are fulfilled. For example throw an event, inform someone or just shutdown. If a condition is fulfilled depends on the data, the facts of the world. Sometime the knowledge of a new fact results in another fact, that results in new fulfilled conditions.
So summarized, Drools enables us to define rules that are executed by the rule engine. The rule itself is not part of the code... but it uses facts or data that is derived from it. So the logic is extracted from our code, as long as it is rule-oriented logic. Sounds nice. So lets get started...
So one important thing that we have are rules. And well we want to use these rules to build a rule-driven system. More precisely we want to tell our system how to react if some conditions are fulfilled. For example throw an event, inform someone or just shutdown. If a condition is fulfilled depends on the data, the facts of the world. Sometime the knowledge of a new fact results in another fact, that results in new fulfilled conditions.
So summarized, Drools enables us to define rules that are executed by the rule engine. The rule itself is not part of the code... but it uses facts or data that is derived from it. So the logic is extracted from our code, as long as it is rule-oriented logic. Sounds nice. So lets get started...
Drools - Getting started...
Just a few words at the beginning
Today, I want to start using Drools in a more professional way. I have used Drools in the past, for smaller projects and out of sheer curiosity, but I never tried to learn it from the scratch.A few minutes ago, I bought the ebook "Instant Drools Starter" by Jeremy Ary to get a better overview and a starting point. I hope the book deliveres :-). So I will update this post, and also prepare a presentation during my work. Perhaps I will upload it.
So what will I use:
- Spring Tool Suite (but I think Eclipse will do it)
- Maven for dependency management
- normally I am using Spring, but we will see
Abonnieren
Posts (Atom)