找到最接近某一测量值的测量算法

时间:2015-08-14 12:59:05

标签: algorithm dynamic-programming


我有一系列测量,例如:
测量#1:{200,350,712,1023,1430,1555,1800,2036,2569}
测量#2:{165,400,974,1124,1600,1893,1919,2032,2654,2932}
...
测量#N:{234,454,879,1432,1877,2000,2543,2876}

每个测量中元素的顺序很重要 每个元素的价值都高于前一个元素 每个测量中的元素数量可能不同,
但它们不应该变化很大。

现在我作为一个输入得到一个新的测量 (让我们说:{212,354,978,1222,1454,1922,2013,2432,2987})
并且应该从我已经拥有的测量集合中找到最接近的测量值。

我的问题是我应该使用什么算法来完成这项任务?

更多:
1.也可以在这样的肉食中扩展任务,相反输入一个测量值,我会得到一小部分测量值。
2.测量中的每个元素代表从开始到第二个时间的时间 当测量值达到3600秒(1小时)时停止测量,因此最小可能值为0,最大值为3599.
在要创建的测量中创建每个元素的事件受到人类行为的影响。

感谢您的帮助:)

2 个答案:

答案 0 :(得分:0)

使用集合中的每个度量值找出新度量的平方误差总和。然后以最小的错误返回集合中的那个。

var measures = [
 [1, 2, 3, 4],
 [10, 20, 30, 40],
 [66, 77, 88, 99],
 [101, 202, 303, 404]
];

// ignores measurements that aren't the same length as the data
// uses the squared sum of differences (errors)
function findClosest(data) {
  var minError = 0x7FFFFFFF; // max 32bit signed int
  var result = null;
  for(var i=0; i < measures.length; i++) {
    if(data.length !== measures[i].length) { continue; }
    var error = 0;
    for(var j=0; j < data.length; j++) {
      error += Math.pow(measures[i][j] - data[j], 2);
    }
    if(error < minError) {
      minError = error;
      result = measures[i];
    }
  }
  return result;
}

// allows data that is different length than measurements by trying to best fit each element of data to an element of the tested measurement
// uses the squared sum of differences (error)
function findClosestV2(data) {
  var minError = 0x7FFFFFFF; // max 32bit signed int
  var result = null;
  for(var i=0; i < measures.length; i++) {
    var measure = measures[i];
    var error = 0;
    var minLocalError = 0x7FFFFFFF;
    for(var j=0; j < data.length; j++) {
      for(var k=0; k < measure.length; k++) {
        var localError = Math.pow(measure[k] - data[j], 2);
        if(localError < minLocalError) {
          minLocalError = localError;
        }
      }
      error += minLocalError;
    }
    if(error < minError) {
      minError = error;
      result = measures[i];
    }
  }
  return result;
}

// allows data that is different length than measurements by trying to best fit each element of data to an element of the tested measurement
// uses the average of the absolute error % using the previous measurement as the ideal value
function findClosestV3(data) {
  var minError = 0x7FFFFFFF; // max 32bit signed int
  var result = null;
  for(var i=0; i < measures.length; i++) {
    var measure = measures[i];
    var error = 0;
    var minLocalError = 0x7FFFFFFF;
    for(var j=0; j < data.length; j++) {
      for(var k=0; k < measure.length; k++) {
        var localError = Math.abs( (measure[k] - data[j]) / measure[k] );
        if(localError < minLocalError) {
          minLocalError = localError;
        }
      }
      error += minLocalError;
    }
    // average of sum of error percentages
    error /= data.length;
    if(error < minError) {
      minError = error;
      result = measures[i];
    }
  }
  return result;
}

console.log(findClosest([2,3,4,5])); // [1,2,3,4]
console.log(findClosest([70,80,90,100])); // [66,77,88,99]
console.log(findClosest([9,19,304,405])); // [101,202,303,404]

console.log(findClosestV2([404])); // [101,202,303,404]
console.log(findClosestV2([66,67,68,69])); // [66,77,88,99]
console.log(findClosestV2([9,19,304,405])); // [10,20,30,40]

console.log(findClosestV3([404])); // [101,202,303,404]
console.log(findClosestV3([66,67,68,69])); // [66,77,88,99]
console.log(findClosestV3([9,19,304,405])); // [10,20,30,40]

答案 1 :(得分:0)

假设您的数据“模糊”,您可能想要研究的一类算法是dynamic programming。通过模糊我的意思是两组几乎对齐,但是一组可能插入额外的元素,与另一组相比被移除,匹配元素“几乎”匹配。

在这些类型的算法中,您通常通过定义在对齐中插入/移除元素的惩罚来定义距离分数,并且对于不完全匹配的两个元素的惩罚分数来定义距离分数。 在您的情况下,您可以定义插入/删除罚分“100”秒以插入额外的计时事件,并将两元素距离分数定义为绝对距离(秒)。 根据该定义,您可以轻松找到并修改needleman-wunsch算法实现或类似的东西。这将在可接受的时间内为您提供两组小测量之间的距离。 但是,如果您的测量中的元素数量很大或者集合的数量很大,并且您需要毫秒级的答案,那么这是一个相当困难的问题,除非您能为您的问题找到很多好的约束。 / p>

以上只是一个例子,它归结为上下文。你的数据有噪音吗?如何“嘈杂”,中间有额外的元素,开始或结束或略微偏离位置?加上大量其他问题。

选择和实现模糊算法的范围可以很容易,几乎不可能完全取决于上下文以及您将使用的结果。它需要准确还是“足够好”。是否需要快速等等。