Теми рефератів
Авіація та космонавтика Банківська справа Безпека життєдіяльності Біографії Біологія Біологія і хімія Біржова справа Ботаніка та сільське гос-во Бухгалтерський облік і аудит Військова кафедра Географія
Геодезія Геологія Держава та право Журналістика Видавнича справа та поліграфія Іноземна мова Інформатика Інформатика, програмування Історія Історія техніки
Комунікації і зв'язок Краєзнавство та етнографія Короткий зміст творів Кулінарія Культура та мистецтво Культурологія Зарубіжна література Російська мова Маркетинг Математика Медицина, здоров'я Медичні науки Міжнародні відносини Менеджмент Москвоведение Музика Податки, оподаткування Наука і техніка Решта реферати Педагогіка Політологія Право Право, юриспруденція Промисловість, виробництво Психологія Педагогіка Радіоелектроніка Реклама Релігія і міфологія Сексологія Соціологія Будівництво Митна система Технологія Транспорт Фізика Фізкультура і спорт Філософія Фінансові науки Хімія Екологія Економіка Економіко-математичне моделювання Етика Юриспруденція Мовознавство Мовознавство, філологія Контакти
Українські реферати та твори » Информатика, программирование » Комбінаторні задачі

Реферат Комбінаторні задачі

Міністерство освіти Республіки Білорусь

Установа освіти

В«Гомельський державний університет ім. Ф. Скорини В»

Математичний факультет

Кафедра МПУ

Реферат

Комбінаторні задачі

Виконавець:

Студентка групи М-42 Макарченко А.Ю.

Науковий керівник: Долинський М.С.

Гомель 2005


Зміст

Введення

Генерація k-елементних підмножин

Генерація всіх підмножин даної множини

Генерація всіх перестановок n-елементного безлічі

Розбивки безлічі

Висновок

Література


Введення

Завдання дискретної математики, до яким належить більшість олімпіадних завдань з інформатики, часто зводяться до перебору різних комбінаторних конфігурацій об'єктів і вибору серед них найкращого, з точки зору умови тієї або іншої задачі. Тому знання алгоритмів генерації найбільш поширених комбінаторних конфігурацій є необхідною умовою успішного вирішення олімпіадних завдань в цілому. Важливо також знати кількість різних варіантів для кожного типу комбінаторних конфігурацій, так як це дозволяє реально оцінити обчислювальну трудомісткість обраного алгоритму вирішення тієї чи іншої задачі на перебір варіантів і, відповідно, його прийнятність для вирішення розглянутої задачі, з урахуванням її розмірності. Крім того, при вирішенні завдань корисним виявляється вміння для кожної з комбінаторних конфігурацій виконувати наступні операції: за наявною конфігурації отримувати наступну за нею в лексикографічному порядку; визначати номер даної конфігурації в лексикографічній нумерації всіх конфігурацій; та, навпаки, за порядковим номером виписувати відповідну йому конфігурацію.


Генерація k-елементних підмножин

В комбінаториці такі підмножини називають поєднаннями з n елементів по k елементів і позначають C n k . Їх кількість виражається наступною формулою:

Однак при програмуванні набагато зручніше використовувати наступні рекурентні співвідношення:

Пояснюється це тим, що у формулі (1) чисельник і знаменник ростуть дуже швидко, тому в силу особливостей комп'ютерної арифметики не завжди можливо точно вирахувати значення C n k , навіть коли останнє не перевершує максимально представимое ціле число.

При фіксованому значенні n максимального значення число сполучень досягає при k = n /2 (вірніше, для парного n максимум один і він зазначений, а для непарного - максимум досягається на двох сусідніх значеннях k : [ N/ 2] і

[ n /2] +1). Тому особливо корисною виявляється наступна оцінка для парних n [4] (Очевидно, що при непарних n відмінності будуть мінімальними), заснована на формулою Стірлінга:

Якщо допустити, що за час, відведений для вирішення завдання, ми можемо перебрати близько 10 6 варіантів, то з формули (3) випливає, що генерацію всіх сполучень з n елементів для будь-якого фіксованого k можна проводити для n ВЈ 24.

