Сортировка перестановки с минимальной стоимостью
Мне дается перестановка элементов {1, 2, 3, ..., N}
, и мне приходится сортировать ее с помощью операции свопинга. Операция, которая меняет элементы x, y, имеет стоимость min (x, y).
Мне нужно узнать минимальную стоимость сортировки перестановки. Я жаловался на жадность, идущую от N
до 1
и помещая каждый элемент в это положение с помощью операции свопинга, но это не очень хорошая идея.
Ответы
Ответ 1
Будет ли это оптимальным:
Find element 2
If it is not at correct place already
Find element at position 2
If swapping that with 2 puts both to right place
Swap them
Cost = Cost + min(2, other swapped element)
repeat
Find element 1
If element 1 is at position 1
Find first element that is in wrong place
If no element found
set sorted true
else
Swap found element with element 1
Cost = Cost + 1
else
Find element that should go to the position where 1 is
Swap found element with element 1
Cost = Cost + 1
until sorted is true
Ответ 2
Если поиски тривиальны, то минимальное количество свопов будет определяться количеством циклов. Он будет следовать принципу, аналогичному Cuckoo Hashing. Вы берете первое значение в перестановке и смотрите значение в индексе значения в исходном индексе. Если они совпадают, замените их на одну операцию.
[ 3 2 1]: значение 3 относится к индексу один, поэтому посмотрите на значение в индексе 3.
[3 2 1]: значение 1 находится в индексе 3, поэтому существует два цикла индекса. Поменяйте эти значения.
Если нет, нажмите первый индекс на стек и найдите индекс для значения второго индекса. В итоге будет цикл. В этот момент начните замену, выбирая значения из стека. Это займет несколько свопов, равных n-1, где n - длина цикла.
[ 3 1 2]: значение 3 относится к индексу один, поэтому посмотрите на значение в индексе 3.
[3 1 2]: значение 2 находится в индексе 3, поэтому добавьте 3 в стек и найдите индекс 2. Также сохраните 3 как начальное значение цикла.
[3 1 2]: значение 1 находится в индексе 2, поэтому добавьте 2 в стек и попробуйте индексировать 1.
[ 3 1 2]: значение 3 - начало цикла, поэтому swap pop 2 укладывается в стек и меняет значения 1 и 2.
[1 3 2]: поп 3 со стека и свопинг 2 и 3, в результате получается отсортированный список с 2 свопами.
[1 2 3]
При таком алгоритме максимальное число свопов будет N-1, где N - общее количество значений. Это происходит, когда существует цикл N длины.
EDIT: Этот алгоритм дает минимальное количество свопов, но не обязательно минимальное значение, используя функцию min (x, y). Я не сделал математику, но считаю, что единственное время, когда swap (x, y) = {swap (1, x), swap (1, y), swap (1, x)} не следует использовать когда x в {2,3} и n < 2; Должно быть достаточно легко написать это как особый случай. Может быть, лучше проверить и поместить 2 и 3 явно, затем следовать алгоритму, упомянутому в комментариях, для достижения сортировки в двух операциях.
РЕДАКТИРОВАТЬ 2: Довольно уверен, что это поймает все случаи.
while ( unsorted ) {
while ( 1 != index(1) )
swap (1 , index (1) )
if (index(2) == [email protected](2))
swap (2, [email protected](2) )
else
swap (1 , highest value out of place)
}
Ответ 3
Если у вас есть перестановка чисел 1, 2,..., N, то отсортированная коллекция будет точно 1, 2,..., N. Итак, вы знаете ответ с сложность O (0) (т.е. вам вообще не нужен алгоритм).
Если вы действительно хотите отсортировать диапазон путем повторной замены, вы можете повторно "продвигать и циклировать": продвигайтесь по уже отсортированному диапазону (где a[i] == i
), а затем меняйте a[i]
на a[a[i]]
, пока не закончите цикл. Повторяйте, пока не достигнете конца. Для этого требуется не более n 1 swaps и в основном выполняет циклическое разложение перестановки.
Ответ 4
Хм. Интересный вопрос. Быстрый алгоритм, который пришел мне на ум, - использовать элементы в качестве индексов. Сначала мы найдем индекс элемента, который имеет 1 в качестве значения, и замените его на элемент этого числа. В конце концов, это закончится тем, что 1 появится в первой позиции, это означает, что вам нужно поменять номер 1 с каким-то элементом, который еще не находится в позиции, и продолжить. Это вершина на 2 * N-2 и имеет нижний предел для N-1 для перестановки (2,3,..., N, 1), но точная стоимость будет отличаться.
Хорошо, учитывая приведенный выше алгоритм и примеры, я думаю, что наиболее оптимальным будет следовать обмен 1 с чем угодно, пока он первым не нападет первым, а затем замените 2 на второе место, если он уже не на месте, а затем продолжите замену 1 с все еще не на месте, пока не будет отсортировано.
set sorted=false
while (!sorted) {
if (element 1 is in place) {
if (element 2 is in place) {
find any element NOT in place
if (no element found) sorted=true
else {
swap 1 with element found
cost++
}
} else {
swap 2 with element at second place
cost+=2
}
} else {
find element with number equals to position of element 1
swap 1 with element found
cost++
}
}
Ответ 5
Использовать сортировку ведра с размером ведра 1.
Стоимость равна нулю, так как нет свопов.
Теперь сделайте проход через массив ведра и замените каждое значение обратно на соответствующую позицию в исходном массиве.
Это N свопов.
Сумма N равна N (N + 1)/2, что дает вам фиксированную стоимость.
Другая интерпретация заключается в том, что вы просто сохраняете из массива ведро, обратно в исходный массив. Это не свопы, поэтому стоимость равна нулю, что является разумным минимумом.