All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.chocosolver.solver.expression.discrete.arithmetic.BiArExpression Maven / Gradle / Ivy

There is a newer version: 4.10.17
Show newest version
/*
 * This file is part of choco-solver, http://choco-solver.org/
 *
 * Copyright (c) 2022, IMT Atlantique. All rights reserved.
 *
 * Licensed under the BSD 4-clause license.
 *
 * See LICENSE file in the project root for full license information.
 */
package org.chocosolver.solver.expression.discrete.arithmetic;

import org.chocosolver.solver.Model;
import org.chocosolver.solver.constraints.extension.Tuples;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.tools.VariableUtils;

import java.util.Map;

/**
 * Binary arithmetic expression
 * 

* Project: choco-solver. * * @author Charles Prud'homme * @since 28/04/2016. */ public class BiArExpression implements ArExpression { /** * The model in which the expression is declared */ Model model; /** * Lazy creation of the underlying variable */ IntVar me = null; /** * Operator of the arithmetic expression */ Operator op; /** * The first expression this expression relies on */ private final ArExpression e1; /** * The second expression this expression relies on */ private final ArExpression e2; /** * Builds a binary expression * * @param op an operator * @param e1 an expression * @param e2 an expression */ public BiArExpression(Operator op, ArExpression e1, ArExpression e2) { this.op = op; this.e1 = e1; this.e2 = e2; this.model = e1.getModel(); } @Override public Model getModel() { return model; } public Operator getOp() { return op; } @Override public IntVar intVar() { if (me == null) { IntVar v1 = e1.intVar(); IntVar v2 = e2.intVar(); int[] bounds; switch (op) { case ADD: bounds = VariableUtils.boundsForAddition(v1, v2); me = model.intVar(model.generateName("sum_exp_"), bounds[0], bounds[1]); model.arithm(v1, "+", v2, "=", me).post(); break; case SUB: bounds = VariableUtils.boundsForSubstraction(v1, v2); me = model.intVar(model.generateName("sub_exp_"), bounds[0], bounds[1]); model.arithm(v1, "-", v2, "=", me).post(); break; case MUL: bounds = VariableUtils.boundsForMultiplication(v1, v2); me = model.intVar(model.generateName("mul_exp_"), bounds[0], bounds[1]); model.times(v1, v2, me).post(); break; case DIV: bounds = VariableUtils.boundsForDivision(v1, v2); me = model.intVar(model.generateName("div_exp_"), bounds[0], bounds[1]); model.div(v1, v2, me).post(); break; case MOD: bounds = VariableUtils.boundsForModulo(v1, v2); me = model.intVar(model.generateName("mod_exp_"), bounds[0], bounds[1]); model.mod(v1, v2, me).post(); break; case POW: // todo as intension constraint bounds = VariableUtils.boundsForPow(v1, v2); me = model.intVar(model.generateName("pow_exp_"), bounds[0], bounds[1]); Tuples tuples = new Tuples(true); for(int val1 : v1){ for(int val2 : v2){ int res = (int)Math.pow(val1, val2); if(me.contains(res)) { tuples.add(val1, val2, res); } } } model.table(new IntVar[]{v1, v2, me}, tuples).post(); break; case MIN: bounds = VariableUtils.boundsForMinimum(v1, v2); me = model.intVar(model.generateName("min_exp_"), bounds[0], bounds[1]); model.min(me, v1, v2).post(); break; case MAX: bounds = VariableUtils.boundsForMaximum(v1, v2); me = model.intVar(model.generateName("max_exp_"), bounds[0], bounds[1]); model.max(me, v1, v2).post(); break; default: throw new UnsupportedOperationException("Binary arithmetic expressions does not support " + op.name()); } } return me; } @Override public int ieval(int[] values, Map map) { return op.eval(e1.ieval(values, map), e2.ieval(values, map)); } @Override public int getNoChild() { return 2; } @Override public ArExpression[] getExpressionChild() { return new ArExpression[]{e1, e2}; } @Override public String toString() { return op.name() + "(" + e1.toString() + "," + e2.toString() + ")"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy