JavaScript中的分区细化算法

时间:2016-12-20 10:36:24

标签: javascript arrays algorithm graph partitioning

我有一组节点{s1,s2,s3,s4,s5}和一些边缘:

  • (S1,一,S2)
  • (S2,一,S2)
  • (S3,一,S4)
  • (S4,一个,S4)
  • (S5,一个,S5)

  • (S1,B,S3)

  • (S3,B,S5)
  • (S5,B,S5)

我在

中有一个分区细化过程

enter image description here

在第一张图片中,我有Array(或Map?)中的所有节点。

在每次迭代中,我都希望将每个块减少为子块。在第一张图片中的(仅)块中,我们看到s2和s4可以进行a-过渡(两个循环)但没有b-过渡,而剩余的节点s1,s3,s5可以进行a-transition和b-transitions,所以我将它们分成两个块{s1,s3,s5}和{s2,s4}。

在下一次迭代中,块{s2,s4}没有区别,但在另一个块中,我们看到s1和s3有一个转换到块{s2,s4}而s5有一个a - 转换到它自己的块{s1,s3,s5},所以我将s5分成它自己的块,产生{s1,s3},{s5},{s2,s4}。

最后,我看到s3有一个b转换到块{s5}而{s1}做有这个,所以我将s3和s1分组为不同的块,产生{s1} ,{s3},{s5},{s2,s4}。

如何在JavaScript中实现此功能?

我猜它可能是这样的

// all nodes
var nodes = getNodes();

// all edges
var edges = getEdges();

// always holding the current partition
var partition = [];

// first add all nodes into 1 block
partition.push(nodes)

// run until the process is terminated
while (true) {

  // loop through each block in partition
  partition.forEach(function (block) {

    // only care about blocks with more than 1 node
    if (block.length > 1) {

      // loop through each node in the block
      block.forEach(function (node) {

        // check which transitions this node have (i.e. which label and which blocks it goes into)

      });

    }

  });

1 个答案:

答案 0 :(得分:1)

这是尝试将某些函数用作规则的回调,以便将数组与节点分开。

第3部分的三个函数命名为'selfOnly',第2部分命名为'transitionOnly',第3部分命名为'transitionInto'

refinement函数采用细化和转换的类型。

refinement的Inisde是一个用于将节点移动到新组的函数,以及partitionspartsedges中的搜索的一些迭代。

然后使用类型相关的回调来确定某个节点是否要与实际组分开。



function refinement(type, transition) {

    function move(source, target, index, pos) {
        if (pos === undefined) {
            pos = target.push(source.splice(index, 1)) - 1;
        } else {
            target[pos].push(source.splice(index, 1)[0]);
        }
        return pos;
    }

    partitions.forEach(function (parts) {
        var pos;
        if (parts.length === 1) {
            return;
        }
        parts.reduceRight(function (_, part, i) {
            edges.forEach({
                selfOnly: function (a) {
                    if (a[0] !== part || a[1] !== transition || a[2] !== part) {
                        return;
                    }
                    if (!edges.some(function (b) { return b[0] === part && b[1] !== transition && a[2] === part; })) {
                        pos = move(parts, partitions, i, pos);
                    }
                },
                transitionOnly: function (a) {
                    if (a[0] !== part || a[1] !== transition || a[2] === part) {
                        return;
                    }
                    pos = move(parts, partitions, i, pos);
                },
                transitionInto: function (a) {
                    if (a[1] !== transition || a[2] !== part) {
                        return;
                    }
                    pos = move(parts, partitions, i, pos);
                }
            }[type]);
        }, null);
    });
}

var nodes = ['s1', 's2', 's3', 's4', 's5'],
    edges = [['s1', 'a', 's2'], ['s2', 'a', 's2'], ['s3', 'a', 's4'], ['s4', 'a', 's4'], ['s5', 'a', 's5'], ['s1', 'b', 's3'], ['s3', 'b', 's5'], ['s5', 'b', 's5']],
    partitions = [nodes];

refinement('selfOnly', 'a');
console.log(partitions);
refinement('transitionOnly', 'a');
console.log(partitions);
refinement('transitionInto', 'b');
console.log(partitions);

.as-console-wrapper { max-height: 100% !important; top: 0; }