/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.optaplanner.core.api.score.buildin.hardmediumsoftbigdecimal; import java.math.BigDecimal; import org.kie.api.runtime.rule.RuleContext; import org.optaplanner.core.api.score.Score; import org.optaplanner.core.api.score.holder.AbstractScoreHolder; /** * @see HardMediumSoftBigDecimalScore */ public class HardMediumSoftBigDecimalScoreHolder extends AbstractScoreHolder { protected BigDecimal hardScore; protected BigDecimal mediumScore; protected BigDecimal softScore; public HardMediumSoftBigDecimalScoreHolder(boolean constraintMatchEnabled) { super(constraintMatchEnabled, HardMediumSoftBigDecimalScore.ZERO); } public BigDecimal getHardScore() { return hardScore; } public BigDecimal getMediumScore() { return mediumScore; } public BigDecimal getSoftScore() { return softScore; } // ************************************************************************ // Worker methods // ************************************************************************ /** * Add a hard constraint of specified weighting. * * This is typically used in Drools scoring to add a hard constraint match (negative value to indicate an infeasible * solution). * * @param kcontext never null, the magic variable in DRL * @param hardWeight never null, higher is better, negative for a penalty, positive for a reward */ public void addHardConstraintMatch(RuleContext kcontext, BigDecimal hardWeight) { hardScore = (hardScore == null) ? hardWeight : hardScore.add(hardWeight); registerConstraintMatch(kcontext, () -> hardScore = hardScore.subtract(hardWeight), () -> HardMediumSoftBigDecimalScore.valueOf(hardWeight, BigDecimal.ZERO, BigDecimal.ZERO)); } /** * Add a medium level constraint of specified weighting. * * This is typically used in Drools scoring to add a medium priority constraint match. * * @param kcontext never null, the magic variable in DRL * @param mediumWeight never null, higher is better, negative for a penalty, positive for a reward */ public void addMediumConstraintMatch(RuleContext kcontext, BigDecimal mediumWeight) { mediumScore = (mediumScore == null) ? mediumWeight : mediumScore.add(mediumWeight); registerConstraintMatch(kcontext, () -> mediumScore = mediumScore.subtract(mediumWeight), () -> HardMediumSoftBigDecimalScore.valueOf(BigDecimal.ZERO, mediumWeight, BigDecimal.ZERO)); } /** * Add a soft constraint match of specified weighting. * * This is typically used in Drools scoring to add a low priority constraint match. * * @param kcontext never null, the magic variable in DRL * @param softWeight never null, higher is better, negative for a penalty, positive for a reward */ public void addSoftConstraintMatch(RuleContext kcontext, BigDecimal softWeight) { softScore = (softScore == null) ? softWeight : softScore.add(softWeight); registerConstraintMatch(kcontext, () -> softScore = softScore.subtract(softWeight), () -> HardMediumSoftBigDecimalScore.valueOf(BigDecimal.ZERO, BigDecimal.ZERO, softWeight)); } /** * @param kcontext never null, the magic variable in DRL * @param hardWeight never null, higher is better, negative for a penalty, positive for a reward * @param mediumWeight never null, higher is better, negative for a penalty, positive for a reward * @param softWeight never null, higher is better, negative for a penalty, positive for a reward */ public void addMultiConstraintMatch(RuleContext kcontext, BigDecimal hardWeight, BigDecimal mediumWeight, BigDecimal softWeight) { hardScore = (hardScore == null) ? hardWeight : hardScore.add(hardWeight); mediumScore = (mediumScore == null) ? mediumWeight : mediumScore.add(mediumWeight); softScore = (softScore == null) ? softWeight : softScore.add(softWeight); registerConstraintMatch(kcontext, () -> { hardScore = hardScore.subtract(hardWeight); mediumScore = mediumScore.subtract(mediumWeight); softScore = softScore.subtract(softWeight); }, () -> HardMediumSoftBigDecimalScore.valueOf(hardWeight, mediumWeight, softWeight)); } @Override public Score extractScore(int initScore) { return HardMediumSoftBigDecimalScore.valueOfUninitialized(initScore, hardScore == null ? BigDecimal.ZERO : hardScore, mediumScore == null ? BigDecimal.ZERO : mediumScore, softScore == null ? BigDecimal.ZERO : softScore); } }