Skip to content

Commit

Permalink
trying to optimize crossings but not working yet
Browse files Browse the repository at this point in the history
  • Loading branch information
jdfekete committed Apr 23, 2015
1 parent 9be1c95 commit d45eb01
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 6 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ reorder.v1.js: \
src/mat2graph.js \
src/graph2mat.js \
src/count_crossings.js \
src/adjacent_exchange.js \
src/barycenter.js \
src/all_pairs_distance.js \
src/graph2distmat.js \
Expand Down
3 changes: 2 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Interaction:
Reordering:
Improve the barycenter heuristic with swaps
Koren multiscale ACE: http://dx.doi.org/10.1109/INFVIS.2002.1173159
Spectral ordering
Sloan ordering
Biclustering
Contingency tables methods:
PCA ordering
Expand All @@ -24,4 +26,3 @@ Reordering done:
Bioinformatics, 19(9), pp 1070-8, 2003
http://www.cs.cmu.edu/~zivbj/compBio/k-aryBio.pdf
Inverse Cuthill-McKee

90 changes: 88 additions & 2 deletions reorder.v1.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(function(exports){
reorder = {version: "0.0.4"}; // semver
reorder = {version: "0.0.5"}; // semver

// Use as: [4,3,2].sort(reorder.cmp_number_asc);
reorder.cmp_number_asc = function(a,b) { return a-b; };
Expand Down Expand Up @@ -854,6 +854,90 @@ function count_crossings(graph, north, south) {
return crosscount;
}
reorder.count_crossings = count_crossings;
// Accorging to
// E. R. Gansner, E. Koutsofios, S. C. North, and K.-P. Vo. 1993. A
// Technique for Drawing Directed Graphs. IEEE Trans. Softw. Eng. 19, 3
// (March 1993), 214-230. DOI=10.1109/32.221135
// http://dx.doi.org/10.1109/32.221135
// page 14: "[...] reduce obvious crossings after the vertices have
// been sorted, transforming a given ordering to one that is locally
// optimal with respect to transposition of adjacent vertices. It
// typically provides an additional 20-50% reduction in edge crossings.

function count_in_crossings(graph, v, w, inv) {
var v_edges = graph.inEdges(v),
w_edges = graph.inEdges(w),
iv, iw, p0, cross = 0;

for (iw = 0; iw < w_edges.length; iw++) {
p0 = inv[w_edges[iw].target.index];
for (iv = 0; iv < v_edges.length; iv++) {
if (inv[v_edges[iv].target.index] > p0)
cross++;
}
}
return cross;
}

function count_out_crossings(graph, v, w, inv) {
var v_edges = graph.outEdges(v),
w_edges = graph.outEdges(w),
iv, iw, p0, cross = 0;

for (iw = 0; iw < w_edges.length; iw++) {
p0 = inv[w_edges[iw].target.index];
for (iv = 0; iv < v_edges.length; iv++) {
if (inv[v_edges[iv].target.index] > p0)
cross++;
}
}
return cross;
}

function adjacent_exchange(graph, layer1, layer2, crossings) {
var i, v, w, c0, c1,
inv_layer1 = inverse_permutation(layer1),
inv_layer2 = inverse_permutation(layer2),
swapped = true;

while (swapped) {
swapped = false;
for (i = 0; i < layer1.length-1; i++) {
v = layer1[i];
w = layer1[i+1];
c0 = count_out_crossings(graph, v, w, inv_layer2);
c1 = count_out_crossings(graph, w, v, inv_layer2);
if (c1 < c0) {
layer1[i] = w;
layer1[i+1] = v;
c0 = inv_layer1[v];
inv_layer1[v] = inv_layer1[w];
inv_layer1[w] = c0;
swapped = true;
crossings -= c0-c1;
}
}
for (i = 0; i < layer2.length-1; i++) {
v = layer2[i];
w = layer2[i+1];
c0 = count_in_crossings(graph, v, w, inv_layer1);
c1 = count_in_crossings(graph, w, v, inv_layer1);
if (c1 < c0) {
layer2[i] = w;
layer2[i+1] = v;
c0 = inv_layer2[v];
inv_layer2[v] = inv_layer2[w];
inv_layer2[w] = c0;
swapped = true;
crossings -= c0-c1;
}
}
}

return [layer1, layer2, crossings];
};

reorder.adjacent_exchange = adjacent_exchange;
reorder.barycenter = function(graph, iter, comps) {
var perms = [[], [], 0];
// Compute the barycenter heuristic on each connected component
Expand Down Expand Up @@ -935,7 +1019,7 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
iter++, layer = (layer == layer1) ? layer2 : layer1) {
for (i = 0; i < layer.length; i++) {
// Compute the median/barycenter for this node and set
// its (real) value into node.mval
// its (real) value into node.pos
v = nodes[layer[i]];
if (layer == layer1)
neighbors = graph.outEdges(v.index);
Expand Down Expand Up @@ -968,9 +1052,11 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
best_layer1 = layer1;
best_layer2 = layer2;
best_iter = iter;
max_iter = Math.max(max_iter, iter + 2); // we improved so go on
}
}
//console.log('Best iter: '+best_iter);

return [best_layer1, best_layer2, best_crossings];
};
reorder.all_pairs_distance = function(graph, comps) {
Expand Down
4 changes: 2 additions & 2 deletions reorder.v1.min.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/barycenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
iter++, layer = (layer == layer1) ? layer2 : layer1) {
for (i = 0; i < layer.length; i++) {
// Compute the median/barycenter for this node and set
// its (real) value into node.mval
// its (real) value into node.pos
v = nodes[layer[i]];
if (layer == layer1)
neighbors = graph.outEdges(v.index);
Expand Down Expand Up @@ -112,8 +112,10 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
best_layer1 = layer1;
best_layer2 = layer2;
best_iter = iter;
max_iter = Math.max(max_iter, iter + 2); // we improved so go on
}
}
//console.log('Best iter: '+best_iter);

return [best_layer1, best_layer2, best_crossings];
};
4 changes: 4 additions & 0 deletions test/barycenter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ function dotest(mat) {
//perms[1], perms[0], perms[2]);
//reorder.printmat(mat, perms[1], perms[0]);
assert.isTrue(initial_crossings > perms[2]);
var perm2 = reorder.adjacent_exchange(graph,
perms[0], perms[1], perms[2]);
assert.isTrue(perm2[2] >= perms[2]);
console.log('Improved by: %d', perm2[2]-perms[2]);
}

suite.addBatch({
Expand Down

0 comments on commit d45eb01

Please sign in to comment.