
org.btrplace.scheduler.choco.constraint.migration.CMinMTTRMig Maven / Gradle / Ivy
/*
* Copyright (c) 2016 University Nice Sophia Antipolis
*
* This file is part of btrplace.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
package org.btrplace.scheduler.choco.constraint.migration;
import org.btrplace.model.Instance;
import org.btrplace.model.Node;
import org.btrplace.model.VM;
import org.btrplace.model.constraint.migration.MinMTTRMig;
import org.btrplace.scheduler.SchedulerException;
import org.btrplace.scheduler.choco.Parameters;
import org.btrplace.scheduler.choco.ReconfigurationProblem;
import org.btrplace.scheduler.choco.Slice;
import org.btrplace.scheduler.choco.constraint.CObjective;
import org.btrplace.scheduler.choco.constraint.mttr.MovementGraph;
import org.btrplace.scheduler.choco.constraint.mttr.MyInputOrder;
import org.btrplace.scheduler.choco.constraint.mttr.OnStableNodeFirst;
import org.btrplace.scheduler.choco.constraint.mttr.StartOnLeafNodes;
import org.btrplace.scheduler.choco.transition.BootableNode;
import org.btrplace.scheduler.choco.transition.NodeTransition;
import org.btrplace.scheduler.choco.transition.ShutdownableNode;
import org.btrplace.scheduler.choco.transition.VMTransition;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.constraints.Constraint;
import org.chocosolver.solver.constraints.IntConstraintFactory;
import org.chocosolver.solver.search.strategy.ISF;
import org.chocosolver.solver.search.strategy.selectors.values.IntDomainMin;
import org.chocosolver.solver.search.strategy.strategy.AbstractStrategy;
import org.chocosolver.solver.search.strategy.strategy.IntStrategy;
import org.chocosolver.solver.search.strategy.strategy.StrategiesSequencer;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.solver.variables.VariableFactory;
import java.util.*;
import java.util.stream.Stream;
/**
* An objective that minimizes the time to repair a non-viable model involving a set of migrations.
*
* @author Vincent Kherbache
*/
public class CMinMTTRMig implements CObjective {
private ReconfigurationProblem rp;
private List costConstraints;
private boolean costActivated = false;
/**
* Make a new Objective.
*/
public CMinMTTRMig(MinMTTRMig m) {
costConstraints = new ArrayList<>();
}
public CMinMTTRMig() {
this(null);
}
@Override
public boolean inject(Parameters ps, ReconfigurationProblem rp) throws SchedulerException {
this.rp = rp;
List endVars = new ArrayList<>();
// Define the cost constraint: sum of all actions' end time
for (VMTransition m : rp.getVMActions()) {
endVars.add(m.getEnd());
}
for (NodeTransition m : rp.getNodeActions()) {
endVars.add(m.getEnd());
}
IntVar[] costs = endVars.toArray(new IntVar[endVars.size()]);
IntVar cost = VariableFactory.bounded(rp.makeVarLabel("costEndVars"), 0, Integer.MAX_VALUE/100, rp.getSolver());
costConstraints.add(IntConstraintFactory.sum(costs, cost));
// Set the objective, minimize the cost
rp.setObjective(true, cost);
// Inject the scheduling heuristic
injectSchedulingHeuristic(cost);
// Post the cost constraint
postCostConstraints();
return true;
}
/**
* Inject a specific scheduling heuristic to the solver.
*
* @param cost the global cost variable.
*/
private void injectSchedulingHeuristic(IntVar cost) {
// Init a list of strategies
List> strategies = new ArrayList<>();
// Init a list of vars
List endVars = new ArrayList<>();
// Boot nodes
for (Node n : rp.getNodes()) {
if (rp.getNodeAction(n) instanceof BootableNode) {
endVars.add(rp.getNodeAction(n).getEnd());
}
}
if (!endVars.isEmpty()) {
strategies.add(ISF.custom(
ISF.minDomainSize_var_selector(),
ISF.min_value_selector(),
ISF.split(), // Split from max
endVars.toArray(new IntVar[endVars.size()])
));
}
endVars.clear();
// Migrate VMs
MovementGraph gr = new MovementGraph(rp);
OnStableNodeFirst schedHeuristic = new OnStableNodeFirst(rp);
Stream s = rp.getVMActions().stream().map(VMTransition::getDSlice).filter(Objects::nonNull);
IntVar[] starts = s.map(Slice::getStart).toArray(IntVar[]::new);
strategies.add(new IntStrategy(starts, new StartOnLeafNodes(rp, gr), new IntDomainMin()));
strategies.add(new IntStrategy(schedHeuristic.getScope(), schedHeuristic, new IntDomainMin()));
// Add remaining VMs actions
for (VMTransition a : rp.getVMActions()) {
endVars.add(a.getEnd());
}
if (!endVars.isEmpty()) {
strategies.add(ISF.custom(
ISF.minDomainSize_var_selector(),
ISF.min_value_selector(),
ISF.split(), // Split from max
endVars.toArray(new IntVar[endVars.size()])
));
}
endVars.clear();
// Shutdown nodes
for (Node n : rp.getNodes()) {
if (rp.getNodeAction(n) instanceof ShutdownableNode) {
endVars.add(rp.getNodeAction(n).getEnd());
}
}
if (!endVars.isEmpty()) {
strategies.add(ISF.custom(
ISF.minDomainSize_var_selector(),
ISF.min_value_selector(),
ISF.split(), // Split from max
endVars.toArray(new IntVar[endVars.size()])
));
}
// Set the strategies in the correct order (as added before)
strategies.add(new IntStrategy(new IntVar[]{rp.getEnd(), cost}, new MyInputOrder<>(rp.getSolver(), this), new IntDomainMin()));
// Add all defined strategies
rp.getSolver().getSearchLoop().set(
new StrategiesSequencer(
rp.getSolver().getEnvironment(),
strategies.toArray(new AbstractStrategy[strategies.size()])
)
);
}
@Override
public void postCostConstraints() {
//TODO: Delay insertion ?
if (!costActivated) {
rp.getLogger().debug("Post the cost-oriented constraints");
costActivated = true;
Solver s = rp.getSolver();
costConstraints.forEach(s::post);
}
}
@Override
public Set getMisPlacedVMs(Instance i) {
return Collections.emptySet();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy