ItEr59S08CUAsignacionRecursosLimitantesItEr58S10: Add method for getting all the gaps that could potentially satisfy some requirements

This commit is contained in:
Óscar González Fernández 2010-06-06 17:31:45 +02:00
parent a436f9df53
commit cbe70505c8
3 changed files with 168 additions and 4 deletions

View file

@ -60,11 +60,15 @@ public class GapRequirements {
this.earliestPossibleEnd = earliestPossibleEnd;
}
public AllocationOnGap guessValidity(Gap gap) {
public boolean isPotentiallyValid(Gap gap) {
DateAndHour gapEnd = gap.getEndTime();
if (gapEnd != null
&& (earliestPossibleStart.compareTo(gapEnd) >= 0 || earliestPossibleEnd
.isAfter(gapEnd))) {
return gapEnd == null
|| (earliestPossibleStart.isBefore(gapEnd) && !earliestPossibleEnd
.isAfter(gapEnd));
}
public AllocationOnGap guessValidity(Gap gap) {
if (!isPotentiallyValid(gap)) {
return AllocationOnGap.invalidOn(gap);
}
DateAndHour realStart = DateAndHour.Max(earliestPossibleStart, gap
@ -171,4 +175,8 @@ public class GapRequirements {
return result;
}
public LimitingResourceQueueElement getElement() {
return element;
}
}

View file

@ -0,0 +1,127 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.limitingresources;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections.comparators.BooleanComparator;
import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue;
/**
* Utility class for doing a merge sort of several ordered list of Gaps <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class GapsMergeSort {
private GapsMergeSort() {
}
private static class CurrentGap implements Comparable<CurrentGap> {
static List<CurrentGap> convert(
Collection<? extends Iterator<GapOnQueue>> iterators) {
List<CurrentGap> result = new ArrayList<CurrentGap>();
for (Iterator<GapOnQueue> iterator : iterators) {
result.add(new CurrentGap(iterator));
}
return result;
}
private Iterator<GapOnQueue> iterator;
private GapOnQueue current;
private CurrentGap(Iterator<GapOnQueue> iterator) {
this.iterator = iterator;
}
public GapOnQueue consume() {
GapOnQueue result = getCurrent();
current = null;
return result;
}
boolean hasFinished() {
return current == null && !iterator.hasNext();
}
private GapOnQueue getCurrent() {
if (hasFinished()) {
throw new IllegalStateException("already finished");
}
if (current != null) {
return current;
}
return current = iterator.next();
}
/**
* Ordering by hasFinished and the gap. An already finished is
* considered bigger than a not finished
*/
@Override
public int compareTo(CurrentGap other) {
int finishComparison = BooleanComparator.getFalseFirstComparator()
.compare(hasFinished(), other.hasFinished());
if (finishComparison != 0) {
return finishComparison;
} else if (hasFinished()) {
assert other.hasFinished();
return 0;
} else {
assert !hasFinished() && !other.hasFinished();
return getCurrent().getGap().compareTo(
other.getCurrent().getGap());
}
}
}
public static List<GapOnQueue> sort(
List<List<GapOnQueue>> orderedListsOfGaps) {
if (orderedListsOfGaps.size() == 1) {
return orderedListsOfGaps.get(0);
}
List<GapOnQueue> result = new ArrayList<GapOnQueue>();
List<CurrentGap> currentGaps = CurrentGap.convert(iteratorsFor(orderedListsOfGaps));
CurrentGap min = null;
do {
min = Collections.min(currentGaps);
if (!min.hasFinished()) {
result.add(min.consume());
}
} while (!min.hasFinished());
return result;
}
private static List<Iterator<GapOnQueue>> iteratorsFor(
List<List<GapOnQueue>> orderedListsOfGaps) {
List<Iterator<GapOnQueue>> result = new ArrayList<Iterator<GapOnQueue>>();
for (List<GapOnQueue> each : orderedListsOfGaps) {
result.add(each.iterator());
}
return result;
}
}

View file

@ -32,7 +32,9 @@ import org.navalplanner.business.common.BaseEntity;
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
import org.navalplanner.business.planner.entities.ResourceAllocation;
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
import org.navalplanner.business.planner.limiting.entities.GapRequirements;
import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement;
import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionCompounder;
import org.navalplanner.business.resources.entities.ICriterion;
@ -154,6 +156,33 @@ public class QueuesState {
throw new RuntimeException("unexpected type of: " + resourceAllocation);
}
public GapRequirements getRequirementsFor(
LimitingResourceQueueElement element) {
return GapRequirements.forElement(getEquivalent(element));
}
/**
* @return all the gaps that could potentially fit <code>element</code>
* ordered by start date
*/
public List<GapOnQueue> getPotentiallyValidGapsFor(
GapRequirements requirements) {
List<LimitingResourceQueue> assignableQueues = getAssignableQueues(requirements
.getElement());
List<List<GapOnQueue>> allGaps = gapsFor(assignableQueues, requirements);
return GapsMergeSort.sort(allGaps);
}
private List<List<GapOnQueue>> gapsFor(
List<LimitingResourceQueue> assignableQueues,
GapRequirements requirements) {
List<List<GapOnQueue>> result = new ArrayList<List<GapOnQueue>>();
for (LimitingResourceQueue each : assignableQueues) {
result.add(each.getGapsPotentiallyValidFor(requirements));
}
return result;
}
private List<LimitingResourceQueue> findQueuesMatchingCriteria(
Set<Criterion> criteria) {
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();