我有一系列测量,例如:
测量#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.
在要创建的测量中创建每个元素的事件受到人类行为的影响。
感谢您的帮助:)
答案 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>
以上只是一个例子,它归结为上下文。你的数据有噪音吗?如何“嘈杂”,中间有额外的元素,开始或结束或略微偏离位置?加上大量其他问题。
选择和实现模糊算法的范围可以很容易,几乎不可能完全取决于上下文以及您将使用的结果。它需要准确还是“足够好”。是否需要快速等等。