zadacha_12x

advertisement
Задание № 12:
С помощью монет заданного номинала требуется набрать необходимую сумму,
затратив при этом минимальное количество монет.
Ход работы:
Используемая среда разработки - swi prolog 7.1.23
В качестве исходных данных подаем список с номиналами монет – List. Список
сортируется в порядке убывания с помощью метода пузырька (т.е 5,4,3,2,1).
Осуществляется поиск в списке L двух смежных элементов X и Y, таких, что если X > Y,
меняем их местами и получаем новый список, M, затем сортируется M. Если в списке нет
не одной пары смежных элементов X и Y, таких, что X > Y, считать что список
отсортирован.
После того как список отсортирован осуществляется поиск всех возможных комбинаций и
осуществляется поиск необходимого (где наименьшее количество монет) результата.
Правило findall – поиск всех возможных вариантов, которая включает привило result,
которая ищет каждую комбинацию. Правило best-выбирает лучший результат используя
правило number, которое подсчитывает количество монет в каждом списке. После всего
выводится на экран результат с помощью правила display_result.
Результат работы программы
1)Запуск программы и результат работы
Сумма 83
Номиналы – [10,5,50,1,2]
2)Если список пуст []
Выводит false
1
3)Если список состоит из отрицательных элементов результат – false.
4) Если список состоит и из положительных и отрицательных элементов, то
обрабатывается только положительные.
[10,-5,-50,1,-2]
5) Если список состоит из 1 элемента с помощью которого нельзя решить задачу [50]
6) Если список состоит из 1 элемента с помощью которого нельзя решить задачу [1]
2
Листинг
%С помощью монет заданного номинала требуется набрать необходимую сумму, затратив
%при этом минимальное количество монет.
% сортировка списка по убыванию, метод пузырька т.е 5,4,3,2,1
%Есть два списка, входной и выходной если выполняется условие order, то swap берет из
%входного списка два параметка, меняет их местами, и записывает в выходной.
bubble_sort(L, S) :- swap(L, M), !, bubble_sort(M, S).
bubble_sort(L, L) :- !.
swap([X, Y|R], [Y, X|R]) :- order(Y, X).
swap([X|R], [X|R1]) :- swap(R, R1).
order(X, Y) :- X >= Y.
%variations - ядро программы, где findall - ищет все возможные варианты(успешные) с
%помощью правила result, представлен в виде вложенных списков
variations(Coins,Result,Recruitment,K):findall(Variation,result(Coins,Result,Variation),Variations),
Variations = [B|Variations1],number(B,K0),best(Variations1,B,Recruitment,K0,K).
% best - поиск оптимального списка список представлен как [достоинство монеты, кол-во
% штук и.т.д]
best([B|Variations],_,Recruitment,K0,K):-number(B,A),
A<K0,!,best(Variations,B,Recruitment,A,K).
best([_|Variations],B0,Recruitment,K0,K):best(Variations,B0,Recruitment,K0,K).
best([],B,B,K,K).
%подсчитывает количество монет в каждом наборе
number([_,A|B],K):-!,number(B,K1),K is K1+A.
number(_,0).
%result - переменная Variation не определена. если result = true то он заносит переменную
%Variation в список Variations сама переменная инициализируется в функции result
result(_,0,[]) :-!.
result([M|Coins],Result,[M,H|Recruitment]):- H is Result div M, H>0,
Rest is Result mod M,
result(Coins,Rest,Recruitment).
result([M|Coins],Result,[M,H|Recruitment]):-H is (Result div M) - 1, H>0,
Rest is (Result mod M) + M,result(Coins,Rest,Recruitment).
result([_|Coins],Result,Recruitment):-result(Coins,Result,Recruitment).
% вывод на экран результата
display_result([M,A|B],K):-write(M),write(' coins - '),write(A),write('
unit.'),nl,!,display_result(B,K).
display_result(_,K):-write('All - '),write(K),write(' unit.'),nl.
% запуск программы, чтобы не вводить в консоли
run :List=[40,5,50,1,2,23],
bubble_sort(List,L2),
variations(L2,93,Recruitment,K),
display_result(Recruitment,K).
3
Download