Javascript 计算通过三个数组的最短路径

Javascript 计算通过三个数组的最短路径,javascript,Javascript,我有三个数组,或者可能是n。现在让我们拿三个。 他们的价值观如下:- Array1=[143, 181]; Array2=[41, 153, 241]; Array3=[22, 67, 131, 190]; 我想找到这三个数组的元素,它们之间的差异最小。 与本例类似,14353131的差异最小。假设您没有大量阵列,下面是一个解决方案,计算(并存储)所有路径: // First let's use a sensible structure var arrays = [Array1, Array2

我有三个数组,或者可能是n。现在让我们拿三个。 他们的价值观如下:-

Array1=[143, 181];
Array2=[41, 153, 241];
Array3=[22, 67, 131, 190];
我想找到这三个数组的元素,它们之间的差异最小。
与本例类似,14353131的差异最小。

假设您没有大量阵列,下面是一个解决方案,计算(并存储)所有路径:

// First let's use a sensible structure
var arrays = [Array1, Array2, Array3];

// Then, let's compute all possible paths
var paths = arrays[0].map(function(v){ return [v] });
for (var i = 1; i<arrays.length; i++) {
   var arr = arrays[i];
   for (var j=paths.length; j--; ) {
      var newPaths = arr.map(function(v){
        return paths[j].concat(v);
      })
      newPaths.unshift(j,1);
      [].splice.apply(paths, newPaths);
   }
}

// Now, let's just take the shortest one
var shortestDistance = Infinity,
    shortestPath = null;
paths.forEach(function(path){
  var distance = 0;
  for (var i=1; i<path.length; i++) {
    distance += Math.abs(path[i]-path[i-1]);
  }
  if (distance<shortestDistance) {
    shortestDistance = distance;
    shortestPath = path;
  }
});

// Finally, let's log the result
console.log(shortestDistance, shortestPath);

也许我知道你想要什么

您必须浏览一棵树,其中每个数组都是每个节点的所有后代的列表,如下所示:

          * (root)
       /      \
   143          181
  / | \        / | \
41 153 241   41 153 241
/|\/|\ /|\   /|\/|\ /|\
........ descendants from 3rd array
然后,可以将叶权重计算为该叶的祖先节点路径的差值

然后,您需要找到所有叶节点的最小权重

如果您递归地实现它,并保留一个变量
minSoFar
和一个节点副本,以保持树中任何叶上的最小值,那么这并不太困难

一旦这个抽象数据结构在概念上明确了,实现就简单明了了

编辑:此实现具有较小的内存占用(仅调用堆栈),并且应按照与非递归版本相同的复杂度顺序执行。在本页所示的递归和非递归实现中,复杂性由抽象数据结构决定。由于内存占用小,虽然计算时间呈指数增长,但应该可以计算相当深的结构(许多数组)

function recursiveMinDiff(arrays)
{
  var minSoFar, minNodes;

  function computeMinDiff(values)
  {
    var i, vs, total;

    vs = values.slice();
    vs.sort(function (a,b) {      // ascending order
      return a - b;
    });

    total = 0;
    for (i = 0; i < vs.length - 1; i++)
    {
      total += vs[i + 1] - vs[i]; // always non-negative
    }

    return total;
  }

  function mindiff(arrays, stack)
  {
    var i, diff, level;

    level = stack.length;
    if (level === arrays.length)  // this is a leaf
    {
      diff = computeMinDiff(stack);
      if (diff < minSoFar)
      {
        minSoFar = diff;          // side-effect on min*
        minNodes = stack.slice(); // clone array
      }
      return;
    }

    for (i = 0; i < arrays[level].length; i++)
    {
      stack.push(arrays[level][i]);
      mindiff(arrays, stack);
      stack.pop();
    }
  }

  minSoFar = Number.MAX_VALUE;
  minNodes = [];
  mindiff(arrays, []);

  return minNodes;
}
函数递归MindIFF(数组)
{
var minSoFar,minNodes;
函数computeMinDiff(值)
{
var i,vs,总计;
vs=values.slice();
vs.sort(函数(a,b){//升序
返回a-b;
});
总数=0;
对于(i=0;i
您到底要最小化什么?差额的总和是多少?最远元素之间的差异?事实上,我正试图解决我的前一个问题,这就是为什么我需要这个。这三个数组都是元素的位置,所以我希望差异得到它们之间的最短路径。到目前为止,您尝试了什么?请注意StackOverflow是来帮助您编码的,而不是为您编码的。@Burki这不是一个简单的问题。计算最短路径,即使不修剪分支,对于N个数组来说也有点棘手,不是所有开发人员都知道如何编写。谢谢。太棒了。工作正常。现在我将尝试解决我之前的问题。是的,这是我想要的,但我从@denys solution得到了最短路径,现在我使用数学函数得到了最小值和最大值。没关系,这对我来说更像是一个练习:)首先用PHP编写,然后我意识到你需要JS。我将在这里为那些想了解这两种实现的人介绍这一点。
function recursiveMinDiff(arrays)
{
  var minSoFar, minNodes;

  function computeMinDiff(values)
  {
    var i, vs, total;

    vs = values.slice();
    vs.sort(function (a,b) {      // ascending order
      return a - b;
    });

    total = 0;
    for (i = 0; i < vs.length - 1; i++)
    {
      total += vs[i + 1] - vs[i]; // always non-negative
    }

    return total;
  }

  function mindiff(arrays, stack)
  {
    var i, diff, level;

    level = stack.length;
    if (level === arrays.length)  // this is a leaf
    {
      diff = computeMinDiff(stack);
      if (diff < minSoFar)
      {
        minSoFar = diff;          // side-effect on min*
        minNodes = stack.slice(); // clone array
      }
      return;
    }

    for (i = 0; i < arrays[level].length; i++)
    {
      stack.push(arrays[level][i]);
      mindiff(arrays, stack);
      stack.pop();
    }
  }

  minSoFar = Number.MAX_VALUE;
  minNodes = [];
  mindiff(arrays, []);

  return minNodes;
}