Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
New Документ Microsoft Word (3).doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
1 Мб
Скачать
☆

4.Задача «куча камней»

Любая найденная в программе ошибка – не последняя

Закон Мерфи

Цель работы – научиться реализовать алгоритм решения известной «задачи о камнях» как примере оптимизационной задачи (4 час.).

Постановка задачи.

Из Википедии: Полный перебор (или метод «грубой силы», англ. brute force) относится к классу методов поиска решения исчерпыванием всевозможных вариантов. Сложность полного перебора зависит от количества всех возможных решений задачи. Если пространство решений очень велико, то полный перебор может не дать результатов в течение нескольких лет или даже столетий. (Другими словами, если вы хотите получать зарплату еще при жизни, то, возможно, вам следует поискать более «быстрое» решение?)

Возьмем в качестве иллюстрации известную «олимпиадную» задачу о куче камней, которая заключается в следующем. Имеется произвольное число камней N>1, вес каждого из которых известен и равен Wi, i=1..N, причем 1<N<21, 0<Wi <100000, N и W – целые числа. Требуется распределить камни на две кучи таким образом, чтобы разность весов этих двух куч была минимальной. Например, пусть есть N=5 камней с весами: 5, 8, 13, 27, 14. Очевидно, что в одну кучу надо поместить камни 5 и 27 (вес 32), а в другую – 8, 13 и 14 (вес 35). Тогда разность весов будет минимальна и равна 3 (по абсолютной величине).

Надо написать (точнее, разработать) алгоритм и программу, которая бы решала поставленную задачу. Учтите, что программа должна запросить у пользователя N и Wi.

Задание. Разработайте алгоритм и программу в соответствии с приведенными ниже (очень ценными) методическими указаниями, выполните отладку и тестирование разработанной программы. Используйте функции, чтобы структурировать программу и повысить ее наглядность и надежность. Разработайте тесты для контроля корректности программы и докажите преподавателю ее работоспособность.

Методические указания.

Шаг 1. Генерация каркаса приложения.

С помощью мастера ИС MVS создайте консольное приложение и включите в него поддержку библиотеки MFC (как и в работе «Разработка типового консольного приложения»). В приведенных ниже листингах предполагается, что проекту присвоено имя StonesHeap, но вы вправе присвоить ему другое имя, например, Lab3, и тогда в вашем проекте у вас будет имя Lab3 там, где в приведенных листингах присутствует идентификатор StonesHeap.

Шаг 2. Добавление заголовочных файлов.

В начало файла StonesHeap.cpp (а у вас будет, возможно, имя файла Lab3.cpp), содержащего функцию _tmain(), добавьте директивы include для подключения необходимых заголовочных файлов (добавления выделены курсивом):

Заголовочный файл Limits.h содержит, в частности, предельные значения для интегральных типов данных и их рекомендуется использовать вместо непосредственно заданных «своих» констант.

Шаг 3. Примитивнейшая версия программы.

Автор этой работы не смог придумать более совершенную программу, чем в приведенном ниже листинге. Помимо отсутствия достоинств, главными ее недостатками являются:

  • возможность нахождения решения задачи только для такого случая, когда исходную кучу достаточно разбить на две такие, одна из которых содержит всего один камень, а в другой, соответственно, находятся все остальные;

  • в программе не предусмотрен ввод числа камней в куче и их весов, так как автору было лень в процессе отладки программы всякий раз их вводить;

  • в программе использовано так называемое «магическое» число 5, что в процессе дальнейшего развития программы сулит неприятности. Очевидно, что максимально возможное число камней в куче (20) лучше бы сделать константой. Если вы по натуре человек бесстрашный, то можете вместо 20 использовать 200, 2000, 20000 и т.д;

  • программу надо повторно запускать для того, чтобы решать задачу с другими исходными данными, что, конечно, неудобно, т.е. «по-дебильному».

Вы, естественно, не можете принять такую примитивную программулину и с легкостью разработаете совершенную, лишенную перечисленных недостатков.

Русифицировать (консольное) приложение можно и путем вызова функции setlocale(LC_ALL,"rus");, которая, упрощенно говоря, устанавливает русский язык в качестве языка ввода/вывода. Эту функцию достаточно вызвать один раз при запуске программы на выполнение – проще всего в начале функции _tmain().

Шаг 4. Вперед на мины! Для проверки корректности алгоритма и собственно программы рекомендуется заранее придумать несколько тестов с известными решениями. Например, кучу из 7 камней с весами 10, 20, 30, 15, 25, 35, 15 можно разделить на две одинаковые: 10+30+35=75 и 20+15+25+15=75, а кучу из камней 1, 5, 11, 16, 18, 21, 21 – на две такие: 5+21+21=47 и 1+11+16+18=46.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]