From 2acc57ddb8e1dd26c35062fddc26d431e7dd010e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Sun, 27 Jun 2010 20:15:51 +0200 Subject: [PATCH] ItEr60S08CUAsignacionRecursosLimitantesItEr59S08: Add method to have a graph with the elements potentially affected by insertion --- .../web/limitingresources/QueuesState.java | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/QueuesState.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/QueuesState.java index 28bfff530..d4303ea39 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/QueuesState.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/limitingresources/QueuesState.java @@ -27,10 +27,14 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import org.apache.commons.lang.Validate; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.jgrapht.DirectedGraph; import org.jgrapht.alg.CycleDetector; +import org.jgrapht.graph.DirectedMultigraph; import org.jgrapht.graph.SimpleDirectedGraph; import org.jgrapht.traverse.TopologicalOrderIterator; import org.navalplanner.business.common.BaseEntity; @@ -41,6 +45,7 @@ import org.navalplanner.business.planner.limiting.entities.InsertionRequirements import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency; import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueElement; import org.navalplanner.business.planner.limiting.entities.Gap.GapOnQueue; +import org.navalplanner.business.planner.limiting.entities.LimitingResourceQueueDependency.QueueDependencyType; import org.navalplanner.business.resources.entities.Criterion; import org.navalplanner.business.resources.entities.CriterionCompounder; import org.navalplanner.business.resources.entities.ICriterion; @@ -283,6 +288,149 @@ public class QueuesState { return result; } + public static class Edge { + public final LimitingResourceQueueElement source; + + public final LimitingResourceQueueElement target; + + public final QueueDependencyType type; + + public static Edge from(LimitingResourceQueueDependency dependency) { + return new Edge(dependency.getHasAsOrigin(), + dependency.getHasAsDestiny(), dependency.getType()); + } + + public static Edge insertionOrder( + LimitingResourceQueueElement element, + LimitingResourceQueueElement contiguousNext) { + return new Edge(element, contiguousNext, + QueueDependencyType.END_START); + } + + private Edge(LimitingResourceQueueElement source, + LimitingResourceQueueElement target, QueueDependencyType type) { + Validate.notNull(source); + Validate.notNull(target); + Validate.notNull(type); + this.source = source; + this.target = target; + this.type = type; + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(source).append(target) + .append(type).toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Edge) { + Edge another = (Edge) obj; + return new EqualsBuilder().append(source, another.source) + .append(target, another.target) + .append(type, another.type).isEquals(); + } + return false; + } + + } + + public DirectedGraph getPotentiallyAffectedByInsertion( + LimitingResourceQueueElement element) { + DirectedMultigraph result; + result = asEdges(onQueues(buildOutgoingGraphFor(getEquivalent(element)))); + Map earliestForEachQueue = earliest(byQueue(result + .vertexSet())); + for (Entry each : earliestForEachQueue + .entrySet()) { + LimitingResourceQueue queue = each.getKey(); + LimitingResourceQueueElement earliest = each.getValue(); + addInsertionOrderOnQueueEdges(result, earliest, + queue.getElementsAfter(earliest)); + } + return result; + + } + + private DirectedGraph onQueues( + DirectedGraph graph) { + SimpleDirectedGraph result; + result = instantiateDirectedGraph(); + for (LimitingResourceQueueDependency each : graph.edgeSet()) { + if (!each.getHasAsOrigin().isDetached() + && !each.getHasAsDestiny().isDetached()) { + addDependency(result, each); + } + } + return result; + } + + private DirectedMultigraph asEdges( + DirectedGraph graph) { + DirectedMultigraph result = instantiateMultiGraph(); + for (LimitingResourceQueueDependency each : graph.edgeSet()) { + Edge edge = Edge.from(each); + result.addVertex(edge.source); + result.addVertex(edge.target); + result.addEdge(edge.source, edge.target, edge); + } + return result; + } + + private DirectedMultigraph instantiateMultiGraph() { + return new DirectedMultigraph( + Edge.class); + } + + private Map> byQueue( + Collection vertexSet) { + Map> result = new HashMap>(); + for (LimitingResourceQueueElement each : vertexSet) { + assert each.getLimitingResourceQueue() != null; + forQueue(result, each.getLimitingResourceQueue()).add(each); + } + return result; + } + + private List forQueue( + Map> map, + LimitingResourceQueue queue) { + List result = map.get(queue); + if (result == null) { + result = new ArrayList(); + map.put(queue, result); + } + return result; + } + + private static Map earliest( + Map> byQueue) { + Map result = new HashMap(); + for (Entry> each : byQueue + .entrySet()) { + result.put(each.getKey(), earliest(each.getValue())); + } + return result; + } + + private static LimitingResourceQueueElement earliest( + List list) { + Validate.isTrue(!list.isEmpty()); + return Collections.min(list, LimitingResourceQueueElement.byStartTimeComparator()); + } + + private void addInsertionOrderOnQueueEdges( + DirectedGraph result, + LimitingResourceQueueElement first, + List elements) { + LimitingResourceQueueElement previous = first; + for (LimitingResourceQueueElement each : elements) { + result.addEdge(previous, each, Edge.insertionOrder(previous, each)); + previous = each; + } + } + /** * @param externalQueueElement * the queue element to insert