[rules-users] How to write a rule which only fires for a closest value?

Edson Tirelli tirelli at post.com
Thu Dec 6 11:54:53 EST 2007


    Your reasoning on how to solve the problem is correct. I don't know
about your implementation, but my suggestion is:

1. Create a function to calculate the distance between 2 points. I would
prefer to create it as a static method in a helper class, but you can define
it in the DRL if you prefer:

function double distance( long originX, long originY, long actualX, long
actualY ) {
    // return the calculated distance
}

2.a. If you want to do it in a single rule, write something like this:

when
    $a: Agent( $x1:x, $y1:y, $r:range)
    $t1: Tile( $x2: x, $y2 : y, eval( distance( $x1, $y1, $x2, $y2 ) <= $r )
)
    not Tile( eval( distance( $x1, $y1, x, y ) < distance( $x1, $y1, $x2,
$y2 ) ) )
then
end

The downside of such approach is that it recalculates the distance many
times and the performance would be poor.

2.b. If you want best performance, try a more relational approach with 2
rules:

rule "calculate distance"
when
    $a: Agent( $x1 : x, $y1 : y, $r : range )
    $t: Tile( eval( distance( $x1, $y1, x, y ) < $r ) )
then
    assertLogical( new TileInRange( $a, $t, distance( $x1, $y1, x, y ) ) );
end

rule "find the closest"
when
    $a: Agent()
    $tr TileInRange( agent == $a, $tile : tile, $dist : distance )
    not TileInRange( agent == $a, distance < $dist )
    $t : Tile( this == $tile ) // this last pattern may be removed if you
don't need to constrain any other attribute
then
    // do something
end

   Hope it helps

    Edson

2007/12/6, velven <velven83 at hotmail.com>:
>
>
> HI, i have a problem
> using tileworld model, i'm supposed to write a rule which will cause the
> agents to choose the tile in the agent's range which is closest to the
> agent.
>
> so a rough idea is
>
> when
>
> agent: Agent(x1:x, y1:y, r:range)
>
> tile1: Tile(<tile's x to be between (x1+r) and (x1-r)> && <tile's y to be
> between (y1+r and y1-r)>)
>
> tile2: not Tile( < which is closer than the tile1 to agent> )
>
> desperately need help,
> alternatives tried::
> i tried to use a query to return a list of tiles which is within the
> agent's
> range then compared which one is closer and other similar implementation,
> but this too slow for my simulation...
>
> I need one single good rule or efficient way of implementing the above
> rule
>
>
> then i tried to do multiple constraints too, say     x (> 30 && < 40) is
> ok
> but
>                                                                   x (>
> ($x-$r) && < ($x+$r)) gives errors ,due to extra parenthesis? i dunno..
> any
> workarounds?
>
> Thanks!
>
>
> --
> View this message in context:
> http://www.nabble.com/How-to-write-a-rule-which-only-fires-for-a-closest-value--tf4947931.html#a14166650
> Sent from the drools - user mailing list archive at Nabble.com.
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>



-- 
  Edson Tirelli
  JBoss Drools Core Development
  Office: +55 11 3529-6000
  Mobile: +55 11 9287-5646
  JBoss, a division of Red Hat @ www.jboss.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20071206/ceafe938/attachment.html 


More information about the rules-users mailing list