Commit 89e2b3ee authored by Sebastian Vollbrecht's avatar Sebastian Vollbrecht
Browse files

JavaDoc fixes and changes regarding the way the generation process is logged.

Also some other minimal changes.
parent 152176dd
......@@ -64,32 +64,17 @@ public class Pair<T1, T2> {
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((first == null) ? 0 : first.hashCode());
result = prime * result + ((second == null) ? 0 : second.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
public boolean equals(Object o) {
if (this == o)
return true;
if (obj == null)
return false;
if (!(obj instanceof Pair))
if (o == null || getClass() != o.getClass())
return false;
Pair<?, ?> other = (Pair<?, ?>) obj;
if (first == null) {
if (other.first != null)
return false;
} else if (!first.equals(other.first))
return false;
if (second == null) {
return other.second == null;
} else
return second.equals(other.second);
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(first, pair.first) && Objects.equals(second, pair.second);
}
@Override
public int hashCode() {
return Objects.hash(first, second);
}
}
......@@ -84,6 +84,17 @@ public class SeededRandom {
return rng.nextDouble();
}
/**
* Returns a random long value.
*
* @return the random long value
* @throws UnsupportedOperationException if this instance has not yet been seeded
*/
public long nextLong() {
checkSeededStatus();
return rng.nextLong();
}
/**
* Returns the wrapped random instance.
*
......
......@@ -19,6 +19,7 @@ package graphgen.generator;
import graphgen.datastructures.Pair;
import graphgen.datastructures.SeededRandom;
import graphgen.enums.ResourceType;
import graphgen.generator.components.StrictComponent;
import graphgen.generator.components.edges.EdgeCreator;
import graphgen.generator.components.edges.includers.EdgeIncluder;
......@@ -36,6 +37,7 @@ import graphgen.util.GraphUtils;
import graphgen.util.JavaUtils;
import modsched.Edge;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
......@@ -84,7 +86,6 @@ public final class GraphGenerator implements StrictComponent {
private final SeededRandom rng;
private final EdgeInclusionDuplicateChecker edgeChecker;
private boolean verbose = false;
private PrintStream out = System.out;
/**
......@@ -165,9 +166,7 @@ public final class GraphGenerator implements StrictComponent {
*/
public Graph<ResourceNode> createGraph(long seed) {
if (verbose) {
out.println("Creating graph with seed " + seed);
}
out.println("Creating graph with seed " + seed);
// Reset and clear generation objects.
layerCreator.reset();
......@@ -186,9 +185,7 @@ public final class GraphGenerator implements StrictComponent {
GeneratedLayerStructure layers = layerCreator.createLayerStructure();
if (verbose) {
out.println("\tGenerated layer structure: " + layers.toString());
}
out.println("\tGenerated layer structure: " + layers.toString());
edgeCreator.addObserver(layers);
edgeCreator.addObserver(property);
......@@ -201,9 +198,17 @@ public final class GraphGenerator implements StrictComponent {
Set<ResourceNode> nodes = nodeCreator.createNodes(layers);
if (verbose) {
out.println("\tGenerated nodes: " + nodes.toString());
out.print("\tResources in use: [");
List<Resource> resourcesUsed = new ArrayList<>(GraphUtils.getResources(nodes, ResourceType.ALL));
for (int i = 0; i < resourcesUsed.size(); i++) {
if (i > 0) {
out.print(", ");
}
Resource r = resourcesUsed.get(i);
out.print(String.format("(%s, %d, %d)", r.name, r.delay, r.limit));
}
out.println("]");
out.println("\tGenerated nodes: " + nodes.toString());
Map<Integer, ResourceNode> nodeTable = new HashMap<>();
nodes.forEach(n -> nodeTable.put(n.getId(), n));
......@@ -218,11 +223,9 @@ public final class GraphGenerator implements StrictComponent {
edgeCreator
);
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.");
}
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);
......@@ -231,22 +234,16 @@ public final class GraphGenerator implements StrictComponent {
generateIncomingEdges(layers, nodes, nodeTable, asapTimes);
if (verbose) {
out.println("\tGenerating outgoing edges.");
}
out.println("\tGenerating outgoing edges.");
generateOutgoingEdges(layers, nodes, nodeTable, asapTimes);
if (verbose) {
out.println("\tGenerating optional edges.");
}
out.println("\tGenerating optional edges.");
generateOptionalEdges(layers, nodes, nodeTable, asapTimes);
verifyASAPTimesMap(edgeCreator.edgeView(), asapTimes);
if (verbose) {
out.println("\tGenerating remaining backedges.");
}
out.println("\tGenerating remaining backedges.");
generateBackedges(asapTimes);
......@@ -280,11 +277,11 @@ public final class GraphGenerator implements StrictComponent {
for (int i = 0; i < amount; i++) {
if (!graphs.add(createGraph(seed)) && verbose) {
out.println("Duplicate detected.");
if (!graphs.add(createGraph(seed))) {
out.println("Duplicate detected (seed: " + seed + ").");
}
seed = rng.getRandom().nextLong();
seed = rng.nextLong();
}
} else {
......@@ -298,11 +295,11 @@ public final class GraphGenerator implements StrictComponent {
if (!GraphUtils.isGraphIsomorphicToAny(graph, asapTimes, asapTimesMap))
graphs.add(graph);
else if (verbose) {
out.println("Isomorphism detected.");
else {
out.println("Isomorphism detected (seed: " + seed + ").");
}
seed = rng.getRandom().nextLong();
seed = rng.nextLong();
}
}
......@@ -321,25 +318,26 @@ public final class GraphGenerator implements StrictComponent {
}
/**
* Sets the generator to verbose mode, i.e. that the generation process will be written to the provided print
* stream.
* Toggles the generator's verbosity. If a print print stream is supplied, the generation process will be written to
* it. If <i>out</i> is null, the generation process won't be documented.
* <p>
* Use <code>new PrintStream(new FileOutputStream(new File(filename))</code> to immediately write to a file.<br>
* Use<p>{@code new PrintStream(new FileOutputStream(new File(filename))}<p>to immediately write to a file.<br>
* <b>Warning</b>: The resulting file might be excessively large due to the
* amount of edges possible in large graphs (O(2*V<sup>2</sup>)).
*
* @param out the print stream
*/
public void setVerbose(PrintStream out) {
verbose = true;
this.out = out;
}
/**
* Sets the generator to non-verbose mode, i.e. that the generation process won't be documented.
* @param out the print stream used to document the generation process or null to disable any generation output
*/
public void setNonVerbose() {
verbose = false;
public void setOut(PrintStream out) {
if (out == null) {
this.out = new PrintStream(new OutputStream() {
@Override
public void write(int b) {
// Do nothing.
}
});
} else {
this.out = out;
}
}
/**
......@@ -375,9 +373,7 @@ public final class GraphGenerator implements StrictComponent {
if (hasMandatoryIncomingEdge)
continue;
if (verbose) {
out.println("\t\tTrying to generate an incoming edge for node " + dst);
}
out.println("\t\tTrying to generate an incoming edge for node " + dst);
/*
* Store source candidates with edge delays whose corresponding edges are
......@@ -400,9 +396,7 @@ public final class GraphGenerator implements StrictComponent {
int delay = edgeCreator.computeEdgeDelay(src, dst);
if (verbose) {
out.print("\t\t\t" + src + "--" + delay + "-->" + dst + ": ");
}
out.print("\t\t\t" + src + "--" + delay + "-->" + dst + ": ");
if (isEdgePossible(src, dst, delay)) {
if (edgeIncluder.includeEdge(new Edge<>(src, dst, delay, 0))) {
......@@ -414,14 +408,11 @@ public final class GraphGenerator implements StrictComponent {
possibleCandidates.add(Pair.of(src, delay));
if (verbose) {
out.println("optimal.");
}
out.println("optimal.");
} else {
if (verbose) {
out.println("the edge includer denied the inclusion.");
}
out.println("the edge includer denied the inclusion.");
if (!optimalCandidatesFound) {
possibleCandidates.add(Pair.of(src, delay));
......@@ -435,9 +426,7 @@ public final class GraphGenerator implements StrictComponent {
int delay;
if (possibleCandidates.isEmpty()) {
if (verbose) {
out.println("\t\t\tChosen incoming edge: " + SOURCE + "--" + 0 + "-->" + dst + ": ");
}
out.println("\t\t\tChosen incoming edge: " + SOURCE + "--" + 0 + "-->" + dst + ": ");
src = SOURCE;
delay = 0;
} else {
......@@ -445,12 +434,10 @@ public final class GraphGenerator implements StrictComponent {
src = srcAndDelay.first;
delay = srcAndDelay.second;
if (verbose) {
if (optimalCandidatesFound)
out.println("\t\t\tChosen incoming edge (optimal): " + src + "--" + delay + "-->" + dst + ": ");
else
out.println(
"\t\t\tChosen incoming edge (not optimal): " + src + "--" + delay + "-->" + dst + ": ");
if (optimalCandidatesFound) {
out.println("\t\t\tChosen incoming edge (optimal): " + src + "--" + delay + "-->" + dst + ": ");
} else {
out.println("\t\t\tChosen incoming edge (not optimal): " + src + "--" + delay + "-->" + dst + ": ");
}
}
......@@ -470,9 +457,7 @@ public final class GraphGenerator implements StrictComponent {
if (!edgeCreator.outgoingEdgesOf(src).isEmpty() || src == SINK)
continue;
if (verbose) {
out.println("\t\tTrying to generate an outgoing edge for node " + src);
}
out.println("\t\tTrying to generate an outgoing edge for node " + src);
int srcDepth = layers.getDepth(src);
......@@ -495,9 +480,7 @@ public final class GraphGenerator implements StrictComponent {
int delay = edgeCreator.computeEdgeDelay(src, dst);
if (verbose) {
out.print("\t\t\t" + src + "--" + delay + "-->" + dst + ": ");
}
out.print("\t\t\t" + src + "--" + delay + "-->" + dst + ": ");
if (isEdgePossible(src, dst, delay)) {
if (edgeIncluder.includeEdge(new Edge<>(src, dst, delay, 0))) {
......@@ -509,13 +492,11 @@ public final class GraphGenerator implements StrictComponent {
possibleCandidates.add(Pair.of(dst, delay));
if (verbose) {
out.println("optimal.");
}
out.println("optimal.");
} else {
if (verbose) {
out.println("the edge includer denied the inclusion.");
}
out.println("the edge includer denied the inclusion.");
if (!optimalCandidatesFound) {
possibleCandidates.add(Pair.of(dst, delay));
......@@ -528,9 +509,7 @@ public final class GraphGenerator implements StrictComponent {
int delay;
if (possibleCandidates.isEmpty()) {
if (verbose) {
out.println("\t\t\tChosen incoming edge: " + src + "--" + 0 + "-->" + SINK + ": ");
}
out.println("\t\t\tChosen incoming edge: " + src + "--" + 0 + "-->" + SINK + ": ");
dst = SINK;
delay = 0;
} else {
......@@ -538,12 +517,10 @@ public final class GraphGenerator implements StrictComponent {
dst = dstAndDelay.first;
delay = dstAndDelay.second;
if (verbose) {
if (optimalCandidatesFound)
out.println("\t\t\tChosen outgoing edge (optimal): " + src + "--" + delay + "-->" + dst + ": ");
else
out.println(
"\t\t\tChosen outgoing edge (not optimal): " + src + "--" + delay + "-->" + dst + ": ");
if (optimalCandidatesFound) {
out.println("\t\t\tChosen outgoing edge (optimal): " + src + "--" + delay + "-->" + dst + ": ");
} else {
out.println("\t\t\tChosen outgoing edge (not optimal): " + src + "--" + delay + "-->" + dst + ": ");
}
}
......@@ -597,30 +574,22 @@ public final class GraphGenerator implements StrictComponent {
int delay = edgeCreator.computeEdgeDelay(src, dst);
if (verbose) {
out.print(
"\t\tChecking inclusion of edge " + ++currentEdgeCount + " of " + maxEdgeCount + ": " + src + "--" + delay + "-->" + dst + ": ");
}
out.print(
"\t\tChecking inclusion of edge " + ++currentEdgeCount + " of " + maxEdgeCount + ": " + src + "--" + delay + "-->" + dst + ": ");
if (!edgeIncluder.includeEdge(new Edge<>(src, dst, delay, 0))) {
if (verbose) {
out.println("the edge includer denied the inclusion.");
}
out.println("the edge includer denied the inclusion.");
continue;
}
if (edgeChecker.hasEdgeBeenDeniedAlready(src, dst, delay) || !property.isEdgeValid(src, dst, delay)) {
if (verbose) {
out.println("the property denied the inclusion.");
}
out.println("the property denied the inclusion.");
continue;
}
edgeCreator.createEdge(src, dst, delay);
if (verbose) {
out.println("OK.");
}
out.println("OK.");
int newDstTime = asapTimes.get(src) + src.getDelay() + delay;
......@@ -670,30 +639,22 @@ public final class GraphGenerator implements StrictComponent {
int delay = edgeCreator.computeBackedgeDelay(src, dst);
int distance = edgeCreator.computeBackedgeDistance(src, dst);
if (verbose) {
out.print(
"\t\tChecking inclusion of backedge " + ++currentBackedgeCount + " of " + maxBackedgeCount + ": " + src + "--(" + delay + ", " + distance + ")-->" + dst + ": ");
}
out.print(
"\t\tChecking inclusion of backedge " + ++currentBackedgeCount + " of " + maxBackedgeCount + ": " + src + "--(" + delay + ", " + distance + ")-->" + dst + ": ");
if (!backedgeIncluder.includeEdge(new Edge<>(src, dst, delay, distance))) {
if (verbose) {
out.println("the backedge includer denied the inclusion.");
}
out.println("the backedge includer denied the inclusion.");
continue;
}
if (!property.isBackedgeValid(src, dst, delay, distance)) {
if (verbose) {
out.println("the property denied the inclusion.");
}
out.println("the property denied the inclusion.");
continue;
}
edgeCreator.createBackedge(src, dst, delay, distance);
if (verbose) {
out.println("OK.");
}
out.println("OK.");
}
}
......@@ -736,23 +697,17 @@ public final class GraphGenerator implements StrictComponent {
private boolean isEdgePossible(ResourceNode src, ResourceNode dst, int delay) {
if (!edgeCreator.isEdgeValid(src, dst)) {
if (verbose) {
out.println("the nodes are connected already.");
}
out.println("the nodes are connected already.");
return false;
}
if (edgeChecker.hasEdgeBeenDeniedAlready(src, dst, delay)) {
if (verbose) {
out.println("the property denied the inclusion.");
}
out.println("the property denied the inclusion.");
return false;
}
if (!property.isEdgeValid(src, dst, delay)) {
if (verbose) {
out.println("the property denied the inclusion.");
}
out.println("the property denied the inclusion.");
edgeChecker.addEdgeDenial(src, dst, delay);
return false;
}
......
......@@ -105,6 +105,8 @@ public abstract class ValueComputer implements EdgeCreationComponent, StrictComp
/**
* Tells the value computer which value it is actually computing. This edge value is then used used to determine (in
* strict mode) whether or not a created edge is illegal.
*
* @param edgeValue the edge value whose computation this value computer is used for
*/
public final void setEdgeValue(EdgeValue edgeValue) {
this.edgeValue = edgeValue;
......
......@@ -57,7 +57,7 @@ public class GeneratedLayerStructure extends LayerStructure implements StrictCom
}
/**
* Swaps the two IDs with each other (see {@link LayerStructure#swapIDs(int, int)}).
* Swaps the two IDs with each other.
*
* @throws IllegalSwapException if an illegal swap is detected, i.e. if the IDs are connected with an edge during a
* graph creation phase and if the swap would violate the layer structure implied by
......
......@@ -176,12 +176,17 @@ public abstract class MinIIProperty<C extends MinIICycleConfiguration> extends 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>
* <pre>(minInnerDelay + backedgeDelay) / backedgeDistance &gt; RecMinII - 1</pre>
* and
* <pre>minInnerDelay > backedgeDistance * (RecMinII - 1) - backedgeDelay</pre><p>
* <pre>minInnerDelay &gt; 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.
*
* @param minII the MinII which needs to be ensured
* @param backedgeDelay the delay of possible RecMinII-ensuring backedges
* @param backedgeDistance the distance of possible RecMinII-ensuring backedges
* @return the minimum inner delay a cycle containing such RecMinII-ensuring backedges can have while still ensuring
* the specified MinII
* @throws IllegalArgumentException if the MinII is not greater than zero, if the delay is negative, if the distance
* is not greater than zero or if the backedge parameters already exceed the
* specified MinII
......@@ -202,6 +207,11 @@ public abstract class MinIIProperty<C extends MinIICycleConfiguration> extends P
* and
* <pre>RecMinII * backedgeDistance - backedgeDelay = maxInnerDelay</pre>
*
* @param minII the MinII which needs to be ensured
* @param backedgeDelay the delay of possible RecMinII-ensuring backedges
* @param backedgeDistance the distance of possible RecMinII-ensuring backedges
* @return the maximum inner delay a cycle containing such RecMinII-ensuring backedges can have while still ensuring
* the specified MinII
* @throws IllegalArgumentException if the MinII is not greater than zero, if the delay is negative, if the distance
* is not greater than zero or if the backedge parameters already exceed the
* specified MinII
......
......@@ -154,7 +154,6 @@ public class InfeasibleMinIIProperty extends MinIIProperty<InfeasibleConfigurati
ResourceNode dstNode;
/* Immediately choose a destination node to avoid listing all possibilities (see method doc). */
if (!nodesInCurrentLayer.isEmpty()) {
dstNode = JavaUtils.pickRandomElement(nodesInCurrentLayer, rng);
} else {
......
......@@ -52,6 +52,8 @@ public class LookupTables {
case BACKEDGE_DISTANCE:
probabilityMapping.put(1, 1.0);
break;
default:
throw new UnsupportedOperationException(edgeValue.toString());
}
return new DeterministicDistribution<>(probabilityMapping);
......
......@@ -54,15 +54,11 @@ public class GraphFileUtils {
/**
* Sanitizes a name so that it can be used as a filename without causing problems. For example:<br>
* <p>
* <code>
* sanitizeFilename("#thisIsATestGraph????!!")
* </code>
* {@code sanitizeFilename("#thisIsATestGraph????!!") }
* <p>
* would be sanitized to
* <p>
* <code>
* "_thisIsATestGraph_"
* </code>
* {@code "_thisIsATestGraph_" }
* <p>
* <b>Warning</b>: collisions can occur.
*
......@@ -76,15 +72,11 @@ public class GraphFileUtils {
/**
* Julianizes a path. For example:<br>
* <p>
* <code>
* julianizePath("./foo/bar/jpeg_export/graph46.graphml")
* </code>
* {@code julianizePath("./foo/bar/jpeg_export/graph46.graphml") }
* <p>
* would be julianized to
* <p>
* <code>
* "jpeg::graph46"
* </code>
* {@code "jpeg::graph46" }
* <p>
* <b>Warning</b>: collisions can occur.
*
......@@ -301,8 +293,7 @@ public class GraphFileUtils {
* Generates java code to create a {@link MoovacFormulation} from scratch for the given graph. The generated code is
* written to the provided print stream.
* <p>
* Use <code>new PrintStream(new FileOutputStream(new File(filename))</code> to immediately write the code to a
* file.
* Use {@code new PrintStream(new FileOutputStream(new File(filename))} to immediately write the code to a file.
*
* @param graph the graph to create the formulation code for
* @param problemName the formulation's problem name
......
......@@ -228,11 +228,7 @@ public class JavaUtils {
* @param key the key to insert or increment
*/
public static <K> void insertOrIncValue(Map<? super K, Integer> map, K key) {
if (!Objects.requireNonNull(map).containsKey(key)) {
map.put(key, 1);
} else {
map.put(key, map.get(key) + 1);
}
map.put(Objects.requireNonNull(key), map.getOrDefault(key, 0) + 1);
}
/**
......@@ -245,12 +241,7 @@ public class JavaUtils {
* @throws IllegalArgumentException if min is greater than max
*/
public static int pickBounded(int min, int max, SeededRandom rng) {
if (min > max) {
throw new IllegalArgumentException(
"Min value must be less than or equal to the max value.\nMin: " + min + "\nMax: " + max);
}