org.chocosolver.solver.constraints.nary.cumulative.Cumulative Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of choco-solver Show documentation
Show all versions of choco-solver Show documentation
Open-source constraint solver.
/*
* This file is part of choco-solver, http://choco-solver.org/
*
* Copyright (c) 2023, 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.constraints.nary.cumulative;
import org.chocosolver.solver.constraints.Constraint;
import org.chocosolver.solver.constraints.ConstraintsName;
import org.chocosolver.solver.constraints.Propagator;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.solver.variables.Task;
import org.chocosolver.util.tools.ArrayUtils;
import java.util.Arrays;
/**
* Cumulative constraint
* @author Jean-Guillaume Fages
* @since 22/10/13
*/
public class Cumulative extends Constraint {
//***********************************************************************************
// CONSTRUCTORS
//***********************************************************************************
/**
* Cumulative constraint
*
* @param tasks task variables (embed start, duration and end variables)
* @param heights height variables (represent the consumption of each task on the resource)
* @param capacity maximal capacity of the resource (same at each point in time)
* @param graphBased parameter indicating how to filter:
* - TRUE: applies on subset of overlapping tasks
* - FALSE: applies on all tasks
* @param filters Filtering algorithm to use:
* - TIME: filters time-table from considering each point in time
* (efficient in practice as long as the time horizon is not too high)
* - SWEEP: filters time-table with a sweep-based algorithm
* - NRJ: greedy energy-based filter.
* BEWARE: should not be used alone, use it in addition to either SWEEP or TIME.
*
*/
public Cumulative(Task[] tasks, IntVar[] heights, IntVar capacity, boolean graphBased, Filter... filters) {
super(ConstraintsName.CUMULATIVE,createPropagators(tasks, heights, capacity, graphBased, Arrays.stream(filters).map(f->f.make(tasks.length)).toArray(CumulFilter[]::new)));
}
/**
* Cumulative constraint
*
* @param tasks task variables (embed start, duration and end variables)
* @param heights height variables (represent the consumption of each task on the resource)
* @param capacity maximal capacity of the resource (same at each point in time)
* @param graphBased parameter indicating how to filter:
* - TRUE: applies on subset of overlapping tasks
* - FALSE: applies on all tasks
* @param filters Filtering algorithm to use:
* - TIME: filters time-table from considering each point in time
* (efficient in practice as long as the time horizon is not too high)
* - SWEEP: filters time-table with a sweep-based algorithm
* - NRJ: greedy energy-based filter.
* BEWARE: should not be used alone, use it in addition to either SWEEP or TIME.
*
*/
public Cumulative(Task[] tasks, IntVar[] heights, IntVar capacity, boolean graphBased, CumulFilter... filters) {
super(ConstraintsName.CUMULATIVE,createPropagators(tasks, heights, capacity, graphBased, filters));
}
//***********************************************************************************
// METHODS
//***********************************************************************************
private static Propagator[] createPropagators(Task[] tasks, IntVar[] heights, IntVar capa, boolean graphBased, CumulFilter... filters){
int n = tasks.length;
assert n==heights.length && n > 0;
IntVar[] vars = extract(tasks,heights,capa);
IntVar[] s = Arrays.copyOfRange(vars,0,n);
IntVar[] d = Arrays.copyOfRange(vars,n,2*n);
IntVar[] e = Arrays.copyOfRange(vars,2*n,3*n);
IntVar[] h = Arrays.copyOfRange(vars,3*n,4*n);
// propagators are posted twice, to achieve fixpoint
if(graphBased){
return new Propagator[]{
new PropGraphCumulative(s,d,e,h,capa,false, filters),
new PropGraphCumulative(s,d,e,h,capa,true, filters)
};
}else{
return new Propagator[]{
new PropCumulative(s,d,e,h,capa, filters),
new PropCumulative(s,d,e,h,capa, filters)
};
}
}
public static IntVar[] extract(Task[] tasks, IntVar[] heights, IntVar capa){
int n = tasks.length;
IntVar[] starts = new IntVar[n];
IntVar[] durations = new IntVar[n];
IntVar[] ends = new IntVar[n];
for (int i = 0; i < n; i++) {
starts[i] = tasks[i].getStart();
durations[i] = tasks[i].getDuration();
ends[i] = tasks[i].getEnd();
}
return ArrayUtils.append(starts,durations,ends,heights,new IntVar[]{capa});
}
//***********************************************************************************
// FILTERING ALGORITHMS
//***********************************************************************************
/**
* Filtering algorithms for Cumulative constraint
*/
public enum Filter {
/**
* filters height variables only (sweep-based algorithm)
* idempotent (on the given set of variables only)
*/
HEIGHTS{
public CumulFilter make(int n){
return new HeightCumulFilter(n);
}
},
/**
* time-table algorithm based on each point in time
* not idempotent
*/
TIME{
public CumulFilter make(int n){
return new TimeCumulFilter(n);
}
},
/**
* time-table algorithm based on each point in time
* not idempotent
*/
NAIVETIME{
@Override
public CumulFilter make(int n) {
return new NaiveTimeCumulFilter(n);
}
},
/**
* time-table algorithm based on a sweep line
* idempotent (on the given set of variables only)
*/
SWEEP{
public CumulFilter make(int n){
return new SweepCumulFilter(n);
}
},
/**
* time-table algorithm based on a sweep line
* idempotent (on the given set of variables only)
*/
SWEEP_HEI_SORT {
public CumulFilter make(int n){
return new SweepHeiSortCumulFilter(n);
}
},
/**
* energetic reasoning to filter
* not idempotent
* not enough to ensure correctness (only an additional filtering)
*/
NRJ{
public CumulFilter make(int n){
return new NRJCumulFilter(n);
}
},
/**
* energetic reasoning to filter disjunctive constraint
* Only propagated on variable subsets of size < 30
* not idempotent
* not enough to ensure correctness (only an additional filtering)
*/
DISJUNCTIVE_TASK_INTERVAL {
public CumulFilter make(int n){
return new DisjunctiveTaskIntervalFilter(n);
}
},
/**
* Combines above filters as a black-box
* not idempotent
*/
DEFAULT {
public CumulFilter make(int n){
return new DefaultCumulFilter(n);
}
};
/**
* Create an instance of the filtering algorithm
* @param n maximum number of tasks
* @return an instance of the filtering algorithm
*/
public abstract CumulFilter make(int n);
}
}