package gipad.plan.choco.constraints; import solver.Solver; import solver.constraints.Constraint; import solver.search.loop.monitors.SearchMonitorFactory; import solver.search.strategy.selectors.values.InDomainMin; import solver.search.strategy.selectors.variables.Smallest; import solver.search.strategy.strategy.Assignment; import solver.variables.IntVar; import solver.variables.Task; import solver.variables.VariableFactory; import org.junit.*; @SuppressWarnings("rawtypes") public class CumulativeMultiDimTest { // ===== DATA ===== Task[] vTasks; IntVar[] vStarts; IntVar[] vDurations; IntVar[] vEnds ; IntVar[][] vHeights ; IntVar[] vCapacities ; IntVar[][] vLoads ; //************ Static variables private final int CUMULATIVE = PropTTPCDynamicSweepLoads.CUMULATIVE; private final int COLORED = PropTTPCDynamicSweepLoads.COLORED; @SuppressWarnings("unchecked") @Test public void testMe() { // ===== BUILD TASKS/ITEMS ===== Solver solver = new Solver(); int[] startsLB = new int[]{0, 0, 0, 0, 0, 0,1,2,3}; int[] endsUB = new int[]{4, 4, 4, 4, 4, 1,2,3,4}; int[] durations = new int[]{1, 1, 1, 1, 1, 1,1,1,1}; int[][] heights = new int[][]{ {2,2,1}, {2,2,2}, {1,1,3}, {1,1,4}, {2,2,5}, {5,5,0},{5,5,0},{5,5,0},{5,5,0}}; int[][] successors = new int[startsLB.length][0]; int[] capacities = new int[]{10,10,2}; int[] resourceType = new int[]{CUMULATIVE,CUMULATIVE,COLORED}; int nbTasks = startsLB.length; int nbResources = capacities.length; int[] interestingTimePoints = new int[]{0,1,2,3}; int[] interestingResources = new int[]{0}; int nbInterestingTimePoints = interestingTimePoints.length; int nbInterestingResources = interestingResources.length; //Convert to IntVar intToIntVar(solver, nbTasks, nbResources, nbInterestingTimePoints, nbInterestingResources, startsLB, endsUB, durations,heights, interestingTimePoints, capacities,interestingResources); // ===== BUILD AND POST CONSTRAINT ===== IntVar[] allVars = varsAggregator( solver, nbTasks, nbResources, nbInterestingTimePoints, nbInterestingResources, capacities); Constraint c = new Constraint(allVars, solver); c.addPropagators(new PropTTPCDynamicSweepLoads(allVars,nbTasks,nbResources,capacities,successors,resourceType,interestingTimePoints,interestingResources)); solver.post(c); // ===== POST ADDITIONAL CONSTRAINTS ? ===== // search configuration solver.set(new Assignment(new Smallest(vStarts), new InDomainMin())); //OK (default) // log configuration SearchMonitorFactory.log(solver, true, true); SearchMonitorFactory.limitTime(solver, 10000); // solve solver.findSolution(); // Pretty out prettyOut(solver,nbTasks,nbResources,resourceType,capacities); } private void prettyOut(Solver solver, int nbTasks,int nbResources, int[] resourceType, int[] capacities) { System.out.println(solver); int horizon = 4; for (int i = 0; i < nbResources; i++) { System.out.println("Res Type " + resourceType[i]); System.out.println("Capacity " + capacities[i]); int[] cumul = new int[horizon + 1]; for (int j = 0; j < nbTasks; j++) { System.out.print("Task n°" + j + " start : " + vTasks[j].getStart().getValue() + " end : " + vTasks[j].getEnd().getValue() +" "); for (int k = 0; k < horizon + 1; k++) { if (k < vTasks[j].getStart().getValue() || k >= vTasks[j].getEnd().getValue()) { System.out.print("_"); } else { System.out.print(vHeights[j][i].getValue()); cumul[k] += vHeights[j][i].getValue(); } } System.out.println(); } System.out.print(" "); for (int k = 0; k < horizon + 1; k++) { System.out.print(cumul[k]); } System.out.println(); System.out.println(); } } private IntVar[] varsAggregator(Solver solver, int nbTasks, int nbResources, int nbInterestingTimePoints, int nbInterestingResources, int[] capacities) { int hIdx = 3*nbTasks; IntVar[] allVars = new IntVar[hIdx+nbTasks*nbResources+nbResources+nbInterestingTimePoints*nbInterestingResources]; for (int t=0;t<nbTasks;t++) { allVars[t] = vStarts[t]; allVars[t+nbTasks] = vDurations[t]; allVars[t+2*nbTasks] = vEnds[t]; for (int r=0;r<nbResources;r++) { allVars[hIdx+t*nbResources+r] = vHeights[t][r]; } } int cIdx = hIdx+nbTasks*nbResources; for (int r=0;r<nbResources;r++) { vCapacities[r] = VariableFactory.bounded("limit_" + r, capacities[r], capacities[r], solver); allVars[cIdx+r] = vCapacities[r]; } int lIdx = cIdx+nbResources; for (int i=0;i<nbInterestingTimePoints;i++) { for (int j=0;j<nbInterestingResources;j++) { allVars[lIdx+i*nbInterestingResources+j] = vLoads[i][j]; } } return allVars; } private void intToIntVar(Solver solver, int nbTasks, int nbResources, int nbInterestingTimePoints, int nbInterestingResources, int[] startsLB, int[] endsUB, int[] durations, int[][] heights, int[] interestingTimePoints, int[] capacities, int[] interestingResources) { vTasks = new Task[nbTasks]; vStarts = new IntVar[nbTasks]; vDurations = new IntVar[nbTasks]; vEnds = new IntVar[nbTasks]; vHeights = new IntVar[nbTasks][nbResources]; vCapacities = new IntVar[nbResources]; vLoads = new IntVar[nbInterestingTimePoints][nbInterestingResources]; for(int i=0;i< nbTasks;i++){ vStarts[i] = VariableFactory.bounded("s_"+i, startsLB[i], endsUB[i]-durations[i], solver); vDurations[i] = VariableFactory.bounded("d_"+i, durations[i], durations[i], solver); vEnds[i] = VariableFactory.bounded("e_"+i, startsLB[i]+durations[i], endsUB[i], solver); vTasks[i] = VariableFactory.task(vStarts[i], vDurations[i], vEnds[i]); for (int r=0;r<nbResources;r++) { vHeights[i][r] = VariableFactory.bounded("t"+i+"_height_r"+r,heights[i][r],heights[i][r], solver); } } for (int i=0;i<nbInterestingTimePoints;i++) { for (int j=0;j<nbInterestingResources;j++) { vLoads[i][j] = VariableFactory.bounded("load_"+interestingTimePoints[i],0,capacities[interestingResources[j]],solver); } } } }