Я экспериментировал с множеством разных подходов, вот чем я и закончил. Основная идея состоит в том, чтобы назначить хорошие, действительные значения массиву ожидаемых значений. Значения, которые не могут быть назначены, исправляются путем использования отсутствующих ожидаемых значений.
Приведен список фактических данных peaks
.
Построить список ожидаемых данных
var expected = Enumerable
// 19 is the known number of values
.Range (0, 19)
// simply interpolate over the actual data
.Select (x => peaks.First () + x * (peaks.Last () - peaks.First ()) / 18)
.ToList ();
Построить матрицу расстояний всех точек
var distances = expected.SelectMany (dst => peaks.Select (src => new {
Expected = dst,
Original = src,
Distance = Math.Abs (dst - src)
}));
Повторите
for (;;)
{
Выберите лучшее расстояние
var best = distances
// ignore really bad values
.Where (x => x.Distance < dAvgAll * 0.3)
.OrderBy (x => x.Distance).FirstOrDefault ();
Если подходящее назначение не найдено, выйдите из системы
if (best == null) {
break;
}
Остальное, храни спичку
expected.Remove (best.Expected);
peaks.Remove (best.Original);
}
Все действительные записи в нашем источнике были идентифицированы и удалены. Мы просто используем оставшиеся значения в ожидаемом наборе и игнорируем оставшиеся исходные значения, чтобы завершить наш окончательный набор данных.
Другие попытки, включая версию, адаптированную к gusbro, работали хуже и часто показывали мне плохое поведение.