Я ищу алгоритм сортировки, который оценивает минимальный и максимальный диапазон для каждого элемента 1. Проблемная область - это механизм рекомендаций, который объединяет набор бизнес-правил (ограничений) с оценочной оценкой (значением). Если у нас есть рекомендация, которую мы хотим рекламировать (например, специальный продукт или сделку) или объявление, которое мы хотим увидеть в верхней части списка (например, "Это очень важно, не забудьте подтвердить свой адрес электронной почты для участия в предстоящей акции!" ) или в нижней части списка (например, "Если вам понравились эти рекомендации, нажмите здесь для получения дополнительной информации" ), они будут куратором с определенным ограничением положения на месте. Например, это всегда должно быть верхнее положение, они должны быть в верхней части 10 или середине 5 и т.д. Этот шаг заготовки выполняется заранее и остается фиксированным в течение заданного периода времени, а по соображениям бизнеса должен оставаться очень гибким.
Пожалуйста, не ставьте под сомнение цель бизнеса, пользовательский интерфейс или проверку ввода. Я просто пытаюсь реализовать алгоритм в ограничениях, которые мне даны. Пожалуйста, рассматривайте это как академический вопрос. Я постараюсь дать строгую постановку проблемы, и обратная связь по всем остальным аспектам проблемы очень приветствуется.
Итак, если бы мы сортировали char
s, наши данные имели бы структуру
struct {
char value;
Integer minPosition;
Integer maxPosition;
}
Где minPosition
и maxPosition
могут быть нулевыми (неограниченными). Если бы это было вызвано алгоритмом, где все ограничения позиций были нулевыми, или все minPosition
были равны 0 или меньше, а все maxPositions
были равны или превосходили размер списка, тогда выход был бы только char
в по возрастанию.
Этот алгоритм будет переупорядочивать только два элемента, если бы те minPosition
и maxPosition
обоих элементов не были бы нарушены их новыми позициями. Алгоритм, основанный на вставке, который продвигает элементы в верхней части списка и переупорядочивает остальную часть, имеет очевидные проблемы в том, что каждый последующий элемент должен быть проверен после каждой итерации; в моей голове, что исключает такие алгоритмы для сложности O (n 3), но я не исключаю таких алгоритмов, не рассматривая доказательства обратного, если они представлены.
В выходном списке некоторые элементы будут не в порядке относительно их значения, тогда и только тогда, когда это задает набор ограничений по положению. Эти выходы по-прежнему действительны.
- A действительный список - это любой список, в котором все элементы находятся в позиции, которая не противоречит их ограничениям.
- Список оптимальный - это список, который нельзя переупорядочить, чтобы более точно соответствовать естественному порядку, не нарушая одно или несколько ограничений позиции. Недопустимый список никогда не является оптимальным. У меня нет строгого определения, которое я могу описать для "более близкого соответствия" между одним заказом. Тем не менее, я думаю, что довольно легко позволить интуиции направлять вас или выбрать что-то похожее на показатель расстояния.
Несколько оптимальных порядков могут существовать, если несколько входов имеют одинаковое значение. Вы можете сделать аргумент, что приведенный выше абзац поэтому неверен, потому что любой может быть переупорядочен другому, не нарушая ограничений, и поэтому ни один из них не может быть оптимальным. Однако любая строгая дистанционная функция будет рассматривать эти списки как идентичные с тем же расстоянием от естественного порядка и, следовательно, допускается переупорядочение одинаковых элементов (поскольку это не-op). Я бы назвал такие выходы правильным, отсортированным порядком, который учитывает ограничения позиции, но несколько комментаторов указали, что мы действительно не возвращаем отсортированный список, поэтому давайте придерживаться "оптимального".
Например, следующие списки входных данных (в форме <char>(<minPosition>:<maxPosition>)
, где Z(1:1)
указывает a Z
, который должен быть в начале списка, а M(-:-)
обозначает M
, который может быть в любой позиции в конечном списке, а естественный порядок (отсортированный по значению) - A...M...Z
) и их оптимальные порядки.
Input order
A(1:1) D(-:-) C(-:-) E(-:-) B(-:-)
Optimal order
A B C D E
Это тривиальный пример, показывающий, что естественный порядок преобладает в списке без ограничений.
Input order
E(1:1) D(2:2) C(3:3) B(4:4) A(5:5)
Optimal order
E D C B A
В этом примере показано, что полностью ограниченный список выводится в том же порядке, в котором он задан. Вход уже является действительным и оптимальнымсписок. Алгоритм должен продолжать работать в O (n log n) времени для таких входов. (Наше начальное решение способно коротко закоротить любой полностью ограниченный список для запуска в линейном времени, я добавил пример как для определения целей оптимального и действительного, так и из-за того, что некоторые алгоритмы подкачки, которые я рассматривал, рассматривали как худший случай. )
Input order
E(1:1) C(-:-) B(1:5) A(4:4) D(2:3)
Optimal Order
E B D A C
E
привязан к 1:1
, поэтому он является первым в списке, хотя он имеет самое низкое значение. A
аналогично ограничено 4:4
, поэтому оно также выходит из естественного порядка. B
имеет по существу одинаковые ограничения для C
и может появляться в любом месте в конечном списке, но B
будет перед C
из-за значения. D
может находиться в позициях 2 или 3, поэтому он появляется после B
из-за естественного упорядочения, но до C
из-за его ограничений.
Обратите внимание, что окончательный порядок верен, несмотря на то, что он дико отличается от естественного порядка (который все еще A
, B
, C
, D
, E
). Как объяснялось в предыдущем абзаце, ничто в этом списке не может быть переупорядочено без нарушения ограничений одного или нескольких элементов.
Input order
B(-:-) C(2:2) A(-:-) A(-:-)
Optimal order
A(-:-) C(2:2) A(-:-) B(-:-)
C
остается невозмутимым, поскольку он уже находится в единственном действительном положении. B
переупорядочивается до конца, потому что его значение меньше, чем A
. На самом деле, будут дополнительные поля, которые различают два A
, но с точки зрения алгоритма они идентичны и сохраняют ИЛИ, изменяя их порядок ввода, является оптимальным решением.
Input order
A(1:1) B(1:1) C(3:4) D(3:4) E(3:4)
Undefined output
Этот вход недействителен по двум причинам: 1) A
и B
оба ограничены положением 1 и 2) C
, D
и E
ограничены диапазоном, чем может удерживаться только 2 элемента. Другими словами, диапазоны 1:1
и 3:4
чрезмерно ограничены. Тем не менее, согласованность и законность ограничений выполняются с помощью проверки UI, поэтому официально это не проблема алгоритмов, если они являются неправильными, и алгоритм может возвращать наилучший порядок или исходный порядок в этом случае. Передача такого типа в алгоритм можно рассматривать как undefined поведение; все может случиться. Итак, для остальной части вопроса...
- Все входные списки будут содержать элементы, которые изначально находятся в допустимых позициях.
- Сам алгоритм сортировки может считать, что ограничения действительны и существует оптимальный порядок. 2
В настоящее время мы установили индивидуальную сортировку (со сложностью выполнения O (n 2)) и обоснованно доказал, что он работает для всех входов, ограничения по которым действительны и согласованы (например, нет забронированы для заданной позиции или диапазона позиций).
Существует ли алгоритм сортировки, который гарантированно вернет оптимальный конечный порядок и будет работать быстрее, чем O (n 2). 3
Я чувствую, что стандартный алгоритм сортировки библиотеки может быть изменен для обработки этих ограничений путем предоставления настраиваемого компаратора, который принимает позицию назначения кандидата для каждого элемента. Это было бы эквивалентно текущей позиции каждого элемента, поэтому, возможно, изменив класс удерживания значения, чтобы включить текущую позицию элемента, и выполнить дополнительный учет в сравнении (.equals()
), и методы подкачки будут достаточными.
Однако, чем больше я думаю об этом, алгоритм, который работает в O (n log n), не может работать корректно с этими ограничениями. Интуитивно, такие алгоритмы основаны на выполнении n сравнений log n раз. Log n достигается за счет использования механизма разделения и покоя, который сравнивает только определенные кандидаты для определенных позиций.
Другими словами, для любого алгоритма сортировки O (n log n) существуют списки ввода с допустимыми ограничениями позиции (например, контрпримеры), где элемент-кандидат сравнивается с элементом (или диапазоном в случае Quicksort и вариантов) с/к которым он не может быть заменен, и поэтому никогда не переместится в правильную конечную позицию. Если это слишком расплывчато, я могу придумать встречный пример для mergesort и quicksort.
Напротив, алгоритм сортировки O (n 2) делает исчерпывающие сравнения и всегда может перенести элемент в его правильную конечную позицию.
Чтобы задать реальный вопрос:Является ли моя интуиция правильной, когда я полагаю, что сортировка O (n log n) не гарантируется для нахождения действительного порядка? Если да, можете ли вы предоставить более конкретные доказательства? Если нет, почему бы и нет? Существуют ли другие существующие исследования по этому классу проблем?
1: мне не удалось найти набор условий поиска, которые указывают мне на какую-либо конкретную классификацию такого алгоритма сортировки или ограничений; поэтому я задаю некоторые основные вопросы о сложности. Если есть термин для этого типа проблемы, отправьте его.
2: Валидация - отдельная проблема, достойная собственного исследования и алгоритма. Я уверен, что существование допустимого порядка может быть доказано в линейном времени:
- Выделить массив кортежей длины, равный вашему списку. Каждый кортеж представляет собой целочисленный счетчик k и двойное значение v для относительного веса присваивания.
- Пройдите список, добавив дробное значение каждого ограничения позиции элемента к соответствующему диапазону и увеличив его счетчик на 1 (например, диапазон 2: 5 в списке из 10 добавляет 0,4 к каждой из 2,3,4 и 5 в нашем списке кортежей, увеличивая счетчик каждого также)
- Пройдите список кортежей и
- Если ни одна запись не имеет значения v больше суммы ряда от 1 до k 1/k, существует действительный порядок.
- Если есть такой кортеж, позиция, в которой он находится, является чрезмерной; вызывать исключение, регистрировать ошибку, использовать массив удвоений для исправления элементов проблемы и т.д.
Изменить:. Этот алгоритм проверки фактически является O (n 2). В худшем случае каждый элемент имеет ограничения 1:n
, вы в конечном итоге переходите свой список из n кортежей n раз. Это по-прежнему не имеет отношения к сфере действия вопроса, поскольку в реальной проблемной области ограничения выполняются один раз и не изменяются.
Определение того, что данный список в правильном порядке еще проще. Просто проверьте текущую позицию каждого элемента на его ограничения.
3: Это, по общему признанию, немного преждевременная оптимизация. Наше первоначальное использование для этого - для довольно небольших списков, но мы смотрим на расширение до более длинных списков, поэтому, если мы сможем оптимизировать сейчас, мы получим небольшой прирост производительности и большую производительность. И кроме того, мое любопытство вызвано, и если есть какие-то исследования по этой теме, я хотел бы увидеть это и (надеюсь) узнать из него.