Что такое инвариант цикла? - PullRequest
248 голосов
/ 11 июля 2010

Я читаю "Введение в алгоритм" от CLRS. В главе 2 авторы упоминают «петлевые инварианты». Что такое инвариант цикла?

Ответы [ 15 ]

1 голос
/ 09 сентября 2015

Трудно отслеживать, что происходит с петлями. Циклы, которые не заканчиваются или не заканчиваются без достижения их целевого поведения, являются распространенной проблемой в компьютерном программировании. Помогают инварианты петли. Инвариант цикла - это формальное утверждение о связи между переменными в вашей программе, которое сохраняется как раз перед тем, как цикл запускается (установление инварианта), и снова становится истинным в нижней части цикла, каждый раз через цикл (поддерживая инвариант ). Вот общая схема использования инвариантов цикла в вашем коде:

... // Инвариант цикла должен быть истинным
while (СОСТОЯНИЕ ИСПЫТАНИЯ) {
// вершина цикла
...
// нижняя часть цикла
// Здесь инвариант цикла должен быть истинным
}
// Завершение + Цикл Инвариант = Цель
...
Между верхом и низом петли, по-видимому, продвигается движение к достижению цели петли. Это может нарушить (сделать ложным) инвариант. Суть инвариантов цикла - это обещание, что инвариант будет восстановлен перед повторением тела цикла каждый раз. В этом есть два преимущества:

Работа не переносится на следующий этап сложными, зависящими от данных способами. Каждый проход по циклу не зависит от всех остальных, а инвариант служит для связывания проходов в рабочее целое. Рассуждение о том, что ваш цикл работает, сводится к рассуждению о том, что инвариант цикла восстанавливается при каждом прохождении цикла. Это разбивает сложное общее поведение цикла на маленькие простые шаги, каждый из которых может рассматриваться отдельно. Условие проверки цикла не является частью инварианта. Это то, что заставляет цикл завершаться. Вы рассматриваете отдельно две вещи: почему цикл должен когда-либо завершаться, и почему цикл достигает своей цели, когда завершается. Цикл завершится, если каждый раз через цикл вы будете приближаться к выполнению условия завершения. Это часто легко гарантировать: например, пошаговое изменение переменной счетчика на единицу, пока не будет достигнут фиксированный верхний предел Иногда рассуждение о прекращении труднее.

Инвариант цикла должен быть создан таким образом, чтобы при достижении условия завершения и инварианте true, тогда была достигнута цель:

инвариант + окончание => цель
Требуется практика для создания простых и взаимосвязанных инвариантов, которые охватывают все достижения цели, кроме завершения. Лучше всего использовать математические символы для выражения инвариантов цикла, но когда это приводит к слишком сложным ситуациям, мы полагаемся на ясную прозу и здравый смысл.

0 голосов
/ 10 октября 2018

Инвариант цикла - это утверждение, которое верно до и после выполнения цикла.

0 голосов
/ 28 октября 2017

Проще говоря, это условие LOOP, которое выполняется в каждой итерации цикла:

for(int i=0; i<10; i++)
{ }

В этом мы можем сказать, что состояние i равно i<10 and i>=0

0 голосов
/ 27 августа 2015

При линейном поиске (согласно упражнению, приведенному в книге) нам нужно найти значение V в данном массиве.

Это просто, как сканирование массива с 0 <= k <length и сравнение каждого элемента. Если V найдено или если сканирование достигает длины массива, просто завершите цикл. </p>

Согласно моему пониманию в вышеупомянутой проблеме -

Инварианты цикла (инициализация): V не найден в k - 1 итерации. Самая первая итерация, это будет -1, поэтому мы можем сказать, что V не найден в позиции -1

коммунальный: В следующей итерации V, не найденное в k-1, выполняется

Terminatation: Если V находится в позиции k или k достигает длины массива, завершите цикл.

0 голосов
/ 30 мая 2015

Инвариант цикла - это математическая формула, такая как (x=y+1).В этом примере x и y представляют две переменные в цикле.Учитывая изменяющееся поведение этих переменных во время выполнения кода, практически невозможно протестировать все возможные значения x и y и посмотреть, не вызывают ли они какую-либо ошибку.Допустим, x является целым числом.Целое число может содержать 32-битное пространство в памяти.Если это число превышает, происходит переполнение буфера.Поэтому мы должны быть уверены, что на протяжении всего выполнения кода он никогда не превышает это пространство.для этого нам нужно понять общую формулу, которая показывает связь между переменными.В конце концов, мы просто пытаемся понять поведение программы.

...