Зазвичай генерацію всіх k -елементних підмножин проводять в лексикографічному порядку, тим більше що в даному випадку це не призводить ні до ускладнення алгоритму, ні до збільшення його обчислювальної трудомісткості. Нагадаємо, що порядок підмножин називається лексикографічним, якщо для будь-яких двох підмножин справедливо, що раннє повинно бути Згенеровано то з них, з індексів елементів якого можна скласти менше k -значне число в n -ричной системі числення (або в десятковій, для n <10). Так, для n = 6 і k = 3 поєднання з третього, першого та п'ятого елемента має бути Згенеровано раніше, ніж з другого, третього і четвертого, так як 135 <234.

Розглянемо рекурсивний алгоритм вирішення цієї задачі. Ідея відомості даної задачі до задачі меншої розмірності наступна. Першим елементом підмножини може бути будь-який елемент, починаючи з першого і закінчуючи ( n - k + 1)-м елементом. Після того, як індекс першого елемента підмножини зафіксований, залишилося вибрати k - 1 елемент з елементів з індексами, більшими, ніж у першого. Далі поступаємо аналогічно. Коли обраний останній елемент, то ми досягли кінцевого рівня рекурсії та вбрання підмножина можна обробити (Проаналізувати або роздрукувати). У запропонованій нижче програмі масив a містить значення елементів вихідного безлічі і може бути заповнений довільним чином. У масиві p будемо формувати чергове поєднання з k елементів.

const nmax = 24;

type list = array [1 .. nmax] of integer; var k, i, j, n, q : Integer; a, p: list; procedure print (k: integer);

var i: integer; beginfor j: = 1 to k dowrite (p [j]: 4); writelnend; {print}

procedure cnk (n, k: integer); procedure gen (m, L: integer); var i: integer; beginif m = 0 then print (k) elsefor i: = L to n-m +1 dobegin

p [k-m +1]: = a [i];

gen (m-1, i +1)

end

end; {gen}

begin {cnk} gen (k, 1) end; {cnk} begin {Main} readln (n, k); for i: = 1 to n doa [i]: = i; { заповнити масив можна і по - іншому }

cnk (n, k)

end.

Зауважимо, що власне генерація поєднань проводиться в рекурсивної підпрограмі gen. Вона має наступні параметри: m - скільки елементів з безлічі нам ще залишилося вибрати і L - починаючи з якого елементу вихідного безлічі, слід вибирати ці m елементів. Зверніть увагу, що саме вкладена структура опису процедур cnk і gen дозволяє не передавати при рекурсивних викликах значення n і k , а з основної програми звертатися до процедури cnk з параметрами, відповідними постановці завдання, не вдаючись у подробиці її вирішення. Такий спосіб будемо застосовувати і надалі.

Генерація всіх підмножин даної множини

При вирішенні олімпіадних завдань найчастіше заздалегідь невідомо, скільки саме елементів вихідного безлічі повинно входити в шукане підмножина, тобто необхідний перебір всіх підмножин. Однак, якщо потрібно знайти мінімальне підмножина, тобто складається як можна з меншого числа елементів (або максимальне підмножина), то найефективніше організувати перебір так, щоб спочатку перевірялися всі підмножини, що складаються з одного елемента, потім з двох, трьох і т. д. елементів (для максимального підмножини - у зворотному порядку). У цьому випадку, перше ж підмножина, що задовольняє умові задачі і буде шуканим, і подальший перебір слід припинити. Для реалізації такого перебору можна скористатися, наприклад, процедурою cnk, описаної в попередньому розділі. Введемо в неї ще один параметр: логічну змінну flag, яка буде позначати, задовольняє поточне поєднання елементів умові завдання чи ні. При отриманні чергового поєднання замість його друку звернемося до процедури його перевірки check, яка і буде визначати значення прапора. Тоді початок процедури gen слід переписати так:

procedure gen ( m , L : integer );

var i: integer;

begin

if m = 0 then

begin

check (p, k, flag);

if flag then exit

end

else ...

Далі процедура дослівно збігається з попередньою версією. В основній же програмі єдине звернення до даної процедури слід замінити наступним фрагментом:

k: = 0;


Страница 1 из 4Следующая страница

Друкувати реферат
Замовити реферат
Товары
загрузка...
Наверх Зворотнiй зв'язок