Sender: |
|
Date: |
Wed, 31 Jul 2013 14:40:42 +0200 |
Reply-To: |
|
Subject: |
|
MIME-Version: |
1.0 |
Content-Transfer-Encoding: |
7bit |
In-Reply-To: |
|
Content-Type: |
text/plain; charset=utf-8 |
From: |
|
Parts/Attachments: |
|
|
Hey ECJ-Users,
I'm using ECJ in a GP way to create rules. But the complexity of a possible rule is still low. So I want to use ADF to define a condition of the rule and change these conditions between my individuals.
My old tree was:
gp.fs.0 = ec.gp.GPFunctionSet
gp.fs.0.name = f0
gp.fs.0.size = 13
gp.fs.0.func.0 = rulevolution.nodes.When
gp.fs.0.func.0.nc = nc0
gp.fs.0.func.1 = rulevolution.nodes.Not
gp.fs.0.func.1.nc = nc1
gp.fs.0.func.2 = rulevolution.nodes.And
gp.fs.0.func.2.nc = nc2
gp.fs.0.func.3 = rulevolution.nodes.Faktum
gp.fs.0.func.3.nc = nc6
gp.fs.0.func.4 = rulevolution.nodes.Contains
gp.fs.0.func.4.nc = nc5
gp.fs.0.func.5 = rulevolution.nodes.Exists
gp.fs.0.func.5.nc = nc3
gp.fs.0.func.6 = rulevolution.nodes.Eval
gp.fs.0.func.6.nc = nc4
gp.fs.0.func.7 = rulevolution.nodes.SubAnd
gp.fs.0.func.7.nc = nc7
gp.fs.0.func.8 = rulevolution.nodes.SubOr
gp.fs.0.func.8.nc = nc7
gp.fs.0.func.9 = rulevolution.nodes.SubAnd
gp.fs.0.func.9.nc = nc8
gp.fs.0.func.10 = rulevolution.nodes.SubOr
gp.fs.0.func.10.nc = nc8
gp.fs.0.func.11 = rulevolution.nodes.Eval
gp.fs.0.func.11.nc = nc11
gp.fs.0.func.12 = rulevolution.nodes.When
gp.fs.0.func.12.nc = nc10
which worked, but created too simple rules. Means maximum 2 or 3 conditions in a tree. If I increase the depth, the tree will just increase the subconditions with SubOr and SubAnd, so I thought that the conditions should have a fixed depth of 3 or 4 Nodes and the Tree can also have a depth of 3 or 4 nodes, which could at maximum define 2 ^ 4 = 16 conditions, that would be more than enough. Don't bother with the nc's, they're well defined.
Now I wanted to add the ADF, which returns a condition:
gp.fs.0 = ec.gp.GPFunctionSet
gp.fs.0.name = f0
gp.fs.0.size = 11
gp.fs.0.func.0 = rulevolution.nodes.When
gp.fs.0.func.0.nc = nc0
gp.fs.0.func.1 = rulevolution.nodes.And
gp.fs.0.func.1.nc = nc2
gp.fs.0.func.2 = rulevolution.nodes.Faktum
gp.fs.0.func.2.nc = nc6
gp.fs.0.func.3 = rulevolution.nodes.Eval
gp.fs.0.func.3.nc = nc4
gp.fs.0.func.4 = rulevolution.nodes.When
gp.fs.0.func.4.nc = nc10
gp.fs.0.func.5 = rulevolution.nodes.SubAnd
gp.fs.0.func.5.nc = nc7
gp.fs.0.func.6 = rulevolution.nodes.SubOr
gp.fs.0.func.6.nc = nc7
gp.fs.0.func.7 = rulevolution.nodes.SubAnd
gp.fs.0.func.7.nc = nc8
gp.fs.0.func.8 = rulevolution.nodes.SubOr
gp.fs.0.func.8.nc = nc8
gp.fs.0.func.9 = ec.gp.ADF
gp.fs.0.func.9.nc = nc1
gp.fs.0.func.9.tree = 1
gp.fs.0.func.9.name = ADF1
gp.fs.0.func.10 = rulevolution.nodes.When
gp.fs.0.func.10.nc = nc10
gp.fs.1 = ec.gp.GPFunctionSet
gp.fs.1.name = f1
gp.fs.1.size = 9
gp.fs.1.func.0 = rulevolution.nodes.Not
gp.fs.1.func.0.nc = nc11
gp.fs.1.func.1 = rulevolution.nodes.Faktum
gp.fs.1.func.1.nc = nc6
gp.fs.1.func.2 = rulevolution.nodes.Contains
gp.fs.1.func.2.nc = nc5
gp.fs.1.func.3 = rulevolution.nodes.Exists
gp.fs.1.func.3.nc = nc3
gp.fs.1.func.4 = rulevolution.nodes.SubAnd
gp.fs.1.func.4.nc = nc7
gp.fs.1.func.5 = rulevolution.nodes.SubOr
gp.fs.1.func.5.nc = nc7
gp.fs.1.func.6 = rulevolution.nodes.SubOr
gp.fs.1.func.6.nc = nc8
gp.fs.1.func.7 = rulevolution.nodes.SubAnd
gp.fs.1.func.7.nc = nc8
gp.fs.1.func.8 = rulevolution.nodes.Exists
gp.fs.1.func.8.nc = nc1
Like you see the node "Not" and "Exists" are only defined in the ADF-Tree, because they're the root of each condition. You can also see that my ADF-Tree has no Eval nodes, because it is not needed in a condition. nc1, nc5 , nc6 and nc10 are the terminals and everything else are non-terminals.
I don't know why, but the algorithm is resetting the Faktum non-stop. Faktum is simply taking a random method from a parameterized class and putting the conditions into the arguments of the method. Here's the flow of the node:
Do
check (Method == null or reset == true) -> method = getRandomMethod(m); reset = false //m is a random number
check (Parameter of Method > Conditions) -> resetNode -> reset = true; m = new random number in range of declaredmethods; increase resets
Else put conditions into arguments and break;
while resets < 100
check (arguments does not exist) -> remove method and use "true" //true always works in rules, it will be removed from the interpreter
I don't know where the infinite loop should come from. But here's a snippet of the threaddump I've created:
"ECJ Evaluation Thread 10" daemon prio=10 tid=0x00002ae1904a3000 nid=0x282 runnable [0x00002ae196c17000]
java.lang.Thread.State: RUNNABLE
at sun.reflect.Reflection.getCallerClass(Native Method)
at java.lang.ClassLoader.getCallerClassLoader(ClassLoader.java:1383)
at java.lang.Class.getDeclaredMethods(Class.java:1792)
at rulevolution.nodes.Faktum.getMethod(Faktum.java:63)
at rulevolution.nodes.Faktum.eval(Faktum.java:81)
at rulevolution.nodes.SubOr.eval(SubOr.java:36)
at rulevolution.nodes.SubAnd.eval(SubAnd.java:38)
at rulevolution.nodes.Eval.eval(Eval.java:35)
at rulevolution.nodes.When.eval(When.java:36)
at rulevolution.RuleProblem.evaluate(RuleProblem.java:178)
at ec.simple.SimpleEvaluator.evalPopChunk(SimpleEvaluator.java:259)
at ec.simple.SimpleEvaluator$SimpleEvaluatorThreadCG.run(SimpleEvaluator.java:341)
at ec.util.ThreadPool$PoolThread.run(ThreadPool.java:57)
Locked ownable synchronizers:
- None
"ECJ Evaluation Thread 9" daemon prio=10 tid=0x00002ae190a66000 nid=0x281 in Object.wait() [0x00002ae196b16000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000975097b8> (a [Ljava.lang.Object;)
at java.lang.Object.wait(Object.java:485)
at ec.util.ThreadPool$PoolThread.run(ThreadPool.java:51)
- locked <0x00000000975097b8> (a [Ljava.lang.Object;)
Locked ownable synchronizers:
- None
"ECJ Evaluation Thread 8" daemon prio=10 tid=0x00002ae19037c800 nid=0x280 runnable [0x00002ae196a15000]
java.lang.Thread.State: RUNNABLE
at sun.reflect.Reflection.getCallerClass(Native Method)
at java.lang.ClassLoader.getCallerClassLoader(ClassLoader.java:1383)
at java.lang.Class.getDeclaredMethods(Class.java:1792)
at rulevolution.nodes.Faktum.resetNode(Faktum.java:233)
at rulevolution.nodes.Faktum.eval(Faktum.java:88)
at rulevolution.nodes.Eval.eval(Eval.java:35)
at rulevolution.nodes.When.eval(When.java:36)
at rulevolution.RuleProblem.evaluate(RuleProblem.java:178)
at ec.simple.SimpleEvaluator.evalPopChunk(SimpleEvaluator.java:259)
at ec.simple.SimpleEvaluator$SimpleEvaluatorThreadCG.run(SimpleEvaluator.java:341)
at ec.util.ThreadPool$PoolThread.run(ThreadPool.java:57)
Locked ownable synchronizers:
- None
Does someone got an idea where the infinite loop comes from?
Thanks and greetings
Bojan
|
|
|