EqualToSum.java
- /* Copyright 2015 Laurent COCAULT
- * Licensed to Laurent COCAULT under one or more contributor license agreements.
- * See the NOTICE file distributed with this work for additional information
- * regarding copyright ownership. Laurent COCAULT licenses this file to You
- * 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.csp.constraint.model.integer;
- import org.csp.constraint.model.TernaryConstraint;
- /**
- * Constraint specifying that one specific integer variable is the sum of two
- * other integer variables.
- */
- public class EqualToSum extends TernaryConstraint<IntValue> {
- /**
- * Constructor of the constraint "FIRST + SECOND = SUM".
- * @param first
- * First variable
- * @param second
- * Second variable
- * @param sum
- * Sum of the two other variables
- */
- public EqualToSum(final IntVar first, final IntVar second, final IntVar sum) {
- super(first.getName() + "+" + second.getName() + "=" + sum.getName(),
- first, second, sum);
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public void propagate() {
- // The sum minimum is the sum of the other variables minimum and the
- // sum maximum is the sum of the other variables maximum.
- final IntValue sumMin = IntValue.sum(getFirst().getMinValue(),
- getSecond().getMinValue());
- final boolean sumMinChanged = getSum().reduceWithMinValue(sumMin);
- final IntValue sumMax = IntValue.sum(getFirst().getMaxValue(),
- getSecond().getMaxValue());
- final boolean sumMaxChanged = getSum().reduceWithMaxValue(sumMax);
- if (sumMaxChanged || sumMinChanged) {
- addRecentChangedVariable(getSum());
- }
- // Propagate the constraint on the first variable
- propagateOnArgument(getFirst(), getSecond(), getSum());
- // Propagate the constraint on the second variable
- propagateOnArgument(getSecond(), getFirst(), getSum());
- }
- /**
- * Propagate the constraint on an argument. The propagation algorithm is the
- * same on the first or the second argument of the constraint: the current
- * method is therefore applied twice with a permutation of the variables.
- * @param argument
- * Argument on which to propagate the constraint
- * @param other
- * Other argument in the sum
- * @param sum
- * Sum of the two arguments
- */
- private void propagateOnArgument(final IntVar argument, final IntVar other,
- final IntVar sum) {
- // The argument maximum shall not be greater than the difference between
- // the "sum" maximum and the "other" minimum.
- final IntValue newMax = IntValue.diff(sum.getMaxValue(),
- other.getMinValue());
- final boolean maxChanged = argument.reduceWithMaxValue(newMax);
- // The argument minimum shall not be lesser than the difference between
- // the "sum" minimum and the "other" maximum.
- final IntValue newMin = IntValue.diff(sum.getMinValue(),
- other.getMaxValue());
- final boolean minChanged = argument.reduceWithMinValue(newMin);
- if (maxChanged || minChanged) {
- addRecentChangedVariable(argument);
- }
- }
- /**
- * Get the first argument of the constraint.
- * @return First argument
- */
- protected IntVar getFirst() {
- return (IntVar) getFirstVariable();
- }
- /**
- * Get the second argument of the constraint.
- * @return Second argument
- */
- protected IntVar getSecond() {
- return (IntVar) getSecondVariable();
- }
- /**
- * Get the sum.
- * @return Sum (third variable)
- */
- protected IntVar getSum() {
- return (IntVar) getThirdVariable();
- }
- }