在有向图中丢弃传入节点

4

我希望能够在有向图中丢弃传入节点

简短总结(跳转到第3部分)

我有一个图,在这个图上执行BFS以删除所有与候选边无关的节点。

1. 样本图数据

假设这是一个图数据结构:

其中: - id1id2目标

      var links = [
        {id1: 1, id2: 2},
        {id1: 2, id2: 3},
        {id1: 9, id2: 3},
        {id1: 6, id2: 8},
        {id1: 3, id2: 4}
      ]

上述结构的可视化:

上述结构的图形可视化

2. 我成功地丢弃了不相关的节点/边

我运行了一个BFS算法(如下所示的函数),以丢弃所有相对于edge = 1无关的节点,结果如下:

      var links = [
        {id1: 1, id2: 2},
        {id1: 2, id2: 3},
        {id1: 9, id2: 3},
       // {id1: 6, id2: 8}, Discarded (no connection with 1)
        {id1: 3, id2: 4}
      ]

上述的可视化效果如下:

上述结构的图形可视化效果

3. 我现在想要删除入节点

现在我想要删除所有的节点,只保留从edge=1开始“指向”相关节点的节点(用缺乏更好的词汇来描述)。

例如:

      var links = [
        {id1: 1, id2: 2},
        {id1: 2, id2: 3},
        {id1: 9, id2: 3}, // remove this
        {id1: 3, id2: 4}
      ]

图形可视化所示的期望结果,显示断开的链接

我该怎么做呢?

这是我目前用来删除不相关节点/边的方法:

var filterUnrelated = function(data, candidateId) {
  var toTest = [candidateId];
  var connected = [];

  function addToTest(node) {
    //If the node is not already set to be tested, and have not been tested
    if (connected.indexOf(node) < 0 && toTest.indexOf(node) < 0) {
      toTest.push(node);
    }
  }

  function findAllConnectedNode(node) {
    //We only test connected node, so this node should be connected
    connected.push(node);
    //Find every link with that node
    data.filter(function(d) {
      return (d.id1 === node) || (d.id2 === node);
      //Add the linked node to test
    }).map(function(d) {
      if (d.id1 === node) {
        addToTest(d.id2);
      }
      else { //d.id1 === node
        addToTest(d.id1);
      }
    });
  }

  while (toTest.length > 0) {
    findAllConnectedNode(toTest.shift());
  }

  return data.filter(function(d) {
    return (connected.indexOf(d.id1) >= 0 ||
      connected.indexOf(d.id2) >= 0);
  })
}


var links = [
  {id1: 1, id2: 2},
  {id1: 2, id2: 3},
  {id1: 9, id2: 3},
  {id1: 6, id2: 8},
  {id1: 3, id2: 4}
]

console.log(filterUnrelated(links, 1));
          

1个回答

2
假设您的图形永远不会有分支(即一个节点指向两个节点),您可以从源节点开始,并继续向上查找每个子节点。
function removeIncoming(data, source){
    // keep track of the member we are looking for
    var target = source;
    // the resulting graph
    var result = [];
    // iterate through the data, looking for the target
    for(var i = 0; i < data.length; i++){
        // the object in the list
        var piece = data[i];
        // its properties id1 and id2
        var id1 = piece.id1;
        var id2 = piece.id2;

        // when we have found what we are looking for
        if(id1 === target){
            // look for its child
            target = id2;
            // start at the beginning
            i = -1;
            // and add the link to the resulting list
            result.push(piece);
        }
    }

    return result;
}

另外,使用分支节点,您可以在数组中跟踪每个可能的节点,然后使用indexOf来搜索它们。

function removeIncoming(data, source){
    // copy the data
    var dataCopy = Array.prototype.slice.call(data);
    // keep track of the members we are looking for
    var targets = [source];
    // the resulting graph
    var result = [];
    // iterate through the data, looking for the target
    for(var i = 0; i < dataCopy.length; i++){
        // the object in the list
        var piece = dataCopy[i];
        // its properties id1 and id2
        var id1 = piece.id1;
        var id2 = piece.id2;

        // when we have found what we are looking for
        if(targets.indexOf(id1) >= 0){
            // begin looking for its child
            targets.push(id2);
            // remove the node we just looked at
            dataCopy.splice(i, 1);
            // start at the beginning
            i = -1;
            // and add the link to the resulting list
            result.push(piece);
        }
    }

    return result;
}

谢谢 - 出于好奇,是否有一种在图论中描述我要构建的路径的正式名称? - nicholaswmin
@NicholasKyriakides 我不确定,但我会把你的路径称为“曲线”。 - Conor O'Brien
我认为 id1/id2 应该颠倒 - 即使用 indexOf(id2)push(id1) - nicholaswmin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接