CookingTimeEstimator.java
/*
* Copyright 2016 the Cook-E development team
*
* This file is part of Cook-E.
*
* Cook-E is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cook-E 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cook-E. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cook_e.data;
import java.util.*;
/**
* A class for estimating cooking times.
*/
public class CookingTimeEstimator {
private CookingTimeEstimator(Schedule schedule) {}
/**
* Calculates and returns the estimated amount of time it would take to cook
* the given schedule.
*
* @param schedule the schedule to measure the estimated time of
* @return the estimated amount of time it would take to cook the given schedule
*/
public static int getOptimizedTime(Schedule schedule) {
int totalTime = 0;
Map<Recipe, Integer> busyTimes = new HashMap<Recipe, Integer>();
for (int i = 0; i < schedule.getStepCount(); i++) {
Step currStep = schedule.getNextStep();
if (currStep == null) {
// handles case where all remaining recipes are blocked
int minBusyTime = Integer.MAX_VALUE;
for (Recipe recipe : busyTimes.keySet()) {
int currBusyTime = busyTimes.get(recipe);
if (currBusyTime < minBusyTime) {
minBusyTime = currBusyTime;
}
}
updateBusyTimes(busyTimes, minBusyTime, schedule);
totalTime += minBusyTime;
} else {
if (currStep.isSimultaneous()) {
// handles case where the next step is simultaneous
busyTimes.put(schedule.getCurrentStepRecipe(), currStep.getDurationMinutes());
} else {
// handles case where the next step is not simultaneous
int currStepTime = currStep.getDurationMinutes();
updateBusyTimes(busyTimes, currStepTime, schedule);
totalTime += currStepTime;
}
}
}
return totalTime;
}
/**
* Calculates and returns the estimated amount of time it would take to cook
* the given bunch if each recipe is done one after another and no interleaving
* of steps is done.
*
* @param bunch the group of recipes estimate the cook time of
* @return the estimated cooking time of cooking one recipe after another
*/
public static int getOriginalTime(Bunch bunch) {
int totalTime = 0;
List<Recipe> recipes = bunch.getRecipes();
for (Recipe recipe : recipes) {
List<Step> steps = recipe.getSteps();
for (Step step : steps) {
totalTime += step.getDurationMinutes();
}
}
return totalTime;
}
/**
*
*
* @param busyTimes the map of recipes to the amount of busy time left to update
* @param offset the amount to decrease the busy times by
* @param schedule the schedule to update when recipes busy times hit zero
*/
private static void updateBusyTimes(Map<Recipe, Integer> busyTimes, int offset, Schedule schedule) {
Iterator<Map.Entry<Recipe, Integer>> busyTimesIterator = busyTimes.entrySet().iterator();
while (busyTimesIterator.hasNext()) {
Map.Entry<Recipe, Integer> currBusyTimeEntry = busyTimesIterator.next();
Recipe recipe = currBusyTimeEntry.getKey();
int busyTime = currBusyTimeEntry.getValue();
busyTimes.put(recipe, Math.max(busyTime - offset, 0));
if (busyTimes.get(recipe) == 0) {
busyTimesIterator.remove();
schedule.finishSimultaneousStepFromRecipe(recipe);
}
}
}
}