Joy
Joy

Reputation: 5

Optaplanner optimization

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

Answers (1)

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

Related Questions