РЕДАКТИРОВАТЬ : Вау, много хороших ответов. Да, я использую это как функцию пригодности для оценки качества сортировки, выполняемой генетическим алгоритмом. Таким образом, стоимость оценки важна (то есть она должна быть быстрой, предпочтительно O(n)
.)
Как часть приложения ИИ, с которым я играю, я бы хотел иметь возможность оценивать массив целых чисел-кандидатов на основе его монотонности, то есть его "сортировки". На данный момент я использую эвристику, которая вычисляет самый длинный отсортированный прогон, а затем делит его на длину массива:
public double monotonicity(int[] array) {
if (array.length == 0) return 1d;
int longestRun = longestSortedRun(array);
return (double) longestRun / (double) array.length;
}
public int longestSortedRun(int[] array) {
if (array.length == 0) return 0;
int longestRun = 1;
int currentRun = 1;
for (int i = 1; i < array.length; i++) {
if (array[i] >= array[i - 1]) {
currentRun++;
} else {
currentRun = 1;
}
if (currentRun > longestRun) longestRun = currentRun;
}
return longestRun;
}
Это хорошее начало, но оно не учитывает вероятность того, что могут быть "скопления" отсортированных подпоследовательностей. E.g.:
{ 4, 5, 6, 0, 1, 2, 3, 7, 8, 9}
Этот массив разделен на три отсортированные подпоследовательности. Мой алгоритм оценит его как отсортированный только на 40%, но интуитивно он должен получить более высокий балл, чем этот. Существует ли стандартный алгоритм для такого рода вещей?