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(a)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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users