Commit 20a1dd9e authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht

Added utility methods & tests for the inner delay calculations.

parent c2875b9e
...@@ -106,19 +106,7 @@ public class FeasibleMinIIProperty extends Property { ...@@ -106,19 +106,7 @@ public class FeasibleMinIIProperty extends Property {
this.minII = minII; this.minII = minII;
this.backedgeDelay = backedgeDelay; this.backedgeDelay = backedgeDelay;
this.backedgeDistance = backedgeDistance; this.backedgeDistance = backedgeDistance;
this.maxInnerDelay = SchedulingUtils.getMaxInnerDelay(minII, backedgeDelay, backedgeDistance);
/*
* Based on the RecMinII formula, we can derive the maximum possible inner delay
* of a cycle which will not result in a RecMinII (and thus a MinII) greater
* than the specified MinII as follows:
*
* RecMinII = ceil((maxInnerDelay + backedgeDelay) / backedgeDistance)
*
* RecMinII * backedgeDistance = maxInnerDelay + backedgeDelay
*
* RecMinII * backedgeDistance - backedgeDelay = maxInnerDelay
*/
this.maxInnerDelay = minII * backedgeDistance - backedgeDelay;
this.enclosedNodes = new HashSet<>(); this.enclosedNodes = new HashSet<>();
this.formulation = formulation; this.formulation = formulation;
......
...@@ -44,13 +44,16 @@ import java.util.function.Predicate; ...@@ -44,13 +44,16 @@ import java.util.function.Predicate;
/** /**
* This property creates graphs which are infeasible regarding a specified MinII. The infeasibility is ensured through * This property creates graphs which are infeasible regarding a specified MinII. The infeasibility is ensured through
* means of arranging specific amounts of resource-sharing nodes in infeasible cycles (i.e. the RecMinII will always be * means of arranging specific amounts of resource-sharing nodes in infeasible cycles (i.e. the RecMinII is always used
* used to generate the requested MinII - its corresponding cycles will be infeasible however). * to generate the requested MinII).
* *
* @author Sebastian Vollbrecht * @author Sebastian Vollbrecht
*/ */
public class InfeasibleMinIIProperty extends Property { public class InfeasibleMinIIProperty extends Property {
/**
* The MinII whose infeasibility is to be ensured.
*/
private final int minII; private final int minII;
/** /**
...@@ -63,13 +66,6 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -63,13 +66,6 @@ public class InfeasibleMinIIProperty extends Property {
*/ */
private final int backedgeDistance; private final int backedgeDistance;
/**
* The maximum inner delay of the RecMinII-ensuring SCCs (i.e. the maximum delay of a path through it consisting of
* forward edges only). This must not be exceeded, as otherwise the RecMinII of the SCCs would exceed the specified
* MinII of the property.
*/
private final int maxInnerDelay;
/** /**
* Creates a new infeasible MinII property which ensures the specified MinII during graph creation. Uses 1 for the * Creates a new infeasible MinII property which ensures the specified MinII during graph creation. Uses 1 for the
* delay and distance parameters of the RecMinII-ensuring backedge. * delay and distance parameters of the RecMinII-ensuring backedge.
...@@ -107,19 +103,6 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -107,19 +103,6 @@ public class InfeasibleMinIIProperty extends Property {
this.backedgeDelay = backedgeDelay; this.backedgeDelay = backedgeDelay;
this.backedgeDistance = backedgeDistance; this.backedgeDistance = backedgeDistance;
/*
* Based on the RecMinII formula, we can derive the maximum possible inner delay
* of a cycle which will not result in a RecMinII (and thus a MinII) greater
* than the specified MinII as follows:
*
* RecMinII = ceil((maxInnerDelay + backedgeDelay) / backedgeDistance)
*
* RecMinII * backedgeDistance = maxInnerDelay + backedgeDelay
*
* RecMinII * backedgeDistance - backedgeDelay = maxInnerDelay
*/
this.maxInnerDelay = minII * backedgeDistance - backedgeDelay;
} }
@Override @Override
...@@ -147,7 +130,11 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -147,7 +130,11 @@ public class InfeasibleMinIIProperty extends Property {
throw new MinIIImpossibleException(resMinII, minII); throw new MinIIImpossibleException(resMinII, minII);
} }
StartConfiguration startCfg = chooseStartConfiguration(getProblematicResources()); int maxInnerDelay = SchedulingUtils.getMaxInnerDelay(minII, backedgeDelay, backedgeDistance);
Set<Resource> problematicResources = getProblematicResources(maxInnerDelay);
StartConfiguration startCfg = chooseStartConfiguration(problematicResources, maxInnerDelay);
InfeasibleConfiguration infeasibleCfg = chooseInfeasibleConfiguration(startCfg); InfeasibleConfiguration infeasibleCfg = chooseInfeasibleConfiguration(startCfg);
...@@ -167,7 +154,7 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -167,7 +154,7 @@ public class InfeasibleMinIIProperty extends Property {
// Do nothing. // Do nothing.
} }
private Set<Resource> getProblematicResources() { private Set<Resource> getProblematicResources(int maxInnerDelay) {
/* Determines possible problematic resources from the given set of nodes. */ /* Determines possible problematic resources from the given set of nodes. */
Set<Resource> problematicResources = InfeasibilityInspector.getProblematicResources(nodes, maxInnerDelay); Set<Resource> problematicResources = InfeasibilityInspector.getProblematicResources(nodes, maxInnerDelay);
...@@ -187,7 +174,7 @@ public class InfeasibleMinIIProperty extends Property { ...@@ -187,7 +174,7 @@ public class InfeasibleMinIIProperty extends Property {
* destination node layer. It is important to note that valid possibilities/destination node combinations will NOT * destination node layer. It is important to note that valid possibilities/destination node combinations will NOT
* be disregarded in any way - every configuration still remains possible.</i> * be disregarded in any way - every configuration still remains possible.</i>
*/ */
private StartConfiguration chooseStartConfiguration(Set<Resource> problematicResources) { private StartConfiguration chooseStartConfiguration(Set<Resource> problematicResources, int maxInnerDelay) {
/* /*
* Possible start configurations can be computed for every potential resource. * Possible start configurations can be computed for every potential resource.
......
...@@ -52,7 +52,6 @@ public final class PlannedEdge { ...@@ -52,7 +52,6 @@ public final class PlannedEdge {
this.distance = distance; this.distance = distance;
} }
/** /**
* Distributes an amount of delay over a collection of planned edges. * Distributes an amount of delay over a collection of planned edges.
* *
...@@ -60,7 +59,8 @@ public final class PlannedEdge { ...@@ -60,7 +59,8 @@ public final class PlannedEdge {
* @param delay the delay to distribute * @param delay the delay to distribute
* @param rng the {@link SeededRandom} instance to use * @param rng the {@link SeededRandom} instance to use
* @throws NullPointerException if the set of edges is null * @throws NullPointerException if the set of edges is null
* @throws IllegalArgumentException if the set of edges is empty and the delay to distribute is non-zero * @throws IllegalArgumentException if the set of edges is empty and the delay to distribute is non-zero, or if the
* delay is negative
*/ */
public static void distributeDelay(Collection<PlannedEdge> plannedEdges, int delay, SeededRandom rng) { public static void distributeDelay(Collection<PlannedEdge> plannedEdges, int delay, SeededRandom rng) {
......
...@@ -411,6 +411,59 @@ public class SchedulingUtils { ...@@ -411,6 +411,59 @@ public class SchedulingUtils {
nodeTimes.put(node, nodeSlot); nodeTimes.put(node, nodeSlot);
} }
/**
* Returns the minimum inner delay which a cycle containing backedges with the specified parameters can have without
* falling below the given MinII.
* <p>
* It is the lower bound of the RecMinII formula's ceiling function and can be retrieved like so:
* <pre>RecMinII = ceil((minInnerDelay + backedgeDelay) / backedgeDistance)</pre>
* It follows that
* <pre>(minInnerDelay + backedgeDelay) / backedgeDistance > RecMinII - 1</pre>
* and
* <pre>minInnerDelay > backedgeDistance * (RecMinII - 1) - backedgeDelay</pre><p>
* Because the inner delay is an integer value, the smallest possible value which still fulfills the inequality is
* the result of adding 1 to the right-hand side.
*
* @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not
* positive
*/
public static int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance) {
if (minII <= 0) {
throw new IllegalArgumentException("MinII must be positive.");
} else if (backedgeDelay < 0) {
throw new IllegalArgumentException("Backedge delay cannot be negative.");
} else if (backedgeDistance <= 0) {
throw new IllegalArgumentException("Backedge distance must be positive.");
}
return backedgeDistance * (minII - 1) - backedgeDelay + 1;
}
/**
* Returns the maximum inner delay which a cycle containing backedges with the specified parameters can have without
* exceeding the given MinII.
* <p>
* It can be derived from the RecMinII formula:
* <pre>RecMinII = ceil((maxInnerDelay + backedgeDelay) / backedgeDistance)</pre>
* It follows that
* <pre>RecMinII * backedgeDistance = maxInnerDelay + backedgeDelay</pre>
* and
* <pre>RecMinII * backedgeDistance - backedgeDelay = maxInnerDelay</pre>
*
* @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not
* positive
*/
public static int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) {
if (minII <= 0) {
throw new IllegalArgumentException("MinII must be positive.");
} else if (backedgeDelay < 0) {
throw new IllegalArgumentException("Backedge delay cannot be negative.");
} else if (backedgeDistance <= 0) {
throw new IllegalArgumentException("Backedge distance must be positive.");
}
return backedgeDistance * minII - backedgeDelay;
}
/** /**
* Transforms the provided graph into the given formulation. * Transforms the provided graph into the given formulation.
* *
......
...@@ -861,4 +861,32 @@ public class SchedulingUtilsTest { ...@@ -861,4 +861,32 @@ public class SchedulingUtilsTest {
); );
} }
@Test
public void testInnerDelays() {
int minII = 5;
int backedgeDelay = 1;
int backedgeDistance = 1;
int minInnerDelay = SchedulingUtils.getMinInnerDelay(minII, backedgeDelay, backedgeDistance);
int maxInnerDelay = SchedulingUtils.getMaxInnerDelay(minII, backedgeDelay, backedgeDistance);
assertEquals(4, minInnerDelay);
assertEquals(4, maxInnerDelay);
backedgeDistance = 2;
minInnerDelay = SchedulingUtils.getMinInnerDelay(minII, backedgeDelay, backedgeDistance);
maxInnerDelay = SchedulingUtils.getMaxInnerDelay(minII, backedgeDelay, backedgeDistance);
assertEquals(8, minInnerDelay);
assertEquals(9, maxInnerDelay);
minII = 50;
backedgeDelay = 10;
backedgeDistance = 5;
minInnerDelay = SchedulingUtils.getMinInnerDelay(minII, backedgeDelay, backedgeDistance);
maxInnerDelay = SchedulingUtils.getMaxInnerDelay(minII, backedgeDelay, backedgeDistance);
assertEquals(236, minInnerDelay);
assertEquals(240, maxInnerDelay);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment