Commit 14582279 authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht

Fixed some minor bugs.

- fixed faulty generator log output: certain graphs caused the 'creating edge x of y'-messages to contain wrong x/y values
- fixed a test case
parent fc62c362
......@@ -213,9 +213,6 @@ public final class GraphGenerator {
nodes.forEach(n -> nodeTable.put(n.getId(), n));
Map<ResourceNode, Integer> asapTimes = new HashMap<>();
nodes.forEach(n -> asapTimes.put(n, -1));
asapTimes.put(SOURCE, -1);
asapTimes.put(SINK, -1);
edgeCreator.setASAPTimesMap(asapTimes);
edgeIncluder.setASAPTimesMap(asapTimes);
......@@ -223,15 +220,17 @@ public final class GraphGenerator {
property.generateProperty(layers, Collections.unmodifiableSet(nodes), nodeTable, edgeCreator);
nodes.add(SOURCE);
nodes.add(SINK);
if (verbose) {
out.println("\tLayer structure post property generation: " + layers.toString());
out.println("\tGenerated edges post property generation: " + edgeCreator.edgeView());
out.println("\tGenerating incoming edges.");
}
nodes.add(SOURCE);
nodes.add(SINK);
nodes.forEach(n -> asapTimes.put(n, -1));
generateIncomingEdges(layers, nodes, nodeTable, asapTimes, seed);
if (verbose) {
......@@ -568,13 +567,21 @@ public final class GraphGenerator {
private void generateOptionalEdges(LayerStructure layers, Set<ResourceNode> nodes,
Map<Integer, ResourceNode> nodeTable, Map<ResourceNode, Integer> asapTimes) {
long maxEdgeCount = verbose ? GraphUtils.getMaxPossibleEdgeNumber(layers) : 0;
long currentEdgeCount = verbose ? edgeCreator.edgeView().stream().filter(e -> !e.isBackedge()).count() : 0;
long maxEdgeCount = getMaxPossibleEdgeNumber(layers);
long currentEdgeCount = 0;
for (Edge<ResourceNode> edge : edgeCreator.edgeView()) {
if (edge.isBackedge() || edge.getSrc() == SOURCE || edge.getDst() == SINK) {
continue;
}
currentEdgeCount++;
}
for (ResourceNode src : JavaUtils.asShuffledList(nodes, rng)) {
if (src == SOURCE || src == SINK)
if (src == SOURCE || src == SINK) {
continue;
}
int srcLayer = layers.getDepth(src);
......@@ -586,12 +593,14 @@ public final class GraphGenerator {
for (ResourceNode dst : JavaUtils.asShuffledList(dstNodes, rng)) {
/*
* Check if the edge is a valid edge. An edge is not valid if an edge exists
* already between the two nodes.
*/
if (!edgeCreator.isEdgeValid(src, dst))
if (!edgeCreator.isEdgeValid(src, dst)) {
continue;
}
int delay = edgeCreator.computeEdgeDelay(src, dst);
......@@ -633,36 +642,37 @@ public final class GraphGenerator {
Map<Integer, Set<ResourceNode>> asapSlots = JavaUtils.invertMap(asapTimes);
long maxBackedgeCount = GraphUtils.getMaxPossibleBackedgeNumber(asapSlots);
long maxBackedgeCount = getMaxPossibleBackedgeNumber(asapSlots);
long currentBackedgeCount = edgeCreator.edgeView().stream().filter(Edge::isBackedge).count();
int asapMax = Collections.max(asapSlots.keySet());
List<Integer> asapSlotsSorted = JavaUtils.asSortedList(asapSlots.keySet());
for (int i = asapMax; i >= 0; i--) {
for (int i = 0; i < asapSlotsSorted.size(); i++) {
if (!asapSlots.containsKey(i))
continue;
int srcSlot = asapSlotsSorted.get(i);
// For every node in the current ASAP slot...
for (ResourceNode src : JavaUtils.asShuffledList(asapSlots.get(i), rng)) {
for (ResourceNode src : JavaUtils.asShuffledList(asapSlots.get(srcSlot), rng)) {
if (src == SOURCE || src == SINK)
if (src == SOURCE || src == SINK) {
continue;
}
// .. iterate through all possible ASAP slots...
for (int j = i; j >= 0; j--) {
for (int j = 0; j <= i; j++) {
if (!asapSlots.containsKey(j))
continue;
int dstSlot = asapSlotsSorted.get(j);
// ... and their nodes.
for (ResourceNode dst : JavaUtils.asShuffledList(asapSlots.get(j), rng)) {
for (ResourceNode dst : JavaUtils.asShuffledList(asapSlots.get(dstSlot), rng)) {
if (dst == SOURCE || dst == SINK || src == dst)
if (dst == SOURCE || dst == SINK) {
continue;
}
if (!edgeCreator.isBackedgeValid(src, dst))
if (!edgeCreator.isBackedgeValid(src, dst)) {
continue;
}
int delay = edgeCreator.computeBackedgeDelay(src, dst);
int distance = edgeCreator.computeBackedgeDistance(src, dst);
......@@ -696,7 +706,6 @@ public final class GraphGenerator {
}
}
}
}
/**
......@@ -763,6 +772,79 @@ public final class GraphGenerator {
return JavaUtils.asSet(ids.stream().map(nodeTable::get));
}
/**
* Computes the maximum possible number of edges using the provided layer structure.
*
* @param layers the layer structure
* @return the maximum possible number of edges
*/
private static int getMaxPossibleEdgeNumber(LayerStructure layers) {
int maxAmount = 0;
for (int srcLayer = 0; srcLayer < layers.getHeight() - 1; srcLayer++) {
int srcLayerSize = layers.getLayer(srcLayer).size();
int possibleConnections = 0;
for (int dstLayer = srcLayer + 1; dstLayer < layers.getHeight(); dstLayer++) {
possibleConnections += layers.getLayer(dstLayer).size();
}
maxAmount += srcLayerSize * possibleConnections;
}
return maxAmount;
}
/**
* Computes the maximum possible number of backedges using the provided map of ASAP slots.
*
* @param asapSlots the ASAP slots
* @return the maximum possible number of backedges
*/
private static int getMaxPossibleBackedgeNumber(Map<Integer, Set<ResourceNode>> asapSlots) {
int maxAmount = 0;
for (int srcSlot : asapSlots.keySet()) {
int srcSlotSize = asapSlots.get(srcSlot).size();
if (asapSlots.get(srcSlot).contains(SOURCE)) {
srcSlotSize--;
}
if (asapSlots.get(srcSlot).contains(SINK)) {
srcSlotSize--;
}
int possibleConnections = 0;
for (int dstSlot : asapSlots.keySet()) {
if (dstSlot <= srcSlot) {
int dstSlotSize = asapSlots.get(dstSlot).size();
if (asapSlots.get(dstSlot).contains(SOURCE)) {
dstSlotSize--;
}
if (asapSlots.get(dstSlot).contains(SINK)) {
dstSlotSize--;
}
// Take src == dst into account.
if (srcSlot == dstSlot) {
dstSlotSize--;
}
possibleConnections += dstSlotSize;
}
}
maxAmount += srcSlotSize * possibleConnections;
}
return maxAmount;
}
/**
* This class is the default property class, used by the {@link GraphGenerator} if no specific property is supplied.
* It never changes a graph and never returns false on an edge validity check.
......
......@@ -61,6 +61,7 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
private final Map<ResourceNode, Set<Edge<ResourceNode>>> incomingBackedges;
private LayerStructure layers;
private Map<ResourceNode, Integer> asapTimes;
private boolean strict;
/**
......@@ -95,8 +96,8 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
* @param dst the edge's destination node
* @param delay the edge's delay
* @return the created edge
* @throws IllegalEdgeException if the delay is less than 0 or if the source and destination nodes are connected
* through a forward edge already
* @throws IllegalEdgeException if the delay is less than 0 or if the edge is {@link #isEdgeValid(ResourceNode,
* ResourceNode) invalid}
* @throws StrictModeException if the edge creator is in strict mode and any of the preventive measures specified
* in the {@link #setStrict(boolean)}-method isn't met
*/
......@@ -140,8 +141,8 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
* @param delay the backedge's delay
* @param distance the backedge's distance
* @return the created backedge
* @throws IllegalEdgeException if the delay is less than 0, if the distance is not greater than 0 or if the source
* and destination nodes are connected through a backedge already
* @throws IllegalEdgeException if the delay is less than 0, if the distance is not greater than 0 or if it is
* {@link #isBackedgeValid(ResourceNode, ResourceNode) invalid}
* @throws StrictModeException if the edge creator is in strict mode and any of the preventive measures specified
* in the {@link #setStrict(boolean)}-method isn't met
*/
......@@ -153,7 +154,7 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
if (distance <= 0)
throw new IllegalEdgeException(distance, true);
if (src != GraphGenerator.SOURCE && dst != GraphGenerator.SINK && !isBackedgeValid(src, dst))
if (!isBackedgeValid(src, dst))
throw new IllegalEdgeException(src, dst, true);
if (strict) {
......@@ -194,8 +195,8 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
* An edge is valid iff any of these two conditions is met:
* <ul>
* <li>the source node's depth is less than the destination node's depth</li>
* <li>the source or destination node (or both) are virtual source and sink
* nodes</li>
* <li>the source node is the virtual sink node or if the destination node is the virtual source
* node</li>
* </ul>
* and if there doesn't exist a forward edge connecting the two nodes already.
*
......@@ -205,6 +206,14 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
*/
public boolean isEdgeValid(ResourceNode src, ResourceNode dst) {
if (src == GraphGenerator.SINK) {
return false;
}
if (dst == GraphGenerator.SOURCE) {
return false;
}
if (src != GraphGenerator.SOURCE && dst != GraphGenerator.SINK) {
if (layers.getDepth(src) >= layers.getDepth(dst)) {
return false;
......@@ -224,13 +233,12 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
* Returns whether a backedge connecting the source and destination nodes would be valid. Note that this method does
* not use the internal {@link EdgeIncluder} to decide validity.
* <p>
* A backedge is valid iff any of these two conditions is met:
* A backedge is invalid iff any of these conditions is met:
* <ul>
* <li>the source and destination nodes are distinct</li>
* <li>the source or destination node (or both) are virtual source and sink
* nodes</li>
* <li>the source and destination nodes are not distinct</li>
* <li>the source node's ASAP time is less than the destination node's ASAP time</li>
* <li>there exists a backedge connecting these two nodes already</li>
* </ul>
* and if there doesn't exist a backedge connecting the two nodes already.
*
* @param src the edge's source node
* @param dst the edge's destination node
......@@ -238,8 +246,15 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
*/
public boolean isBackedgeValid(ResourceNode src, ResourceNode dst) {
if (src != GraphGenerator.SOURCE && dst != GraphGenerator.SINK && src == dst)
if (src == dst) {
return false;
}
if (asapTimes.containsKey(src) && asapTimes.containsKey(dst)) {
if (asapTimes.get(src) < asapTimes.get(dst)) {
return false;
}
}
outgoingBackedges.putIfAbsent(src, new HashSet<>());
outgoingBackedges.putIfAbsent(dst, new HashSet<>());
......@@ -296,6 +311,9 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
@Override
public void setASAPTimesMap(Map<ResourceNode, Integer> asapTimes) {
this.asapTimes = asapTimes;
edgeDelayComputer.setASAPTimesMap(asapTimes);
backedgeDelayComputer.setASAPTimesMap(asapTimes);
backedgeDistanceComputer.setASAPTimesMap(asapTimes);
......@@ -311,6 +329,9 @@ public class EdgeCreator extends Observable<Edge<ResourceNode>> implements EdgeC
@Override
public void reset() {
layers = null;
asapTimes = null;
edges.clear();
outgoingEdges.clear();
......
......@@ -1772,57 +1772,6 @@ public class GraphUtils {
}
}
/**
* Computes the maximum possible number of edges using the provided layer structure.
*
* @param layers the layer structure
* @return the maximum possible number of edges
*/
public static int getMaxPossibleEdgeNumber(LayerStructure layers) {
int maxAmount = 0;
for (int srcLayer = 0; srcLayer < layers.getHeight() - 1; srcLayer++) {
int srcLayerSize = layers.getLayer(srcLayer).size();
int possibleConnections = 0;
for (int dstLayer = srcLayer + 1; dstLayer < layers.getHeight(); dstLayer++) {
possibleConnections += layers.getLayer(dstLayer).size();
}
maxAmount += srcLayerSize * possibleConnections;
}
return maxAmount;
}
/**
* Computes the maximum possible number of backedges using the provided map of ASAP slots.
*
* @param <N> the node type
* @param asapSlots the ASAP slots
* @return the maximum possible number of backedges
*/
public static <N extends Node> int getMaxPossibleBackedgeNumber(Map<Integer, Set<N>> asapSlots) {
int maxAmount = 0;
for (int srcSlot : JavaUtils.asSortedList(asapSlots.keySet())) {
int srcSlotSize = asapSlots.get(srcSlot).size();
int possibleConnections = 0;
for (int dstSlot : JavaUtils.asSortedList(asapSlots.keySet())) {
if (dstSlot == srcSlot)
possibleConnections += asapSlots.get(dstSlot).size() - 1;
else
possibleConnections += asapSlots.get(dstSlot).size();
}
maxAmount += srcSlotSize * possibleConnections;
}
return maxAmount;
}
/**
* Constructs a graph from the given graph without the edges matching the specified edge type.
*
......
......@@ -39,7 +39,7 @@ public class LayerStructureTest {
int id = GraphGenerator.SINK.getId() + 1;
List<Integer> layer0 = Arrays.asList(id);
List<Integer> layer0 = Arrays.asList(id++);
List<Integer> layer1 = Arrays.asList(id++, id++, id++, id++, id++);
List<Integer> layer2 = Arrays.asList(id++, id++, id++, id++);
List<Integer> layer3 = Arrays.asList(id++, id++, id++);
......
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