diff --git a/graph/graph.cpp b/graph/graph.cpp
index 91fae50cb2c684b411b2c669c11861d8469152a9..a3ed67b350289013b1289e02237582a60f8b4688 100644
--- a/graph/graph.cpp
+++ b/graph/graph.cpp
@@ -35,9 +35,96 @@
 //-----------------------------------------------------------------------------
 
 // The first command line argument is the graph ID.
-// Currently, this program can generate only the following graphs:
-// fn_k: "Fence Graph" with Nodes V = {1, ..., 2n}
-//	and Edges E = { (i, (i+j-1 mod n)+n+1) | 1 <= i <= n and 0 <= j < k }
+// The graph ID consists of a letter (lowercase or uppercase are equivalent)
+// and one or two parameters (natural numbers).
+// If there are two parameters, they are separated with "_".
+// For instance, M1000_10 is a "Multipath" graph that consists of 10 paths
+// of length 1000.
+
+// The second and following command line parameters are the output files.
+// Currently, the extension of the output files must be .P or .tsv.
+// For .P, Prolog facts are generated,
+// for .tsv, Tab-separated values.
+
+// This program can generate the following graphs:
+// -----------------------------------------------
+
+// Bn: Binary tree of height n
+//       2^n - 1 nodes, 2^n - 2 edges.
+//       N = {1, ..., 2^n - 1}
+//       E = {(i, 2*i)     | i = 1, ..., 2^{n-1} - 1} u
+//           {(i, 2*i + 1) | i = 1, ..., 2^{n-1} - 1}
+
+// Cn: Cycle with n nodes
+//       n nodes, n edges.
+//       N = {1, ..., n}
+//       E = {(i, i+1) | i = 1, ..., n-1} u {(n, 1)}  
+
+// Dn_k: Diamond (k copies)
+// Dn:   Diamond (k = 1, i.e. one copy)
+//       Each diamond consists of a bottom node, e.g. 1 for the first diamond,
+//       from there edges to n nodes (e.g. 2, ..., n+1),
+//       and from each of these nodes edges to a top node (e.g. n+2).
+//       k * (n+2) nodes, k * 2*n edges
+//       N = {1, ..., k * (n+2)}
+//       E = { (i*(n+2) + 1, i*(n+2) + 1 + j) | i = 0,...,k; j = 1,...,n} u
+//           { (i*(n+2) + j, i*(n+2) + n + 2) | i = 0,...,k; j = 1,...,n} u
+
+// Kn: Complete graph with n nodes.
+//       n nodes, n^2 edges.
+//       N = {1, ..., n}
+//       E = {(i, j) | i = 1, ..., n;  j = 1, ..., n }
+
+// Mn_k: Multipath: k paths of length m.
+//       n*k nodes, (n-1)*k edges.
+//       V = {1, ..., n*k}
+//       E = {(i, i+k) | i = 1, ..., (n-1)*k}
+
+// Pn:   Path of length n
+//       n nodes, n-1 edges.
+//       V = {1, ..., n}
+//       E = {(i, i+1) | i = 1, ..., n-1}
+
+// Sn_k: Shortcut graph (cycle of length n with shortcuts)
+//       It is required that n is divisible by k+1.
+//       Each node has out degree k+1.
+//       E.g. from node 1, there is one edge to node 2 (as in standard cycle),
+//       then one edge to node 2 + (n/(k+1)),
+//       then one edge to node 2 + 2 * (n/(k+1)),
+//       and so on until node  2 + k * (n/(k+1)).
+//       The next value in the sequence, 2 + (k+1) * (n/(k+1)) modulo n is 2.
+//       For instance, if k=1, there is one shortcut edge spanning half the
+//       cycle, e.g. node 1 has connections to node 2 and node 2 + n/2.
+//       For n=10 and k=2, the edges are (1,2), (1,7), (2,3), (2,8), ...
+//       The graph has n nodes, n * (k+1) edges.
+//       N = {1, ..., n}
+//       E = {(i, i+1) | i = 1, ..., n-1} u {(n, 1)} u // Standard Cycle
+//           {(i, 1 + ((i + (n*j)/(k+1)) mod n) | i = 1,...,n; j=1,...,k }
+
+// Tn:   Total order graph (maximum acyclic graph)
+
+// Un_k: Random Graph, Uniform Distribution of Node Degrees
+//       n nodes, k edges
+
+// Vn:   InVerted binary tree of height n (looks like V if edges point down)
+//       2^n - 1 nodes, 2^n - 2 edges.
+//       N = {1, ..., 2^n - 1}
+//       E = {(2*i, i)     | i = 1, ..., 2^{n-1} - 1} u
+//           {(2*i + 1, i) | i = 1, ..., 2^{n-1} - 1}
+
+
+// Wn_k: Single level of edges, mesh, 2n nodes, degree k):
+//       V = {1, ..., 2n}
+//       E = { (i, (i+j-1 mod n)+n+1) | 1 <= i <= n and 0 <= j < k }
+
+// Xn_k: X-graph (n edges to central node, k from there)
+
+// Yn_k: Y-graph (n nodes point to central node, then path of length k)
+//       n+k nodes: V= {1,...,n+k}
+//       n+k-1 edges:
+//       E = {(i, n+1)} | i = 1,...,n} u {(n+i, n+i+1) | i = 1,...,k-1}
+
+// The program code for graph g is in the procedure gen_graph_g.
 
 //=============================================================================
 // Buffer Size for Graph Parameter:
