Loading src/main/java/graphgen/generator/components/properties/minII/infeasible/configuration/StartConfiguration.java→src/main/java/graphgen/generator/components/properties/minII/MinIICycleConfiguration.java +107 −0 Original line number Diff line number Diff line Loading @@ -15,43 +15,78 @@ * limitations under the License. */ package graphgen.generator.components.properties.minII.infeasible.configuration; package graphgen.generator.components.properties.minII; import graphgen.graph.LayerStructure; import graphgen.graph.Resource; import graphgen.graph.ResourceNode; import java.util.Map; import java.util.Objects; /** * The start configuration represents the very start of an infeasible cycle. It contains the cycle's problematic * resource. * The abstract base class of the configuration classes related to creating feasible or infeasible MinII-specific * cycles. It stores the graph's layer structure, the node table and the cycle's maximum inner delay. The maximum inner * delay must not be exceeded in order to ensure corresponding MinIIs or other cycle properties. * * @author Sebastian Vollbrecht */ public class StartConfiguration extends MinIICycleConfiguration { public abstract class MinIICycleConfiguration { private final Resource problematicResource; protected final LayerStructure layers; protected final Map<Integer, ResourceNode> nodeTable; /** * Creates a new start configuration based on the provided arguments. * The cycle's maximum inner delay which must not be exceeded in order to ensure its corresponding MinII (or other * cycle properties). */ protected final int maxInnerDelay; /** * Creates a new configuration based on the provided arguments. * * @param layers the graph's layer structure * @param nodeTable the graph's node table * @param destinationNode the cycle's destination node * @param destinationNodeLayer the destination node's layer * @param maxInnerDelay the cycle's maximum inner delay * @param problematicResource the cycle's problematic resource */ public StartConfiguration(LayerStructure layers, Map<Integer, ResourceNode> nodeTable, ResourceNode destinationNode, int destinationNodeLayer, int maxInnerDelay, Resource problematicResource) { super(layers, nodeTable, destinationNode, destinationNodeLayer, maxInnerDelay); this.problematicResource = Objects.requireNonNull(problematicResource); protected MinIICycleConfiguration(LayerStructure layers, Map<Integer, ResourceNode> nodeTable, int maxInnerDelay) { this.layers = Objects.requireNonNull(layers); this.nodeTable = Objects.requireNonNull(nodeTable); if (maxInnerDelay < 0) { throw new IllegalArgumentException("The maximum inner delay cannot be negative."); } this.maxInnerDelay = maxInnerDelay; } public Resource getProblematicResource() { return problematicResource; protected MinIICycleConfiguration(MinIICycleConfiguration other) { this(other.layers, other.nodeTable, other.maxInnerDelay); } /** * Returns the graph's layer structure. * * @return the layer structure */ public LayerStructure getLayers() { return layers; } /** * Returns the graph's mapping of node IDs to nodes. * * @return the node table */ public Map<Integer, ResourceNode> getNodeTable() { return nodeTable; } /** * Returns the cycle's inner delay. * * @return the cycle's inner delay */ public int getMaxInnerDelay() { return maxInnerDelay; } @Override Loading @@ -60,14 +95,13 @@ public class StartConfiguration extends MinIICycleConfiguration { return true; if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; StartConfiguration that = (StartConfiguration) o; return Objects.equals(problematicResource, that.problematicResource); MinIICycleConfiguration that = (MinIICycleConfiguration) o; return maxInnerDelay == that.maxInnerDelay && Objects.equals(layers, that.layers) && Objects .equals(nodeTable, that.nodeTable); } @Override public int hashCode() { return Objects.hash(super.hashCode(), problematicResource); return Objects.hash(layers, nodeTable, maxInnerDelay); } } src/main/java/graphgen/generator/components/properties/minII/MinIICycleEdgePlanner.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * Copyright 2018 Sebastian Vollbrecht, Julian Oppermann * Embedded Systems and Applications Group, TU Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package graphgen.generator.components.properties.minII; import graphgen.datastructures.Pair; import graphgen.datastructures.SeededRandom; import graphgen.generator.components.properties.minII.util.PlannedEdge; import graphgen.graph.ResourceNode; import graphgen.util.JavaUtils; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Set; /** * This is the abstract base class of classes which deal with interconnecting nodes in MinII-specific cycles. Besides * some small utility methods, it provides methods for determining needed edges (in terms of source-destination pairs) * and for distributing individual amounts of delay over sets of planned edges. For these purposes it also stores the * generator's {@link SeededRandom} instance. * * @author Sebastian Vollbrecht */ public abstract class MinIICycleEdgePlanner { protected final SeededRandom rng; protected MinIICycleEdgePlanner(SeededRandom rng) { this.rng = Objects.requireNonNull(rng); } /** * Computes source-destination node pairs for every destination node which needs an incoming edge. * * @return the source-destination node pairs */ protected abstract Set<Pair<ResourceNode, ResourceNode>> getIncomingEdgePairs(); /** * Distributes some internally computed delay over the provided set of edges. * * @param edges the set of edges to distribute the delay over */ protected abstract void distributeDelay(Set<PlannedEdge> edges); /** * Distributes an amount of delay uniformly (for delays approaching infinity) over a collection of planned edges. * * @param plannedEdges the collection of planned edges * @param delay the delay to distribute * @param rng the {@link SeededRandom} instance to use * @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, or if the * delay is negative */ protected static void uniformlyDistributeDelay(Collection<PlannedEdge> plannedEdges, int delay, SeededRandom rng) { if (plannedEdges.isEmpty() && delay > 0) { throw new IllegalArgumentException("Cannot distribute delay of " + delay + " over non-existent edges."); } else if (delay < 0) { throw new IllegalArgumentException("The delay cannot be negative."); } while (delay > 0) { JavaUtils.pickRandomElement(plannedEdges, rng).delay++; delay--; } } /** * Maps nodes to their incoming edge, based on the provided set of edges. The set containing the relevant nodes is * used to determine which nodes to include in the returned map. * * @param edges the set of edges * @param relevantNodes the nodes to consider * @return a mapping of relevant nodes to their incoming edge * @throws IllegalArgumentException if any of the relevant nodes has more than one incoming edge or none at all */ protected static Map<ResourceNode, PlannedEdge> getIncomingEdgesMap(Set<PlannedEdge> edges, Collection<ResourceNode> relevantNodes) { Map<ResourceNode, PlannedEdge> incomingEdgesByNode = new HashMap<>(); for (PlannedEdge edge : Objects.requireNonNull(edges)) { if (Objects.requireNonNull(relevantNodes).contains(edge.src) && relevantNodes.contains(edge.dst)) { if (incomingEdgesByNode.containsKey(edge.dst)) { throw new IllegalArgumentException("Node " + edge.dst + " must have exactly one incoming edge."); } incomingEdgesByNode.put(edge.dst, edge); } } return incomingEdgesByNode; } /** * Maps nodes to their outgoing edge, based on the provided set of edges. The set containing the relevant nodes is * used to determine which nodes to include in the returned map. * * @param edges the set of edges * @param relevantNodes the nodes to consider * @return a mapping of relevant nodes to their outgoing edge * @throws IllegalArgumentException if any of the relevant nodes has more than one outgoing edge or none at all */ protected static Map<ResourceNode, PlannedEdge> getOutgoingEdgesMap(Set<PlannedEdge> edges, Collection<ResourceNode> relevantNodes) { Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = new HashMap<>(); for (PlannedEdge edge : Objects.requireNonNull(edges)) { if (Objects.requireNonNull(relevantNodes).contains(edge.src) && relevantNodes.contains(edge.dst)) { if (outgoingEdgesByNode.containsKey(edge.src)) { throw new IllegalArgumentException("Node " + edge.src + " must have exactly one outgoing edge."); } outgoingEdgesByNode.put(edge.src, edge); } } return outgoingEdgesByNode; } } src/main/java/graphgen/generator/components/properties/minII/MinIICycleInspector.java +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public abstract class MinIICycleInspector { * @param backedgeDistance the distance of the backedge(s) which will <i>close</i> the cycle * @return the cycle's minimum inner delay adhering to the above-mentioned requirements */ public abstract int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance); protected abstract int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance); /** * Returns the maximum inner delay which a cycle induced by the given arguments can have. The implementing classes Loading @@ -62,7 +62,7 @@ public abstract class MinIICycleInspector { * @param backedgeDistance the distance of the backedge(s) which will <i>close</i> the cycle * @return the cycle's maximum inner delay adhering to the above-mentioned requirements */ public abstract int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance); protected abstract int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance); /** * Returns the minimum inner delay which a cycle containing backedges with the specified parameters can have without Loading @@ -80,7 +80,7 @@ public abstract class MinIICycleInspector { * @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not * positive */ public static int minInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected static int minInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { if (minII <= 0) { throw new IllegalArgumentException("MinII must be positive."); } else if (backedgeDelay < 0) { Loading @@ -105,7 +105,7 @@ public abstract class MinIICycleInspector { * @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not * positive */ public static int maxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected static int maxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { if (minII <= 0) { throw new IllegalArgumentException("MinII must be positive."); } else if (backedgeDelay < 0) { Loading src/main/java/graphgen/generator/components/properties/minII/MinIICycleNodePlacer.java 0 → 100644 +51 −0 Original line number Diff line number Diff line /* * Copyright 2018 Sebastian Vollbrecht, Julian Oppermann * Embedded Systems and Applications Group, TU Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package graphgen.generator.components.properties.minII; import graphgen.datastructures.SeededRandom; import graphgen.graph.ResourceNode; import java.util.Objects; import java.util.Set; /** * This is the abstract base class of classes which deal with arranging nodes in MinII-specific cycles. It provides a * single abstract method for placing nodes in certain target layers. It also stores the generator's {@link * SeededRandom} instance. This way, the implementing classes can choose the target layer randomly (or other things * which might be needed). * * @author Sebastian Vollbrecht */ public abstract class MinIICycleNodePlacer { protected final SeededRandom rng; protected MinIICycleNodePlacer(SeededRandom rng) { this.rng = Objects.requireNonNull(rng); } /** * Places the specified node in one of the possible provided target layers. Depending on the property, this method * might introduce further changes to the graph (e.g. moving other nodes around). * * @param node the node to place in any of the layers * @param targetLayers the layers the node can be placed in */ protected abstract void placeNode(ResourceNode node, Set<Integer> targetLayers); } src/main/java/graphgen/generator/components/properties/minII/feasible/FeasibleCycleInspector.java +23 −23 Original line number Diff line number Diff line Loading @@ -33,36 +33,36 @@ import java.util.Set; * * @author Sebastian Vollbrecht */ public class FeasibleCycleInspector extends MinIICycleInspector { class FeasibleCycleInspector extends MinIICycleInspector { public FeasibleCycleInspector(LayerStructure layers, Set<ResourceNode> nodes) { FeasibleCycleInspector(LayerStructure layers, Set<ResourceNode> nodes) { super(layers, nodes); } @Override public int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { return minInnerDelay(minII, backedgeDelay, backedgeDistance); } @Override public int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { return maxInnerDelay(minII, backedgeDelay, backedgeDistance); } /** * Computes all destination nodes that could potentially be the destination node for the backedges of a feasible * cycle.<p>A node can only be considered destination node if at least one other node exists which can be appended * to the destination node without exceeding the specified inner delay.<p>In case of a two-element cycle consisting * of these two nodes only, it is furthermore important to filter out nodes which might result in an * <i>infeasible</i> cycle if connected to the destination node. For example, if both nodes shared the same * Computes all initial nodes of a feasible cycle.<p>A node can only be considered initial node if at least one * other node exists which can be appended to the initial node without exceeding the specified inner delay.<p>In * case of a two-element cycle consisting of these two nodes only, it is furthermore important to filter out nodes * which might result in an * <i>infeasible</i> cycle if connected to the initial node. For example, if both nodes shared the same * resource with delay 0 and a limit of 1, an edge with delay 0 would render their induced cycle infeasible. * * @param innerDelay the feasible cycle's inner delay * @return a set containing all potential destination node candidates * @return a set containing all potential initial node candidates */ public Set<ResourceNode> getPossibleDstNodes(int innerDelay) { Set<ResourceNode> getPossibleInitialNodes(int innerDelay) { Set<ResourceNode> possibleDstNodes = new HashSet<>(); Set<ResourceNode> possibleInitialNodes = new HashSet<>(); Map<Integer, Set<ResourceNode>> nodesByDelay = new HashMap<>(); for (ResourceNode node : nodes) { Loading @@ -78,9 +78,9 @@ public class FeasibleCycleInspector extends MinIICycleInspector { continue; } for (ResourceNode dstNode : firstEntry.getValue()) { for (ResourceNode initialNode : firstEntry.getValue()) { if (possibleDstNodes.contains(dstNode)) { if (possibleInitialNodes.contains(initialNode)) { continue; } Loading @@ -97,22 +97,22 @@ public class FeasibleCycleInspector extends MinIICycleInspector { for (ResourceNode otherNode : secondEntry.getValue()) { if (dstNode == otherNode) { if (initialNode == otherNode) { continue; } /* * Infeasibility check. */ if (dstNode.resource == otherNode.resource) { if (dstNode.resource.delay == 0 && dstNode.resource.limit == 1) { if (initialNode.resource == otherNode.resource) { if (initialNode.resource.delay == 0 && initialNode.resource.limit == 1) { /* * If there is no inner delay remaining if these two nodes were used, * they would need to be connected with an edge with delay 0, thus * rendering the cycle infeasible. */ if (innerDelay - (2 * dstNode.resource.delay) == 0) { if (innerDelay - (2 * initialNode.resource.delay) == 0) { continue; } } Loading @@ -120,11 +120,11 @@ public class FeasibleCycleInspector extends MinIICycleInspector { /* * If the first node can be the destination node, the second one can automatically * be the destination node as well (skipping them in the next iteration speeds up * the calculation). * be the destination node as well (by skipping them in the next iteration we can * slightly speed up the calculation). */ possibleDstNodes.add(dstNode); possibleDstNodes.add(otherNode); possibleInitialNodes.add(initialNode); possibleInitialNodes.add(otherNode); break; } Loading @@ -132,7 +132,7 @@ public class FeasibleCycleInspector extends MinIICycleInspector { } } return possibleDstNodes; return possibleInitialNodes; } Loading Loading
src/main/java/graphgen/generator/components/properties/minII/infeasible/configuration/StartConfiguration.java→src/main/java/graphgen/generator/components/properties/minII/MinIICycleConfiguration.java +107 −0 Original line number Diff line number Diff line Loading @@ -15,43 +15,78 @@ * limitations under the License. */ package graphgen.generator.components.properties.minII.infeasible.configuration; package graphgen.generator.components.properties.minII; import graphgen.graph.LayerStructure; import graphgen.graph.Resource; import graphgen.graph.ResourceNode; import java.util.Map; import java.util.Objects; /** * The start configuration represents the very start of an infeasible cycle. It contains the cycle's problematic * resource. * The abstract base class of the configuration classes related to creating feasible or infeasible MinII-specific * cycles. It stores the graph's layer structure, the node table and the cycle's maximum inner delay. The maximum inner * delay must not be exceeded in order to ensure corresponding MinIIs or other cycle properties. * * @author Sebastian Vollbrecht */ public class StartConfiguration extends MinIICycleConfiguration { public abstract class MinIICycleConfiguration { private final Resource problematicResource; protected final LayerStructure layers; protected final Map<Integer, ResourceNode> nodeTable; /** * Creates a new start configuration based on the provided arguments. * The cycle's maximum inner delay which must not be exceeded in order to ensure its corresponding MinII (or other * cycle properties). */ protected final int maxInnerDelay; /** * Creates a new configuration based on the provided arguments. * * @param layers the graph's layer structure * @param nodeTable the graph's node table * @param destinationNode the cycle's destination node * @param destinationNodeLayer the destination node's layer * @param maxInnerDelay the cycle's maximum inner delay * @param problematicResource the cycle's problematic resource */ public StartConfiguration(LayerStructure layers, Map<Integer, ResourceNode> nodeTable, ResourceNode destinationNode, int destinationNodeLayer, int maxInnerDelay, Resource problematicResource) { super(layers, nodeTable, destinationNode, destinationNodeLayer, maxInnerDelay); this.problematicResource = Objects.requireNonNull(problematicResource); protected MinIICycleConfiguration(LayerStructure layers, Map<Integer, ResourceNode> nodeTable, int maxInnerDelay) { this.layers = Objects.requireNonNull(layers); this.nodeTable = Objects.requireNonNull(nodeTable); if (maxInnerDelay < 0) { throw new IllegalArgumentException("The maximum inner delay cannot be negative."); } this.maxInnerDelay = maxInnerDelay; } public Resource getProblematicResource() { return problematicResource; protected MinIICycleConfiguration(MinIICycleConfiguration other) { this(other.layers, other.nodeTable, other.maxInnerDelay); } /** * Returns the graph's layer structure. * * @return the layer structure */ public LayerStructure getLayers() { return layers; } /** * Returns the graph's mapping of node IDs to nodes. * * @return the node table */ public Map<Integer, ResourceNode> getNodeTable() { return nodeTable; } /** * Returns the cycle's inner delay. * * @return the cycle's inner delay */ public int getMaxInnerDelay() { return maxInnerDelay; } @Override Loading @@ -60,14 +95,13 @@ public class StartConfiguration extends MinIICycleConfiguration { return true; if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; StartConfiguration that = (StartConfiguration) o; return Objects.equals(problematicResource, that.problematicResource); MinIICycleConfiguration that = (MinIICycleConfiguration) o; return maxInnerDelay == that.maxInnerDelay && Objects.equals(layers, that.layers) && Objects .equals(nodeTable, that.nodeTable); } @Override public int hashCode() { return Objects.hash(super.hashCode(), problematicResource); return Objects.hash(layers, nodeTable, maxInnerDelay); } }
src/main/java/graphgen/generator/components/properties/minII/MinIICycleEdgePlanner.java 0 → 100644 +140 −0 Original line number Diff line number Diff line /* * Copyright 2018 Sebastian Vollbrecht, Julian Oppermann * Embedded Systems and Applications Group, TU Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package graphgen.generator.components.properties.minII; import graphgen.datastructures.Pair; import graphgen.datastructures.SeededRandom; import graphgen.generator.components.properties.minII.util.PlannedEdge; import graphgen.graph.ResourceNode; import graphgen.util.JavaUtils; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Set; /** * This is the abstract base class of classes which deal with interconnecting nodes in MinII-specific cycles. Besides * some small utility methods, it provides methods for determining needed edges (in terms of source-destination pairs) * and for distributing individual amounts of delay over sets of planned edges. For these purposes it also stores the * generator's {@link SeededRandom} instance. * * @author Sebastian Vollbrecht */ public abstract class MinIICycleEdgePlanner { protected final SeededRandom rng; protected MinIICycleEdgePlanner(SeededRandom rng) { this.rng = Objects.requireNonNull(rng); } /** * Computes source-destination node pairs for every destination node which needs an incoming edge. * * @return the source-destination node pairs */ protected abstract Set<Pair<ResourceNode, ResourceNode>> getIncomingEdgePairs(); /** * Distributes some internally computed delay over the provided set of edges. * * @param edges the set of edges to distribute the delay over */ protected abstract void distributeDelay(Set<PlannedEdge> edges); /** * Distributes an amount of delay uniformly (for delays approaching infinity) over a collection of planned edges. * * @param plannedEdges the collection of planned edges * @param delay the delay to distribute * @param rng the {@link SeededRandom} instance to use * @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, or if the * delay is negative */ protected static void uniformlyDistributeDelay(Collection<PlannedEdge> plannedEdges, int delay, SeededRandom rng) { if (plannedEdges.isEmpty() && delay > 0) { throw new IllegalArgumentException("Cannot distribute delay of " + delay + " over non-existent edges."); } else if (delay < 0) { throw new IllegalArgumentException("The delay cannot be negative."); } while (delay > 0) { JavaUtils.pickRandomElement(plannedEdges, rng).delay++; delay--; } } /** * Maps nodes to their incoming edge, based on the provided set of edges. The set containing the relevant nodes is * used to determine which nodes to include in the returned map. * * @param edges the set of edges * @param relevantNodes the nodes to consider * @return a mapping of relevant nodes to their incoming edge * @throws IllegalArgumentException if any of the relevant nodes has more than one incoming edge or none at all */ protected static Map<ResourceNode, PlannedEdge> getIncomingEdgesMap(Set<PlannedEdge> edges, Collection<ResourceNode> relevantNodes) { Map<ResourceNode, PlannedEdge> incomingEdgesByNode = new HashMap<>(); for (PlannedEdge edge : Objects.requireNonNull(edges)) { if (Objects.requireNonNull(relevantNodes).contains(edge.src) && relevantNodes.contains(edge.dst)) { if (incomingEdgesByNode.containsKey(edge.dst)) { throw new IllegalArgumentException("Node " + edge.dst + " must have exactly one incoming edge."); } incomingEdgesByNode.put(edge.dst, edge); } } return incomingEdgesByNode; } /** * Maps nodes to their outgoing edge, based on the provided set of edges. The set containing the relevant nodes is * used to determine which nodes to include in the returned map. * * @param edges the set of edges * @param relevantNodes the nodes to consider * @return a mapping of relevant nodes to their outgoing edge * @throws IllegalArgumentException if any of the relevant nodes has more than one outgoing edge or none at all */ protected static Map<ResourceNode, PlannedEdge> getOutgoingEdgesMap(Set<PlannedEdge> edges, Collection<ResourceNode> relevantNodes) { Map<ResourceNode, PlannedEdge> outgoingEdgesByNode = new HashMap<>(); for (PlannedEdge edge : Objects.requireNonNull(edges)) { if (Objects.requireNonNull(relevantNodes).contains(edge.src) && relevantNodes.contains(edge.dst)) { if (outgoingEdgesByNode.containsKey(edge.src)) { throw new IllegalArgumentException("Node " + edge.src + " must have exactly one outgoing edge."); } outgoingEdgesByNode.put(edge.src, edge); } } return outgoingEdgesByNode; } }
src/main/java/graphgen/generator/components/properties/minII/MinIICycleInspector.java +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ public abstract class MinIICycleInspector { * @param backedgeDistance the distance of the backedge(s) which will <i>close</i> the cycle * @return the cycle's minimum inner delay adhering to the above-mentioned requirements */ public abstract int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance); protected abstract int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance); /** * Returns the maximum inner delay which a cycle induced by the given arguments can have. The implementing classes Loading @@ -62,7 +62,7 @@ public abstract class MinIICycleInspector { * @param backedgeDistance the distance of the backedge(s) which will <i>close</i> the cycle * @return the cycle's maximum inner delay adhering to the above-mentioned requirements */ public abstract int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance); protected abstract int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance); /** * Returns the minimum inner delay which a cycle containing backedges with the specified parameters can have without Loading @@ -80,7 +80,7 @@ public abstract class MinIICycleInspector { * @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not * positive */ public static int minInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected static int minInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { if (minII <= 0) { throw new IllegalArgumentException("MinII must be positive."); } else if (backedgeDelay < 0) { Loading @@ -105,7 +105,7 @@ public abstract class MinIICycleInspector { * @throws IllegalArgumentException if the MinII is not positive, if the delay is negative or if the distance is not * positive */ public static int maxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected static int maxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { if (minII <= 0) { throw new IllegalArgumentException("MinII must be positive."); } else if (backedgeDelay < 0) { Loading
src/main/java/graphgen/generator/components/properties/minII/MinIICycleNodePlacer.java 0 → 100644 +51 −0 Original line number Diff line number Diff line /* * Copyright 2018 Sebastian Vollbrecht, Julian Oppermann * Embedded Systems and Applications Group, TU Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package graphgen.generator.components.properties.minII; import graphgen.datastructures.SeededRandom; import graphgen.graph.ResourceNode; import java.util.Objects; import java.util.Set; /** * This is the abstract base class of classes which deal with arranging nodes in MinII-specific cycles. It provides a * single abstract method for placing nodes in certain target layers. It also stores the generator's {@link * SeededRandom} instance. This way, the implementing classes can choose the target layer randomly (or other things * which might be needed). * * @author Sebastian Vollbrecht */ public abstract class MinIICycleNodePlacer { protected final SeededRandom rng; protected MinIICycleNodePlacer(SeededRandom rng) { this.rng = Objects.requireNonNull(rng); } /** * Places the specified node in one of the possible provided target layers. Depending on the property, this method * might introduce further changes to the graph (e.g. moving other nodes around). * * @param node the node to place in any of the layers * @param targetLayers the layers the node can be placed in */ protected abstract void placeNode(ResourceNode node, Set<Integer> targetLayers); }
src/main/java/graphgen/generator/components/properties/minII/feasible/FeasibleCycleInspector.java +23 −23 Original line number Diff line number Diff line Loading @@ -33,36 +33,36 @@ import java.util.Set; * * @author Sebastian Vollbrecht */ public class FeasibleCycleInspector extends MinIICycleInspector { class FeasibleCycleInspector extends MinIICycleInspector { public FeasibleCycleInspector(LayerStructure layers, Set<ResourceNode> nodes) { FeasibleCycleInspector(LayerStructure layers, Set<ResourceNode> nodes) { super(layers, nodes); } @Override public int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected int getMinInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { return minInnerDelay(minII, backedgeDelay, backedgeDistance); } @Override public int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { protected int getMaxInnerDelay(int minII, int backedgeDelay, int backedgeDistance) { return maxInnerDelay(minII, backedgeDelay, backedgeDistance); } /** * Computes all destination nodes that could potentially be the destination node for the backedges of a feasible * cycle.<p>A node can only be considered destination node if at least one other node exists which can be appended * to the destination node without exceeding the specified inner delay.<p>In case of a two-element cycle consisting * of these two nodes only, it is furthermore important to filter out nodes which might result in an * <i>infeasible</i> cycle if connected to the destination node. For example, if both nodes shared the same * Computes all initial nodes of a feasible cycle.<p>A node can only be considered initial node if at least one * other node exists which can be appended to the initial node without exceeding the specified inner delay.<p>In * case of a two-element cycle consisting of these two nodes only, it is furthermore important to filter out nodes * which might result in an * <i>infeasible</i> cycle if connected to the initial node. For example, if both nodes shared the same * resource with delay 0 and a limit of 1, an edge with delay 0 would render their induced cycle infeasible. * * @param innerDelay the feasible cycle's inner delay * @return a set containing all potential destination node candidates * @return a set containing all potential initial node candidates */ public Set<ResourceNode> getPossibleDstNodes(int innerDelay) { Set<ResourceNode> getPossibleInitialNodes(int innerDelay) { Set<ResourceNode> possibleDstNodes = new HashSet<>(); Set<ResourceNode> possibleInitialNodes = new HashSet<>(); Map<Integer, Set<ResourceNode>> nodesByDelay = new HashMap<>(); for (ResourceNode node : nodes) { Loading @@ -78,9 +78,9 @@ public class FeasibleCycleInspector extends MinIICycleInspector { continue; } for (ResourceNode dstNode : firstEntry.getValue()) { for (ResourceNode initialNode : firstEntry.getValue()) { if (possibleDstNodes.contains(dstNode)) { if (possibleInitialNodes.contains(initialNode)) { continue; } Loading @@ -97,22 +97,22 @@ public class FeasibleCycleInspector extends MinIICycleInspector { for (ResourceNode otherNode : secondEntry.getValue()) { if (dstNode == otherNode) { if (initialNode == otherNode) { continue; } /* * Infeasibility check. */ if (dstNode.resource == otherNode.resource) { if (dstNode.resource.delay == 0 && dstNode.resource.limit == 1) { if (initialNode.resource == otherNode.resource) { if (initialNode.resource.delay == 0 && initialNode.resource.limit == 1) { /* * If there is no inner delay remaining if these two nodes were used, * they would need to be connected with an edge with delay 0, thus * rendering the cycle infeasible. */ if (innerDelay - (2 * dstNode.resource.delay) == 0) { if (innerDelay - (2 * initialNode.resource.delay) == 0) { continue; } } Loading @@ -120,11 +120,11 @@ public class FeasibleCycleInspector extends MinIICycleInspector { /* * If the first node can be the destination node, the second one can automatically * be the destination node as well (skipping them in the next iteration speeds up * the calculation). * be the destination node as well (by skipping them in the next iteration we can * slightly speed up the calculation). */ possibleDstNodes.add(dstNode); possibleDstNodes.add(otherNode); possibleInitialNodes.add(initialNode); possibleInitialNodes.add(otherNode); break; } Loading @@ -132,7 +132,7 @@ public class FeasibleCycleInspector extends MinIICycleInspector { } } return possibleDstNodes; return possibleInitialNodes; } Loading