package edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation; import edu.usc.enl.dynamicmeasurement.data.ConfigReader; import edu.usc.enl.dynamicmeasurement.model.monitorpoint.MonitorPoint; import edu.usc.enl.dynamicmeasurement.util.Util; import org.w3c.dom.Element; import java.util.*; /** * Created with IntelliJ IDEA. * User: masoud * Date: 7/30/13 * Time: 12:15 PM */ public class EqualAvgThresholdAlgorithm extends MultiTaskResourceControl { private final int minResource; private final int maxResource; private final Random random; private double lowThreshold; private double highThreshold; private int resourceChangeStep; private List<TaskRecord2> tasks = new LinkedList<>(); public EqualAvgThresholdAlgorithm(Element element, MonitorPoint monitorPoint) { Map<String, Element> properties = Util.getChildrenProperties(element, "Property"); this.resourceChangeStep = Integer.parseInt(properties.get("ResourceChangeStep").getAttribute(ConfigReader.PROPERTY_VALUE)); this.lowThreshold = Double.parseDouble(properties.get("LowThreshold").getAttribute(ConfigReader.PROPERTY_VALUE)); this.highThreshold = Double.parseDouble(properties.get("HighThreshold").getAttribute(ConfigReader.PROPERTY_VALUE)); this.random = new Random(Long.parseLong(properties.get("Random").getAttribute(ConfigReader.PROPERTY_VALUE))); this.minResource = 1; maxResource = monitorPoint.getCapacity(); } public EqualAvgThresholdAlgorithm(int resourceChangeStep, double lowThreshold, double highThreshold, int minResource, int maxResource, Random random) { this.resourceChangeStep = resourceChangeStep; this.lowThreshold = lowThreshold; this.highThreshold = highThreshold; this.minResource = minResource; this.maxResource = maxResource; this.random = random; } // public static void main(String[] args) { // EqualAvgThresholdAlgorithm thresholdAlgorithm = new EqualAvgThresholdAlgorithm(0.1, 0.05, 0.05, 0, 1, new Random(1324234)); // TestTask task1 = new TestTask(4, new EWMAAccuracyAggregatorImpl(0)); // TestTask task2 = new TestTask(4, new EWMAAccuracyAggregatorImpl(0)); // TestTask task3 = new TestTask(2, new EWMAAccuracyAggregatorImpl(0)); // ArrayList<SingleSwitchTask> tasks = new ArrayList<>(); // tasks.add(task1); // tasks.add(task2); // tasks.add(task3); // task1.setResourceShare(1); // task2.setResourceShare(0); // task3.setResourceShare(0); // Random random1 = new Random(34309432); // for (int i = 0; i < 50; i++) { // System.out.print(i); // for (Task task : tasks) { // ((TestTask) task).updateAccuracyEstimate(); // System.out.print(", " + task); // } // System.out.println(); // thresholdAlgorithm.allocate(tasks); // if (i % 5 == 4) { // ((TestTask) task1).setCoefficient(random1.nextInt(10) + 1); // } // } // } @Override public void allocate() { double averageAccuracy = 0; for (TaskRecord2 task : tasks) { averageAccuracy += task.getTask().getAggregatedAccuracy(); } averageAccuracy /= tasks.size(); List<AllocationTaskView> toRemoveTask = new ArrayList<>(); List<AllocationTaskView> toAddTask = new ArrayList<>(); for (TaskRecord2 task1 : tasks) { AllocationTaskView task = (AllocationTaskView) task1.getTask(); double accuracy = task.getAggregatedAccuracy(); if (accuracy > averageAccuracy + highThreshold && task.getResourceShare() > resourceChangeStep + minResource) { toRemoveTask.add(task); } else if (accuracy < averageAccuracy + lowThreshold && task.getResourceShare() < maxResource - resourceChangeStep) { toAddTask.add(task); } } if (toRemoveTask.size() > 0 && toAddTask.size() > 0) { if (toRemoveTask.size() > toAddTask.size()) { Collections.shuffle(toRemoveTask, random); toRemoveTask = toRemoveTask.subList(0, toAddTask.size()); } else if (toRemoveTask.size() < toAddTask.size()) { Collections.shuffle(toAddTask, random); toAddTask = toAddTask.subList(0, toRemoveTask.size()); } for (AllocationTaskView task : toRemoveTask) { task.setResourceShare(task.getResourceShare() - resourceChangeStep); } for (AllocationTaskView task : toAddTask) { task.setResourceShare(task.getResourceShare() + resourceChangeStep); } } } @Override public boolean addTask(AllocationTaskView task) { //assume the new task accuracy is 0, take resource from highest accuracy guy, //if no other task give all if (tasks.size() == 0) { task.setResourceShare(1); return true; } //if there double maxAccuracy = 0; AllocationTaskView maxTask = null; for (TaskRecord2 oldTask : tasks) { double accuracy = oldTask.getTask().getAggregatedAccuracy(); if (maxTask == null || maxAccuracy < accuracy) { maxAccuracy = accuracy; maxTask = oldTask.getTask(); } } if (maxTask.getResourceShare() < minResource + resourceChangeStep) { return false; } tasks.add(new TaskRecord2(task, -tasks.size())); maxTask.setResourceShare(maxTask.getResourceShare() - resourceChangeStep); task.setResourceShare(resourceChangeStep); return true; } @Override public void removeTask(AllocationTaskView task) { //give its share to the task with minimum resource if (tasks.size() > 0) { for (Iterator<TaskRecord2> iterator = tasks.iterator(); iterator.hasNext(); ) { TaskRecord2 next = iterator.next(); if (next.getTask().equals(task)) { iterator.remove(); break; } } //find min accuracy task double minAccuracy = 0; AllocationTaskView minTask = null; for (TaskRecord2 taskRecord2 : tasks) { double accuracy = taskRecord2.getTask().getAggregatedAccuracy(); if (minTask == null || minAccuracy > accuracy) { minAccuracy = accuracy; minTask = taskRecord2.getTask(); } } minTask.setResourceShare(minTask.getResourceShare() + task.getResourceShare()); } task.setResourceShare(0); // double resourceShare = task.getResourceShare() / newTasks.size(); // for (SingleSwitchTask singleSwitchTask : newTasks.keySet()) { // singleSwitchTask.setResourceShare(singleSwitchTask.getResourceShare() + resourceShare); // } } // private static class TestTask extends SingleSwitchTask { // private double coefficient; // // private TestTask(double coefficient, AccuracyAggregator accuracyAggregator) { // super("", accuracyAggregator, 1); // this.coefficient = coefficient; // } // // private void setCoefficient(double coefficient) { // this.coefficient = coefficient; // } // // public void updateAccuracyEstimate() { // setAccuracy(1 - Math.exp(-coefficient * getResourceShare())); // } // // @Override // public String toString() { // return coefficient + "," + getResourceShare() + "," + getAccuracy(); // } // // } }