Permalink
Browse files

Rename Graph => IndexedEdgeList, make library functions generic.

  * Choice of name reflects that given to the corresponding
    graph implementation in igraph.

  * Library functions should now work with any graph satisfying
    the characteristics tested for by isGraph
  • Loading branch information...
WebDrake committed Aug 30, 2013
1 parent 48ccb32 commit aa40b50b26e088178024f467dd8d40c63f197987
Showing with 85 additions and 40 deletions.
  1. +4 −3 betweenness.d
  2. +9 −9 dgraph/graph.d
  3. +54 −21 dgraph/metric.d
  4. +12 −3 dgraph/test/tests.d
  5. +6 −4 graphtest.d
View
@@ -2,9 +2,9 @@ import std.datetime, std.stdio;
import dgraph.graph, dgraph.metric, dgraph.test.samplegraph50;
void betw(bool directed)(ref Graph!directed g)
void betw(Graph)(ref Graph g)
if(isGraph!Graph)
{
assert(!directed);
auto centrality = betweenness(g);
assert(centrality.length == g.vertexCount);
/* writeln("Centrality values:");
@@ -16,7 +16,8 @@ void betw(bool directed)(ref Graph!directed g)
void main()
{
auto g = new Graph!false;
alias Graph = IndexedEdgeList!false;
auto g = new Graph;
g.addVertices(50);
foreach (immutable i; 0 .. sampleGraph50.length / 2)
View
@@ -93,15 +93,15 @@ template isUndirectedGraph(G)
unittest
{
assert(isGraph!(Graph!true));
assert(isGraph!(Graph!false));
assert(isDirectedGraph!(Graph!true));
assert(!isDirectedGraph!(Graph!false));
assert(!isUndirectedGraph!(Graph!true));
assert(isUndirectedGraph!(Graph!false));
assert(isGraph!(IndexedEdgeList!true));
assert(isGraph!(IndexedEdgeList!false));
assert(isDirectedGraph!(IndexedEdgeList!true));
assert(!isDirectedGraph!(IndexedEdgeList!false));
assert(!isUndirectedGraph!(IndexedEdgeList!true));
assert(isUndirectedGraph!(IndexedEdgeList!false));
}
final class Graph(bool dir)
final class IndexedEdgeList(bool dir)
{
private:
size_t[] _head;
@@ -419,7 +419,7 @@ final class Graph(bool dir)
unittest
{
import std.stdio;
auto g1 = new Graph!false;
auto g1 = new IndexedEdgeList!false;
g1.addVertices(10);
assert(g1.vertexCount == 10);
g1.addEdge(5, 8);
@@ -482,7 +482,7 @@ unittest
assert(i == g1.edgeID(t, h));
}
auto g2 = new Graph!true;
auto g2 = new IndexedEdgeList!true;
g2.addVertices(10);
assert(g2.vertexCount == 10);
g2.addEdge(5, 8);
View
@@ -70,8 +70,8 @@ unittest
assert(q.empty);
}
auto betweenness(T = double, bool directed)(ref Graph!directed g, bool[] ignore = null)
if (isFloatingPoint!T)
auto betweenness(Graph, T = double)(ref Graph g, bool[] ignore = null)
if (isGraph!Graph && isFloatingPoint!T)
{
T[] centrality = new T[g.vertexCount];
centrality[] = to!T(0);
@@ -159,15 +159,16 @@ auto betweenness(T = double, bool directed)(ref Graph!directed g, bool[] ignore
}
}
static if (!directed)
static if (!g.directed)
{
centrality[] /= 2;
}
return centrality;
}
size_t largestClusterSize(bool directed)(ref Graph!directed g, bool[] ignore)
size_t largestClusterSize(Graph)(ref Graph g, bool[] ignore)
if (isGraph!Graph)
{
long[] cluster = new long[g.vertexCount];
cluster[] = -1L;
@@ -188,7 +189,7 @@ size_t largestClusterSize(bool directed)(ref Graph!directed g, bool[] ignore)
size_t v = q.front;
q.pop();
static if (directed)
static if (g.directed)
{
auto allNeighbours = chain(g.neighboursIn(v), g.neighboursOut(v));
}
@@ -219,9 +220,17 @@ unittest
{
import std.stdio, std.typecons;
void clusterTest1(bool directed = false)()
void clusterTest1(Graph)()
if (isGraph!Graph)
{
auto g = new Graph!directed;
static if (is(Graph == class))
{
auto g = new Graph;
}
else
{
auto g = Graph;
}
bool[] ignore = new bool[5];
g.addVertices(5);
g.addEdge(0, 1);
@@ -235,9 +244,17 @@ unittest
writeln("largest cluster size = ", largest);
}
void clusterTest2(bool directed = false)()
void clusterTest2(Graph)()
if (isGraph!Graph)
{
auto g = new Graph!directed;
static if (is(Graph == class))
{
auto g = new Graph;
}
else
{
auto g = Graph;
}
bool ignore[] = new bool[100];
g.addVertices(100);
foreach (immutable i; 0 .. 100)
@@ -255,9 +272,17 @@ unittest
}
}
void clusterTest3(bool directed = false)(immutable size_t n)
void clusterTest3(Graph)(immutable size_t n)
if (isGraph!Graph)
{
auto g = new Graph!directed;
static if (is(Graph == class))
{
auto g = new Graph;
}
else
{
auto g = Graph;
}
bool ignore[] = new bool[n];
g.addVertices(n);
foreach (immutable i; 0 .. n - 1)
@@ -269,12 +294,20 @@ unittest
writeln("largest cluster size = ", largestClusterSize(g, ignore));
}
void clusterTest50(bool directed = false)()
void clusterTest50(Graph)()
if (isGraph!Graph)
{
import std.random;
import dgraph.test.samplegraph50;
auto g = new Graph!directed;
static if (is(Graph == class))
{
auto g = new Graph;
}
else
{
auto g = Graph;
}
bool ignore[] = new bool[50];
g.addVertices(50);
g.addEdge(sampleGraph50);
@@ -293,14 +326,14 @@ unittest
}
clusterTest1!false();
clusterTest2!false();
clusterTest1!true();
clusterTest2!true();
clusterTest1!(IndexedEdgeList!false)();
clusterTest2!(IndexedEdgeList!false)();
clusterTest1!(IndexedEdgeList!true)();
clusterTest2!(IndexedEdgeList!true)();
clusterTest50!false();
clusterTest50!true();
clusterTest50!(IndexedEdgeList!false)();
clusterTest50!(IndexedEdgeList!true)();
clusterTest3!false(40);
clusterTest3!true(40);
clusterTest3!(IndexedEdgeList!false)(40);
clusterTest3!(IndexedEdgeList!true)(40);
}
View
@@ -29,11 +29,19 @@ import dgraph.graph;
Tests adding edges one at a time. Can be used e.g. for benchmarking or for
checking that network properties are reliably imported.
*/
void testAddEdge(bool allAtOnce = false, bool directed = false, ushort verbose = 0, T : size_t)
void testAddEdge(Graph, bool allAtOnce = false, ushort verbose = 0, T : size_t)
(immutable size_t v, T[] edgeList)
if (isGraph!Graph)
{
assert(edgeList.length % 2 == 0);
auto g = new Graph!directed;
static if (is(Graph == class))
{
auto g = new Graph;
}
else
{
auto g = Graph;
}
g.addVertices(v);
static if (allAtOnce)
@@ -118,7 +126,8 @@ void testAddEdge(bool allAtOnce = false, bool directed = false, ushort verbose =
}
/// Tests that the edgeID function returns correct values for all edges in the graph.
void testEdgeID(bool directed)(ref Graph!directed g)
void testEdgeID(Graph, bool directed)(ref Graph g)
if(isGraph!Graph)
{
foreach (immutable i; 0 .. g.edgeCount)
{
View
@@ -26,6 +26,8 @@ import dgraph.graph, dgraph.test.tests, dgraph.test.samplegraph50,
void main()
{
alias G = IndexedEdgeList;
enum bool dir = false;
StopWatch watch;
writeln("Let's benchmark some simple graph creation scenarios.");
@@ -37,9 +39,9 @@ void main()
watch.start;
foreach (immutable _; 0 .. 100_000)
{
testAddEdge!(true, false, 0)(50, sampleGraph50);
testAddEdge!(G!dir, true, 0)(50, sampleGraph50);
}
testAddEdge!(true, false, 1)(50, sampleGraph50);
testAddEdge!(G!dir, true, 1)(50, sampleGraph50);
watch.stop;
writeln("Done in ", watch.peek.msecs, " ms.");
writeln;
@@ -51,9 +53,9 @@ void main()
watch.start;
foreach (immutable _; 0 .. 1_000)
{
testAddEdge!(true, false, 0)(10_000, sampleGraph10k);
testAddEdge!(G!dir, true, 0)(10_000, sampleGraph10k);
}
testAddEdge!(true, false, 1)(10_000, sampleGraph10k);
testAddEdge!(G!dir, true, 1)(10_000, sampleGraph10k);
watch.stop;
writeln("Done in ", watch.peek.msecs, " ms.");
}

0 comments on commit aa40b50

Please sign in to comment.