Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Непонимание инварианта цикла, на примере сортировки вставкой 
V
    Опции темы
Pretorian
Дата 26.1.2012, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



Здравствуйте уважаемые форумчане!
Имеется алгоритм сортировки вставкой из Кормена
Код

INSERTION-SORT(A)
    for j ← 2 to n
        do key ← A[ j ]
            i ← j − 1
            while i > 0 and A[ i ] > key
                do A[i + 1] ← A[ i ]
                i ← i − 1
            A[i + 1] ← key

при сортировке массива {5, 2, 4, 6, 1, 3}, получаются следующие итерации:
user posted image
, где чёрный квадратик - это элемент с индексом j, серые квадратики - подмассив A[ 1..j - 1]
и белые квадратики соответственно подмассив A[ j+1..n ]
Далее идёт формулировка инвариантов цикла данного алгоритма:
Цитата

В начале каждой итерации цикла for подмассив A[1..j - 1]
содержит те же элементы, которые были в нём с самого начала, но
расположенные в отсортированном порядке.


Инварианты цикла позволяют понять, корректно ли работает алгоритм.
Необходимо показать, что инварианты циклов обладают следующими тремя свойствами.

Инициализация. Они справедливы перед первой инициализацией цикла.
Сохранение. Если они истинны перед очередной итерацией цикла, то остаются
истинны и после неё.
Завершение. По завершении цикла инварианты позволяют убедиться в правильности алгоритма.


И наконец вопрос! smile 
Как я понял, при соблюдении инварианта цикла, в подмассиве A[1..j - 1] в начале и в конце итерации цикла for будут
одни и те же элементы. Но на самом то деле если посмотреть, допустим на итерацию а), на картинке, то видно, что
в начале итерации в ячейке A[1] значение 5, и по завершении цикла в A[1] будет содержаться значение 2, а 5 будет уже
в ячейке A[2].
Так же можно рассмотреть итерацию б) - в начале итерации A[1] = 2, A[2] = 5 (т.е. в подмассиве A[1..j-1] такие значения),
а после окончания итерации A[1] = 2, A[2] = 4 (в подмассиве A[1..j-1] уже другие значения).
Получается что инварианты не соблюдаются??

Объясните пожалуйста, что я не так понял?! И заранее спасибо!
PM   Вверх
_Y_
Дата 27.1.2012, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Что-то на первый взгляд картинка иллустрирует алгоритм пузырьковой сортировки. Или я чего-то спросонья не понимаю?


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Pretorian
Дата 27.1.2012, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



Цитата(_Y_ @  27.1.2012,  13:46 Найти цитируемый пост)
Что-то на первый взгляд картинка иллустрирует алгоритм пузырьковой сортировки. Или я чего-то спросонья не понимаю?

Нет, это именно сортировка вставкой
PM   Вверх
_Y_
Дата 27.1.2012, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Цитата(Pretorian @  27.1.2012,  11:55 Найти цитируемый пост)
Нет, это именно сортировка вставкой 
 

Классные танцы smile  

К сожалению, названия алгоритмов и то, что танцами продемонстрировано - полная путаница. Кликаю "Bubble sort with Hungarian", а вижу алгоруитм попарной перестановки.

Так что, похоже, озаглавленное "Insert sort with Romanian folk dance" на самом деле иллустрирует пузырек в его худшей реализации (в лучшей реализации элементы не переставляются попарно, а "всплывающий" элемент помещается во временную переменную).







--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Pretorian
Дата 27.1.2012, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



Цитата(_Y_ @  27.1.2012,  14:13 Найти цитируемый пост)
Классные танцы

 smile 
Сортировку вставкой сравнивают ещё с сортировкой карт в руке:
user posted image
user posted image
Вот примеры сортировок на Java, вставкой
Код

public static void insertionSort(int[] a) {
        int key, i;
        for (int j = 1; j < a.length; j++) {
            i = j - 1;
            key = a[j];
            while ((i > -1) && (a[i] > key)) {
                a[i + 1] = a[i];
                i--;
            }
            a[i + 1] = key;
        }
    }

и пузырьком
Код

public static void bubbleSort(int[] a) {
        int buf;
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = a.length - 2; j >= i; j--) {
                if (a[j] > a[j + 1]) {
                    buf = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = buf;
                }
            }
        }
    }

может они и похожи, но они разные)
PM   Вверх
_Y_
Дата 27.1.2012, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



О! О чем я и говорю:
Цитата
в начале и левой руке нет ни одной карты

Т.е. сортировка вставкой иллюстрируется "переносом" элементов из одного массива в другой. А в первом посте рисунок иллюстрирует пересортировку одного массива методом пузырька.

В реализации, конечно, можно обойтись одним массивом, но тогда, похоже, эти алгоритмы будут идентичными. Или я все еще не проснулся? Пятница все-таки

Добавлено через 3 минуты и 30 секунд
Что касается кода, то второй код имеет чисто академический смысл т.к. по сравнению с первым ИМХО имеет только недостатки - дополнительные ненужные операции присвоения.


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Pretorian
Дата 27.1.2012, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



при сортировке вставкой, как показано на рисунке в первом посте, "берется карта со стола" (это элемент с индексом j) и сравнивается с "картами в левой руке" (т.е. элементы с меньшим индексом, чем j или ещё можно сказать подмассив A[1..j - 1]). Если A[j] меньше A[j - 1], то сдвигаем A[j - 1] вправо, если A[j] < A[j - 2], то A[j - 2] тоже сдвигаем вправо, т.е. на место A[j - 1] и т.д. пока не дойдём до начала массива или не найдём элемент меньший, чем A[j] и только тогда вставляем A[j] в нужное место. Тем самым подмассив A[1..j - 1] ВСЕГДА (на начало итерации for) отсортирован!

а при пузырьковой сортировке мы таскаем элемент по всему массиву, пока не дойдём до нужного места. Если, допустим самый большой элемент стоит на 1-ом месте, то мы его протащим до конца массива.

да, у этих сортировок сложность примерно одинаковая (O(n^2)), но логика разная....

точнее, если самый маленький элемент на последнем месте, то протащим его на первое место, внутренним циклом for, конечно же smile 

Это сообщение отредактировал(а) Pretorian - 27.1.2012, 13:47
PM   Вверх
_Y_
Дата 27.1.2012, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Мне кажется, мы начали толочь воду в ступе фактически обсуждая сколько ангелов... является ли алгоритм сортировки вставкой алгоритмом сортировки пузырьком

По данному флейму выходит что да, поскольку "таскать элемент по всему массиву" занятие совершенно безсмысленное. Логика, конечно, своя есть, но имеет она смысл чисто академический: типа "а вот можно еще и так извратиться" smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
Pretorian
Дата 27.1.2012, 15:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



да, вобщем неважно кто есть кто... мнеб по моему вопросу лучше)
PM   Вверх
Pretorian
Дата 27.1.2012, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



....кстати, было бы хорошо, если объяснили бы на пальцах про инвариант цикла и показали бы на каких-нибудь простых циклах  smile, типа while(i < 10) i++; хотябы, если это возможно... или вот ещё линейный поиск максимума в массиве, тоже хороший пример...
теории об инвариантах в сети полно, я её уже начитался  smile 
PM   Вверх
Mirkes
Дата 1.2.2012, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 4
Всего: 17



Цитата(Pretorian @ 26.1.2012,  22:40)
Далее идёт формулировка инвариантов цикла данного алгоритма:
Цитата

В начале каждой итерации цикла for подмассив A[1..j - 1]
содержит те же элементы, которые были в нём с самого начала, но
расположенные в отсортированном порядке.


Инварианты цикла позволяют понять, корректно ли работает алгоритм.
Необходимо показать, что инварианты циклов обладают следующими тремя свойствами.

Инициализация. Они справедливы перед первой инициализацией цикла.
Сохранение. Если они истинны перед очередной итерацией цикла, то остаются
истинны и после неё.
Завершение. По завершении цикла инварианты позволяют убедиться в правильности алгоритма.


И наконец вопрос! smile 
Как я понял, при соблюдении инварианта цикла, в подмассиве A[1..j - 1] в начале и в конце итерации цикла for будут
одни и те же элементы. Но на самом то деле если посмотреть, 

Итак Вы предложили  объяснить инварианты цикла на двух примерах:
сортировки и поиска максимума в массиве.

Начнем со второго.
сначала код (возможно не оптимальный но для примера сойдет)
Код

      int[] arr = {1,3,2,6,3,5,7,3}
      int max=arr[0];    // Инициация! с этого момента можно говорить об инварианте
      for (int i=1;i<arr.length;i++){
         if (max<arr[i])
            max=arr[i];
      }

Инвариант: max содержит максимум элементов от 0 до текущего.
1. проверяем корректность Первое значение в цикле БУДЕТ 1. Значит текущее 0 ДО НАЧАЛА ЦИКЛА max СОДЕРЖИТ МАКСИМУМ ОТРЕЗКА ОТ 0 ДО 0. Верно.
2. Если инвариант справедлив ПЕРЕД итерацией то он справедлив и после нее.
итерация начинается с ИЗМЕНЕНИЯ ПЕРЕМЕННОЙ ЦИКЛА. Таким образом перед итерацией k значение i==k-1. и max содержит максмум на отрезке от 0 до k-1. 
изменяем i++ теперь i=k. после выполнения ТЕЛА цикла в переменной max содержится максимум значения участка от 0 до k. все верно. 
Из 1 и 2 следует утверждение, что после завершения цикла в переменной max будет максимум всего массива.

Теперь сортировка.
Инвариант. На шаге j отрезок массива от 1 до j отсортирован.
проверяем.
ДО ЦИКЛА j=1. Один элемент очевидно отсортирован. Верно.
на начало итерации с j=k значение j очевидно равно k-1. Если массив на отрезке от 1 до k-1 отсортирован, то после выполнения ИЗМЕНЕНИЯ ПЕРЕМЕННОЙ ЦИКЛА и ТЕЛА ЦИКЛА отсортирован будет отрезок  от 1 до k. верно.

Значит и весь алгоритм сортировки верен.

Основная ваша ошибка состоит в том, что вы неправильно определили итерацию цикла. Она либо начинается, либо заканчивается изменением переменной цикла.


--------------------
Mirkes
PM MAIL   Вверх
Pretorian
Дата 2.2.2012, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 57
Регистрация: 9.12.2011
Где: нигде

Репутация: нет
Всего: 1



Большое спасибо Mirkes, за хороший ответ! Поставил бы +, но жаль не могу  smile 
PM   Вверх
1000000dollars
Дата 2.2.2012, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 231
Регистрация: 6.10.2007

Репутация: 1
Всего: 8



Pretorian, не переживай, я ему плюс поставил smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0822 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.