@@ -1044,21 +1131,78 @@ int next_prime(int p) {
 	return p;
 }
 
+//-----------------------------------------------------------------------------
+// Random number generator (to make random graphs deterministic and portable):
+//-----------------------------------------------------------------------------
+
+// The code is from
+// https://de.wikipedia.org/wiki/KISS_(Zufallszahlengenerator)
+// The same generator is the main random number generator mentioned in
+// http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf
+
+static uint32_t x = 123456789; // seed can be arbitrary,
+static uint32_t y = 362436000; // as long as y != 0 and
+static uint32_t z = 521288629; // z,c are not both 0
+static uint32_t c = 7654321;
+
+uint32_t rand_KISS() {
+   uint64_t t;
+
+   // Linear congruential generator:
+   x = 69069 * x + 12345;
+
+   // Xorshift:
+   y ^= y << 13;
+   y ^= y >> 17;
+   y ^= y << 5;
+
+   // Multiply-with-carry:
+   t = (uint64_t)698769069 * z + c;
+   c = t >> 32;
+   z = (uint32_t) t;
+
+   return x + y + z;
+}
+
 //-----------------------------------------------------------------------------
 // Compute Random Number from 0 to n (inclusive):
 //-----------------------------------------------------------------------------
 
 int rand_until(int n) {
-	//return rand() % (n+1);
-	int r = rand();
+	//int r = rand();
+	uint32_t r = rand_KISS();
+
 	int result = r % (n+1);
+	//	This is the simple version that can be used when n is much
+	//	smaller than the maximal random number that is generated.
+	//	Theoretically, the numbers are not completely evenly
+	//	distributed, because the last set of n+1 numbers before
+	//	the maximal random number is usually not complete
+	//	(unless the number of results that the random number generates
+	//	is dividable by n+1).
+	//	However, if n is not more than 4 million (e.g. we generate
+	//	not more than 4M edges), the error from a uniform distribution
+	//	is less than one promille.
+
+	//int result = (int) (((double) r) * (n+1) / (0xFFFFFFFF + 1.0));
+	//	This version avoids the slight problem, but uses double.
+	//	The divisor is the maximal result of rand_KISS + 1:
+	//	4294967296.0
+	//	When double is converted to int, no rounding is done,
+	//	but the floor function is used.
+	//	Therefore, the result can never be n+1 or larger.
+
+	if(result < 0 || result > n) {
+		std::cerr << "Error in random number generator!\n";
+		exit(24);
+	}
 	std::cout << "rand_until(" << n << ") = " << result <<
 		"\t[rand = " << r << "]\n";
 	return result;
 }
 
 //-----------------------------------------------------------------------------
-// Random Suffling of Array:
+// Random Shuffling of Array:
 //-----------------------------------------------------------------------------
 
 void rand_shuffle(int arr[], int len) {
@@ -1070,7 +1214,7 @@ void rand_shuffle(int arr[], int len) {
 	}
 
 	std::cout << "\n";
-	std::cout << "Result of Shuffle (Array Length: " << len << "\n";
+	std::cout << "Result of Shuffle (Array Length: " << len << ")\n";
 	for(int i = 0; i < len; i++)
 		std::cout << "\t arr[" << i << "] = " << arr[i] << "\n";
 	std::cout << "\n";
@@ -1274,7 +1418,7 @@ void gen_graph_s(int n, int k, output_t out, gsize_t gsize) {
 	// Check divisibility condition:
 	if(n % (k+1) != 0) {
 		std::cout << "S[n,k] requires that n is divisible by k+1.\n";
-		exit(24);
+		exit(25);
 	}
 
 	// Set number of nodes:
@@ -1290,7 +1434,8 @@ void gen_graph_s(int n, int k, output_t out, gsize_t gsize) {
 	for(int j = 1; j <= k; j++) {
 		int skip =  (n*j)/(k+1);
 		for(int i = 1; i <= n; i++) {
-			out->write_edge(i, 1 + (i-1 + skip) % n);
+			//out->write_edge(i, 1 + (i-1 + skip) % n);
+			out->write_edge(i, 1 + (i + skip) % n);
 		}
 	}
 
@@ -1305,14 +1450,22 @@ void gen_graph_s(int n, int k, output_t out, gsize_t gsize) {
 	gsize->set_tc_inst(r);
 
 	// SG Size:
-	if(k == 1 && n % 4 == 2) {
-		gsize->set_sg_size(m * m / 2);
-		gsize->set_sg_inst(2 * (m * m + m));
-	}
-	else {
-		gsize->set_sg_size(m * m);
-		gsize->set_sg_inst(m * (k + 1) + m * m * (k+1) * (k+1));
-	}
+	//if(k == 1 && n % 4 == 2) {
+	//	gsize->set_sg_size(m * m / 2);
+	//	gsize->set_sg_inst(2 * (m * m + m));
+	//}
+	//else {
+	//	gsize->set_sg_size(m * m);
+	//	gsize->set_sg_inst(m * (k + 1) + m * m * (k+1) * (k+1));
+	//}
+	gsize->set_sg_size(m * (k+1));
+	//gsize->set_sg_inst(m*(k+1) + (k+1) * (m * (k+1)) * (k+1));
+	//The following is the same, slightly shorter:
+	gsize->set_sg_inst(m * (k+1) * (1 + (k+1) * (k+1)));
+	if(k > 0 && n > 1)
+		gsize->set_sg_iter(2);
+	else
+		gsize->set_sg_iter(1);
 }
 
 //-----------------------------------------------------------------------------
@@ -1627,7 +1780,7 @@ int main(int argc, str_t argv[])
 	// The program should be called with the graph and the output files:
 	if(argc < 3) {
 		std::cout << "Usage: ./graph GraphID OutputFile1 ...\n";
-		exit(25);
+		exit(26);
 	}
 
 	// Get graph parameters, first code:
@@ -1636,7 +1789,7 @@ int main(int argc, str_t argv[])
 	char graph_code = *p++;
 	if(graph_code == '\0') {
 		std::cout << "Impossible empty Graph ID.\n";
-		exit(26);
+		exit(27);
 	}
 
 	// First parameter:
@@ -1647,7 +1800,7 @@ int main(int argc, str_t argv[])
 	par_chars[i] = 0;
 	if(i == 0) {
 		std::cout << "First parameter in graph ID missing.\n";
-		exit(27);
+		exit(28);
 	}
 	int par1 = str_int(par_chars);
 	if(*p == 'k') {
@@ -1682,7 +1835,7 @@ int main(int argc, str_t argv[])
 		par_chars[i] = 0;
 		if(i == 0) {
 			std::cout << "Second parameter in graph ID missing.\n";
-			exit(28);
+			exit(29);
 		}
 		par2 = str_int(par_chars);
 		if(*p == 'k') {
@@ -1712,7 +1865,7 @@ int main(int argc, str_t argv[])
 	// Check that we have successfully parsed the entire graph ID:
 	if(*p != '\0') {
 		std::cout << "Unexpected characters at the end of graph ID.\n";
-		exit(29);
+		exit(30);
 	}
 
 	// Open output file(s):
@@ -1795,11 +1948,11 @@ int main(int argc, str_t argv[])
 			// Acyclic random graph
 			std::cout << "Please use the other graph generator " <<
 				"for this graph.\n";
-			exit(30);
+			exit(31);
 		default:
 			std::cout << "Unknown graph type '" << graph_code <<
 				"'.\n";
-			exit(31);
+			exit(32);
 	}
 
 	// Output number of edges written:
@@ -1832,6 +1985,7 @@ int main(int argc, str_t argv[])
 	sg.export_gsize(&gsize);
 
 	// Print computed size data:
+	std::cout << "\n";
 	std::cout << "Size Data Computed From Graph:\n";
 	std::cout << "=============================\n";
 	gsize.print();