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

org.chocosolver.solver.propagation.PropagationTrigger Maven / Gradle / Ivy

There is a newer version: 4.10.16
Show newest version
/**
 * Copyright (c) 2016, Ecole des Mines de Nantes
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the .
 * 4. Neither the name of the  nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY  ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.chocosolver.solver.propagation;

import org.chocosolver.memory.IEnvironment;
import org.chocosolver.solver.Model;
import org.chocosolver.solver.constraints.Propagator;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.events.PropagatorEventType;
import org.chocosolver.util.objects.IntList;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * A specific propagation engine for initial propagation and dynamic addition of propagators during the resolution.
 * 
* It handles three different types of constraints: * - constraints posted before solving the problem, * - permanent constraints posted once the resolution has begun, * - temporary constraints (removed upon backtrack) posted once the resolution has begun. * * @author Charles Prud'homme * @since 15/12/12 */ public class PropagationTrigger { private final IPropagationEngine engine; // wrapped engine private final IEnvironment environment; private final Model model; private final boolean DEBUG, COLOR; // stores the static propagators private ArrayList sta_propagators = new ArrayList<>(); // stores the dynamic propagators, ie cut private ArrayList perm_propagators = new ArrayList<>(); // stores the world of the last propagation of the cuts private IntList perm_world = new IntList(); private int size; public PropagationTrigger(IPropagationEngine engine, Model model) { this.engine = engine; this.environment = model.getEnvironment(); this.model = model; size = 0; this.DEBUG = model.getSettings().debugPropagation(); this.COLOR = model.getSettings().outputWithANSIColors(); } public void addAll(Propagator... propagators) { assert perm_propagators.size() == perm_world.size(); sta_propagators.addAll(Arrays.asList(propagators)); size += propagators.length; if(model.getSettings().sortPropagatorActivationWRTPriority()) { sta_propagators.sort((p1, p2) -> p1.getPriority().priority - p2.getPriority().priority); } } public void dynAdd(Propagator propagator, boolean permanent) { if (permanent) { assert perm_propagators.size() == perm_world.size(); int pos = find(propagator); if (pos == -1) { perm_propagators.add(propagator); perm_world.add(Integer.MAX_VALUE); size++; } else { perm_world.replaceQuick(pos, Integer.MAX_VALUE); } } } private int find(Propagator p) { int i = 0; while (i < perm_propagators.size() && perm_propagators.get(i) != p) { i++; } if (i == perm_propagators.size()) return -1; else return i; } public void remove(Propagator propagator) { // Remove a pending propagator, ie, not yet propagated // 1. look for a static propagator int idx = sta_propagators.indexOf(propagator); if (idx > -1) { sta_propagators.remove(idx); } // 2. then, if necessary look for permanent one idx = perm_propagators.indexOf(propagator); if (idx > -1) { perm_propagators.remove(idx); perm_world.removeAt(idx); } } public boolean needToRun() { return size > 0; } public void clear(){ sta_propagators.clear(); perm_propagators.clear(); perm_world.clear(); size = 0; } /** * Define a way to initialize the propagation engine. * Loops over the propagator of the model, then activate them one by one, if stateless, * and call propagate after each propagator. * * @throws ContradictionException can throw a contradiction */ public void propagate() throws ContradictionException { if (sta_propagators.size() > 0) { for (int p = 0; p < sta_propagators.size(); p++) { if (DEBUG) { IPropagationEngine.Trace.printFirstPropagation(sta_propagators.get(p), COLOR); } execute(sta_propagators.get(p), engine); } size -= sta_propagators.size(); sta_propagators.clear(); } if (perm_propagators.size() > 0) { int cw = environment.getWorldIndex(); // get current index for (int p = 0; p < perm_propagators.size(); p++) { if (perm_world.getQuick(p) >= cw) { execute(perm_propagators.get(p), engine); perm_world.replace(p, cw); // TODO: add a test on the root world to clear the list } } } /*if (tmp_propagators.size() > 0) { for (int p = 0; p < tmp_propagators.size(); p++) { Propagator propagator = tmp_propagators.get(p); execute(propagator, engine); tmp_propagators.remove(p); p--; size--; tmp_cstr.add(propagator.getConstraint()); } for (final Constraint c : tmp_cstr) { // the constraint has been added during the resolution. // it should be removed on backtrack -> create a new undo operation environment.save(new Operation() { @Override public void undo() { if (LoggerFactory.getLogger("solver").isDebugEnabled()) { LoggerFactory.getLogger("solver").debug("unpost " + c); } model.unpost(c); } }); } tmp_cstr.clear(); }*/ } public static void execute(Propagator toPropagate, IPropagationEngine engine) throws ContradictionException { if (toPropagate.isStateLess()) { toPropagate.setActive(); toPropagate.propagate(PropagatorEventType.FULL_PROPAGATION.getMask()); engine.onPropagatorExecution(toPropagate); } else if (toPropagate.isActive()) { // deal with updated propagator toPropagate.propagate(PropagatorEventType.FULL_PROPAGATION.getMask()); engine.onPropagatorExecution(toPropagate); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy