Відповіді:
Інваріант є більш «концептуальним», ніж змінною. Взагалі, це властивість стану програми, що завжди відповідає дійсності. Функція або метод, який забезпечує, що інваріант має місце, як кажуть, підтримує інваріант.
Наприклад, бінарне дерево пошуку може бути інваріантним, що для кожного вузла ключ лівої дочірки вузла менше, ніж власний ключ вузла. Правильно написана функція вставки для цього дерева підтримуватиме цю інваріантність.
Як ви можете сказати, це не та річ, яку ви можете зберігати в змінній: це більше твердження про програму. З'ясувавши, який тип інваріантів має підтримувати ваша програма, переглянувши ваш код, щоб переконатися, що він фактично підтримує ці інваріанти, ви зможете уникнути логічних помилок у своєму коді.
Я зазвичай розглядаю їх більше з точки зору алгоритмів чи структур.
Наприклад, у вас може бути інваріант циклу, який можна стверджувати - завжди вірно на початку або в кінці кожної ітерації. Тобто, якщо ваш цикл повинен був обробити колекцію об'єктів з однієї стеки в іншу, ви можете сказати, що | stack1 | + | stack2 | = c, вгорі або внизу циклу.
Якщо інваріантна перевірка не вдалася, це вказувало б, що щось пішло не так. У цьому прикладі це може означати, що ви забули натиснути оброблений елемент на остаточний стек тощо.
Магія вікіпедії: Інваріант (інформатика)
В інформатиці присудок, який, якщо це правда, залишиться істинним протягом певної послідовності операцій, називається (ін) інваріантним для цієї послідовності.
Як зазначено у цьому рядку:
В інформатиці присудок, який, якщо це правда, залишиться істинним протягом певної послідовності операцій, називається (ін) інваріантним для цієї послідовності.
Щоб краще зрозуміти цю надію, цей приклад на C ++ допомагає.
Розглянемо сценарій, коли потрібно отримати деякі значення та отримати їх загальну кількість у змінній, що називається як, count
і додати їх у змінну, що називається якsum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
Код для вищезазначеного був би приблизно таким,
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
Що робить вищевказаний код?
1) Прочитає вхідні дані cin
та додає їхx
2) Після одного успішного читання, збільшення count
таsum = sum + x
3) Повторюйте 1-2, поки читання не зупиниться (тобто ctrl + D)
Іваріант повинен бути ІСТИНИМ ЗАВЖДИ . Тож спочатку ви починаєте свій код саме з цього
while(cin>>x){
}
Цей цикл зчитує дані зі стандартного введення та зберігає у x. Ну і добре. Але інваріант стає хибним, оскільки перша частина нашого інваріанта не дотримувалася (або зберігалася правдою).
// we have read count grades so far, and
Просто! приріст кол.
Так ++count;
би добре! Тепер наш код стає приблизно таким,
while(cin>>x){
++count;
}
Навіть зараз наш інваріант (поняття, яке повинно бути ПРАВИЛЬНИМ) є помилковим, оскільки зараз ми не задовольнили другу частину нашого інваріанта.
// sum is the sum of the first count grades
То що тепер робити?
Додайте x
до sum
і збережіть його у sum
( sum+=x
), і наступного разу
cin>>x
прочитаєте нове значення у x.
Тепер наш код стає приблизно таким,
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
код:
while(cin>>x){
++count;
sum+=x;
}
Ах !. Тепер цикл інваріантний "Істинний завжди" і код працює нормально.
Наведений вище приклад взяли та модифікували з книги « Прискорений C ++ » Ендрю-Конінг та Барбара-Е
Виходячи з того, що це таке, інваріанти досить корисні при написанні чистого коду, оскільки концептуально знання того, які інваріанти повинні бути присутніми у вашому коді, дозволяє вам легко вирішити, як організувати свій код для досягнення цих цілей. Як уже згадувалося, вони також корисні при налагодженні, оскільки перевірка того, чи підтримується інваріант, часто є хорошим способом побачити, чи будь-яка маніпуляція, яку ви намагаєтеся виконати, насправді робить те, що ви хочете.
Зазвичай це величина, яка не змінюється за певних математичних операцій. Прикладом є скаляром, який не змінюється при поворотах. Наприклад, у магнітно-резонансній томографії корисно характеризувати властивість тканини за допомогою обертального інваріанта, оскільки тоді її оцінка в ідеалі не залежить від орієнтації тіла в сканері.
Ця відповідь для моєї 5-річної дитини. Не думайте про інваріант як про постійне чи фіксоване числове значення. Але це може бути. Однак це більше того.
Швидше, інваріант - це щось на зразок фіксованих відносин між різними сутностями. Наприклад, ваш вік завжди буде меншим, ніж у порівнянні з вашими біологічними батьками. І ваш вік, і вік вашого батька змінюються з часом, але відносини, про які я згадував вище, інваріантні.
Інваріант також може бути числовою константою. Наприклад, значення pi
- інваріантне відношення між окружністю кола над його діаметром. Незалежно від того, наскільки велике чи маленьке коло, це співвідношення завжди буде pi
.
Інваріант ADT визначає зв'язки між полями даних (змінні екземпляра), які завжди повинні бути істинними до та після виконання будь-якого методу екземпляра.
Є чудовий приклад інваріанта і чому це має значення в книзі Java Concurrency in Practice .
Хоча орієнтований на Java, у прикладі описано деякий код, який відповідає за обчислення факторів поданого цілого числа. Приклад коду намагається кешувати останнє надане число та фактори, які були розраховані для підвищення продуктивності. У цьому сценарії є інваріант, який не враховувався в прикладі коду, який залишив код сприйнятливим до перегонових умов за паралельним сценарієм.
Усі відповіді тут чудові, але я відчув, що я можу пролити більше світла на цю справу:
Інваріант з мовної точки зору означає щось, що ніколи не змінюється. Ця концепція походить насправді з математики, але це одна з популярних методик доказування в поєднанні з індукцією.
Ось як свідчить доказ: Якщо ви можете знайти інваріанта, який знаходиться в початковому стані, і що цей інваріант зберігається незалежно від будь-якої [правової] трансформації, застосованої до держави, то ви можете довести, що якщо певна держава не має цього інваріантний, то він ніколи не може відбутися, незалежно від того, яка послідовність перетворень застосовується до початкового стану.
Тепер попередній спосіб мислення (знову поєднаний з індукцією) дає можливість передбачити логіку комп'ютерного програмного забезпечення. Особливо важливо, коли виконання йде в циклі, в яких інваріант може бути використаний для доведення того, що певний цикл дасть певний результат або що він ніколи не змінить стан програми певним чином.
Коли інваріант використовується для предикації циклу циклу, його називають циклом інваріантом . Його можна використовувати зовнішні петлі, але для циклів це дійсно важливо, тому що у вас часто багато можливостей або нескінченна кількість можливостей.
Зауважте, що я використовую слово "предикат" логіку комп'ютерного програмного забезпечення, а не доказую. І це тому, що хоча математичний інваріант може бути використаний як доказ, він ніколи не може довести, що комп'ютерне програмне забезпечення при його виконанні дасть те, що очікується, через те, що програмне забезпечення виконується поверх багатьох абстракцій, що ніколи не може бути доведено що вони дадуть те, що очікується (подумайте, наприклад, про апаратну абстракцію).
Нарешті, хоча теоретично і жорстко прогнозувати логіку програмного забезпечення важливо лише для таких критично важливих програм, як Медична та Військова. Інваріант все ще може бути використаний для допомоги типовому програмісту при налагодженні. Її можна використовувати, щоб знати, де в певному місці. Програма не вдалася, оскільки вона не змогла підтримувати певний інваріант - багато хто з нас так чи інакше використовує її, не замислюючись про це.