/** * Constraint modeling the Traveling Salesman Problem * * @param GRAPHVAR graph variable representing a Hamiltonian cycle * @param COSTVAR variable representing the cost of the cycle * @param EDGE_COSTS cost matrix (should be symmetric) * @param LAGR_MODE use the Lagrangian relaxation of the tsp described by Held and Karp {0:no * Lagrangian relaxation, 1:Lagrangian relaxation (since root node), 2:Lagrangian relaxation * but wait a first solution before running it} * @return a tsp constraint */ public static Constraint tsp( IUndirectedGraphVar GRAPHVAR, IntVar COSTVAR, int[][] EDGE_COSTS, int LAGR_MODE) { Propagator[] props = ArrayUtils.append( hamiltonian_cycle(GRAPHVAR).getPropagators(), new Propagator[] {new PropCycleCostSimple(GRAPHVAR, COSTVAR, EDGE_COSTS)}); if (LAGR_MODE > 0) { PropLagr_OneTree hk = new PropLagr_OneTree(GRAPHVAR, COSTVAR, EDGE_COSTS); hk.waitFirstSolution(LAGR_MODE == 2); props = ArrayUtils.append(props, new Propagator[] {hk}); } return new Constraint("TSP", props); }
/** * AtLeastNValues Propagator (similar to SoftAllDiff) The number of distinct values in vars is at * least nValues Performs Generalized Arc Consistency based on Maximum Bipartite Matching The * worst case time complexity is O(nm) but this is very pessimistic In practice it is more like * O(m) where m is the number of variable-value pairs * * @param variables array of integer variables * @param nValues integer variable */ public PropAtLeastNValues_AC(IntVar[] variables, IntVar nValues) { super(ArrayUtils.append(variables, new IntVar[] {nValues}), PropagatorPriority.QUADRATIC, true); this.idms = new IIntDeltaMonitor[this.vars.length]; for (int i = 0; i < this.vars.length; i++) { idms[i] = this.vars[i].monitorDelta(this); } n = variables.length; map = new TIntIntHashMap(); IntVar v; int ub; int idx = n; for (int i = 0; i < n; i++) { v = vars[i]; ub = v.getUB(); for (int j = v.getLB(); j <= ub; j = v.nextValue(j)) { if (!map.containsKey(j)) { map.put(j, idx); idx++; } } } n2 = idx; fifo = new int[n2]; digraph = new DirectedGraph(model, n2 + 2, SetType.LINKED_LIST, false); free = new BitSet(n2); remProc = new DirectedRemProc(); father = new int[n2]; in = new BitSet(n2); SCCfinder = new StrongConnectivityFinder(digraph); }
public PropBoolMax(BoolVar[] variables, BoolVar maxVar) { super(ArrayUtils.append(variables, new BoolVar[] {maxVar}), PropagatorPriority.UNARY, true); n = variables.length; x1 = -1; x2 = -1; assert n > 0; }
public PropKnapsack( IntVar[] itemOccurence, IntVar capacity, IntVar power, int[] weight, int[] energy) { super( ArrayUtils.append(itemOccurence, new IntVar[] {capacity, power}), PropagatorPriority.LINEAR, false); this.weigth = weight; this.energy = energy; this.n = itemOccurence.length; this.capacity = vars[n]; this.power = vars[n + 1]; this.order = new int[n]; this.ratio = new double[n]; for (int i = 0; i < n; i++) { ratio[i] = weight[i] == 0 ? Double.MAX_VALUE : ((double) (energy[i]) / (double) (weight[i])); } this.order = ArrayUtils.array(0, n - 1); ArraySort sorter = new ArraySort(n, false, true); sorter.sort( order, n, (i1, i2) -> { return Double.compare(ratio[i2], ratio[i1]); }); }
public PropIntEqReal(IntVar[] intVars, RealVar[] realVars, double epsilon) { super(ArrayUtils.append(intVars, realVars), PropagatorPriority.LINEAR, false); this.n = intVars.length; this.intVars = intVars; this.realVars = realVars; this.epsilon = epsilon; assert n == realVars.length; }
/** * Creates a degree-constrained minimum spanning tree constraint : GRAPH is a spanning tree of * cost COSTVAR and each vertex degree is constrained * * <p>BEWARE : assumes the channeling between GRAPH and DEGREES is already done * * @param GRAPH an undirected graph variable * @param DEGREES the degree of every vertex * @param COSTVAR variable representing the cost of the mst * @param EDGE_COSTS cost matrix (should be symmetric) * @param LAGR_MODE use the Lagrangian relaxation of the dcmst {0:no Lagrangian relaxation, * 1:Lagrangian relaxation (since root node), 2:Lagrangian relaxation but wait a first * solution before running it} * @return a degree-constrained minimum spanning tree constraint */ public static Constraint dcmst( IUndirectedGraphVar GRAPH, IntVar[] DEGREES, IntVar COSTVAR, int[][] EDGE_COSTS, int LAGR_MODE) { Propagator[] props = ArrayUtils.append( tree(GRAPH).getPropagators(), new Propagator[] { new PropTreeCostSimple(GRAPH, COSTVAR, EDGE_COSTS), new PropMaxDegVarTree(GRAPH, DEGREES) }); if (LAGR_MODE > 0) { PropLagr_DCMST_generic hk = new PropLagr_DCMST_generic(GRAPH, COSTVAR, DEGREES, EDGE_COSTS, LAGR_MODE == 2); props = ArrayUtils.append(props, new Propagator[] {hk}); } return new Constraint("dcmst", props); }
/** Inverse set propagator x in sets[y-offSet1] <=> y in inverses[x-offSet2] */ public PropInverse(SetVar[] sets, SetVar[] invsets, int offSet1, int offSet2) { super(ArrayUtils.append(sets, invsets), PropagatorPriority.LINEAR, true); n = sets.length; n2 = invsets.length; this.offSet1 = offSet1; this.offSet2 = offSet2; this.sets = Arrays.copyOfRange(vars, 0, sets.length); this.invsets = Arrays.copyOfRange(vars, sets.length, vars.length); // delta monitors sdm = new ISetDeltaMonitor[n + n2]; for (int i = 0; i < n + n2; i++) { sdm[i] = this.vars[i].monitorDelta(this); } elementForced = element -> toFilter[element - offSet].addToKernel(idx, aCause); elementRemoved = element -> toFilter[element - offSet].removeFromEnvelope(idx, aCause); }
public PropIntValuesUnion(IntVar[] X, IntVar union) { super(ArrayUtils.append(new IntVar[] {union}, X), PropagatorPriority.LINEAR, false); }
@Override public void configureSearch() { solver.set(IntStrategyFactory.minDom_LB(ArrayUtils.append(rows))); }