Reputation: 5
I am trying to apply optaplanner to my project, such as picking order path calculation. When there are many order items, the calculation speed is very slow. I want to know how to improve the calculation speed,When the order items are more than 200, the calculation speed is particularly slow, and I only add constraints. I defined a selectionsorterweightfactory, but the debug doesn't seem to work.
private Constraint requiredNumberOfBuckets(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(TrolleyStep.class)
// raw total volume per order
.groupBy(
trolleyStep -> trolleyStep.getTrolley(),
trolleyStep -> trolleyStep.getOrderItem().getOrderCode(),
sum(trolleyStep -> trolleyStep.getOrderItem().getProduct().getCapacity()))
// required buckets per order
.groupBy(
(trolley, order, orderTotalVolume) -> trolley,
(trolley, order, orderTotalVolume) -> order,
sum(
(trolley, order, orderTotalVolume) ->
calculateOrderRequiredBuckets(orderTotalVolume, trolley.getBucketCapacity())))
// required buckets per trolley
.groupBy(
(trolley, order, orderTotalBuckets) -> trolley,
sum((trolley, order, orderTotalBuckets) -> orderTotalBuckets))
// penalization if the trolley don't have enough buckets to hold the orders
.filter((trolley, trolleyTotalBuckets) -> trolley.getBucketNum() < trolleyTotalBuckets)
.penalize(
"Required number of buckets",
HardSoftLongScore.ONE_HARD,
(trolley, trolleyTotalBuckets) -> trolleyTotalBuckets - trolley.getBucketNum());}
private Constraint minimizeOrderSplitByTrolley(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(TrolleyStep.class)
.groupBy(
trolleyStep -> trolleyStep.getOrderItem().getOrderCode(),
countDistinctLong(TrolleyStep::getTrolley))
.penalizeLong(
"Minimize order split by trolley",
HardSoftLongScore.ONE_SOFT,
(order, trolleySpreadCount) -> trolleySpreadCount * 10000);
private Constraint distanceToEnd(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(TrolleyStep.class)
.filter(ele -> ele.getNextStep() == null)
.penalizeLong(
" distance to end ",
HardSoftLongScore.ONE_SOFT,
trolleyStep -> (long) trolleyStep.distanceToLocation(OrderPickingService.end));}
private Constraint distanceToPrevious(ConstraintFactory constraintFactory) {
return constraintFactory
.forEach(TrolleyStep.class)
.penalizeLong(
" distance to previous ",
HardSoftLongScore.ONE_SOFT,
trolleyStep ->
(long)
trolleyStep.distanceToLocation(
trolleyStep.getPreviousStandstill().getLocation()));}
Upvotes: 0
Views: 80
Reputation: 5682
Your problem will be the requiredNumberOfBuckets
constraint.
Unfortunately, in the current implementation of Constraint Streams, there is no way how to make three consecutive groupBy()
s fast. You will have to find a way around it. I'd experiment with writing a custom ConstraintCollector
that would do the work in one groupBy(...)
, as opposed to doing it in three steps.
Upvotes: 0