[rules-users] Rule using accumulate

Wolfgang Laun wolfgang.laun at gmail.com
Mon Apr 26 13:46:41 EDT 2010


I'm not going to propose a complete solution, merely the outline of a
different approach.

It would introduce a "PartiallyCoveredBid", which is a Bid with one or
more Offers associated with the original Bid. It extends a Bid with a
Collection of associated Offers (so far) and the accumulated size and
prize. A rule to add another Offer to the PartiallyCoveredBid would
have to check that the PartiallyCoveredBid isn't fully covered yet,
and that the Offer isn't contained in the "associated" Collection.
This should provide an opportunity to select the next Offer by
smallest prize/size ratio or other criteria.

Note that this is just a sketchy idea - your requirements may not
permit this approach - but I have a gut feeling that this may permit a
more flexible approach.

HTH
-W


2010/4/26 Andrés Corvetto <acorvetto at gmail.com>:
> Hi guys,
> I'm new to drools, and i'm trying to build a small prototype.
> I have 2 entities in my model: Offers and Bids. Both have a size (and a
> price). I need a rule that matches a single Bid with multiple Offers adding
> up in size to the Bid size. Matched Offers have to be sorted
> by (increasing) insertion time .
> I have managed to write a rule using 'accumulate', but i feel it's not too
> efficient, since i have to match every Offer in the working memory with the
> right price, sort them and then pick the first n ones.
> Here's the rule:
> rule "Match Bids"
> when
> $b : Bid($s:size, $p:price)
> $i : OfferAccumulator(acumSize >= $s) from accumulate ( $o:Offer(price<=$p)
> ,
> init(OfferAccumulator accum = new OfferAccumulator($s); ),
> action( accum.add($o);),
> reverse ( accum.remove($o);),
> result( accum ))
> then
> System.out.println( "Matched Bid:" + $b + "," + $i.getOffers());
> end
> and here's OfferAccumulator:
> public class OfferAccumulator {
> private int sizeLimit=0;
> private int accumSize=0;
> Set<Offer> offers = new TreeSet<Offer>();
> public OfferAccumulator(int sizeLimit) {
> this.sizeLimit = sizeLimit;
> }
> public void add(Offer op) {
> accumSize+=op.getSize();
> offers.add(op);
> }
> public void remove(Offer op) {
> if (offers.remove(op)) {
> accumSize-=op.getSize();
> }
> }
> public List<Offer> getOffers() {
> List<Offer> ret = new ArrayList<Offer>();
> int accum=0;
> Iterator<Offer> it = offers.iterator();
> while (it.hasNext() && acum<sizeLimit) {
> Offer offer = it.next();
> accum+=offer.getSize();
> ret.add(offer);
> }
> return ret;
> }
> }
> Can you think of a more efficient way of achieving the same result? Is there
> a way of controlling the order in which facts are feeded to the accumulator?
> Thanks in advance!
>      Andres
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>
>




More information about the rules-users mailing list