diff --git a/lib/order/cross-count.js b/lib/order/cross-count.js index 2f8b6b0f..18a78882 100644 --- a/lib/order/cross-count.js +++ b/lib/order/cross-count.js @@ -22,8 +22,34 @@ module.exports = crossCount; */ function crossCount(g, layering) { var cc = 0; - for (var i = 1; i < layering.length; ++i) { - cc += twoLayerCrossCount(g, layering[i-1], layering[i]); + for (var i = 0; i < layering.length; ++i) { + cc += singleLayerCrossCount(g, layering[i]); + if (i > 0) { + cc += twoLayerCrossCount(g, layering[i-1], layering[i]); + } + } + return cc; +} + +function singleLayerCrossCount(g, layer) { + var cc = 0; + if (layer.length) { + var layerRank = g.node(layer[0]).rank; + var layerIndex = _.zipObject( + layer, + _.map(layer, function (v, i) { return i; }) + ); + + _.forEach(layer, function(n, i) { + _.forEach(g.inEdges(n), function(e) { + if (g.node(e.v).rank == layerRank) { + var otherPos = layerIndex[e.v]; + if (Math.abs(otherPos - i) > 1) { + cc++; + } + } + }); + }); } return cc; } diff --git a/test/order/cross-count-test.js b/test/order/cross-count-test.js index a884582e..c48a0c67 100644 --- a/test/order/cross-count-test.js +++ b/test/order/cross-count-test.js @@ -1,6 +1,8 @@ var expect = require("../chai").expect; var Graph = require("../../lib/graphlib").Graph; var crossCount = require("../../lib/order/cross-count"); +var _ = require("lodash"); + describe("crossCount", function() { var g; @@ -8,6 +10,9 @@ describe("crossCount", function() { beforeEach(function() { g = new Graph() .setDefaultEdgeLabel(function() { return { weight: 1 }; }); + _.forEach(["a1", "a2", "a3"], function(v) { g.setNode(v, { rank: 1 }); }); + _.forEach(["b1", "b2"], function(v) { g.setNode(v, { rank: 2 }); }); + _.forEach(["c1", "c2"], function(v) { g.setNode(v, { rank: 3 }); }); }); it("returns 0 for an empty layering", function() { @@ -39,6 +44,9 @@ describe("crossCount", function() { }); it("works for graph #1", function() { + _.forEach(["a", "d"], function(v) { g.setNode(v, { rank: 1 }); }); + _.forEach(["b", "f", "e"], function(v) { g.setNode(v, { rank: 2 }); }); + _.forEach(["c", "i"], function(v) { g.setNode(v, { rank: 3 }); }); g.setPath(["a", "b", "c"]); g.setPath(["d", "e", "c"]); g.setPath(["a", "f", "i"]); @@ -46,4 +54,12 @@ describe("crossCount", function() { expect(crossCount(g, [["a", "d"], ["b", "e", "f"], ["c", "i"]])).equals(1); expect(crossCount(g, [["d", "a"], ["e", "b", "f"], ["c", "i"]])).equals(0); }); + + it("handles single-layer crossings", function() { + g.setEdge("a1", "b1"); + g.setEdge("a1", "a3"); + g.setEdge("a2", "b2"); + expect(crossCount(g, [["a1", "a2", "a3"], ["b2", "b1"]])).equals(2); + }); + });