Скачиваний:
0
Добавлен:
12.01.2026
Размер:
777.42 Кб
Скачать

Министерство цифрового развития, связи и массовых коммуникаций Российской Федерации

Федеральное государственное бюджетное образовательное учреждение Высшего образования «Санкт-Петербургский государственный университет телекоммуникаций им. Проф. М. А. Бонч-Бруевича» (СПбГУТ)

Факультет Информационных технологий и программной инженерии

Кафедра Программной инженерии

Лабораторная работа 3

По дисциплине: Разработка приложений искусственного интеллекта в киберфизических системах

Выполнил студент: Яковлев М. А. ИКПИ-32

Принял работу: Ерофеев С. А.

Дата выполнения:

«28» ноября 2025 г.

Санкт-Петербург

2025 г.

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

Разработать программу цифровой сортировки чисел из файла в Turbo Prolog 2.0.

Алгоритм сортировки

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

Сначала алгоритм определяет максимальное число в массиве, чтобы узнать, сколько разрядов у него всего. Затем для каждого разряда, начиная с нулевого (младший разряд), выполняются следующие шаги:

• Создаются 10 пустых корзин, по одной для каждой цифры от 0 до 9.

• Все элементы исходного массива рассматриваются, и для каждого определяется цифра на текущем разряде.

• В зависимости от этой цифры элемент помещается в соответствующую корзину.

• После распределения всех элементов по корзинам они собираются в один массив, сохраняя порядок корзин от 0 к 9.

Этот процесс повторяется для всех разрядов числа, постепенно упорядочивая список.

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

Перечень предикатов

1. main - Запускает программу, вызывает чтение данных и выполняет сортировку

2. radix_sort_signed(List, Sorted) - Обрабатывает список с учётом знаков: разделяет на положительные и отрицательные, сортирует отдельно, затем объединяет

3. split_sign(Input, Positives, Negatives) - Разделяет входной список на два: положительные числа (включая ноль) и отрицательные числа

4. restore_sign(AbsValues, SignedValues) - Преобразует список абсолютных значений обратно в отрицательные числа

5. reverse_list(Input, Reversed) - Разворачивает порядок элементов в списке

6. radix_sort(Unsorted, Sorted) - Выполняет поразрядную сортировку для неотрицательных чисел

7. radix_pass(List, CurrentPosition, MaxPosition, Result) - Выполняет сортировку по конкретному разряду, рекурсивно обрабатывает все разряды

8. count_sort(InputList, DigitPos, SortedList) - Реализует сортировку для одного разряда с использованием корзин

9. mk_buckets(Count, Buckets) - Создает указанное количество пустых корзин

10. distribute(Numbers, DigitPos, InputBuckets, OutputBuckets) - Распределяет числа по корзинам в соответствии с цифрой текущего разряда

11. collect(Buckets, CombinedList) - Собирает числа из всех корзин в единый отсортированный список

12. add_to_bucket(Buckets, Index, Number, NewBuckets) - Добавляет число в указанную корзину по индексу цифры

13. digit_at(Number, Position, Digit) - Извлекает конкретную цифру из числа по указанной позиции (разряду)

14. int_pow10(Exponent, Result) - Вычисляет 10 в заданной степени

15. max_list(Numbers, Maximum) - Находит самое длинное число в списке для определения количества разрядов

16. max_list_h(Numbers, CurrentMax, FinalMax) - Вспомогательный предикат для поиска максимума

17. digit_width(Number, Width) - Определяет количество цифр в числе

18. digit_width_h(Number, Counter, Result) - Вспомогательный предикат для рекурсивного подсчёта разрядов

19. append(List1, List2, Result) - Объединяет два списка в один

20. rev_append(Input, Accumulator, Result) - Вспомогательный предикат для разворота списка

Схема

Рисунок 1. Общая схема работы программы

Рисунок 2. Сортировка отрицательных чисел

Программа

domains

int_list = integer*

buckets = int_list*

file = text_file

predicates

main % Главный предикат, запускающий сортировку

radix_sort_signed(int_list, int_list) % Предикат для сортировки списка целых чисел с учетом знаков

read_data(int_list) % Чтение данных из файла в список целых чисел

read_n(integer, int_list) % Чтение N целых чисел и сохранение их в список

split_sign(int_list, int_list, int_list) % Разделение списка на положительные и отрицательные числа

restore_sign(int_list, int_list) % Восстановление знаков у отрицательных чисел

reverse_list(int_list, int_list)

radix_sort(int_list, int_list) % Основной предикат для сортировки с использованием алгоритма радикс-сортировки

radix_pass(int_list, integer, integer, int_list) % Один проход сортировки по определенной цифре

count_sort(int_list, integer, int_list)

mk_buckets(integer, buckets)

distribute(int_list, integer, buckets, buckets) % Распределение чисел по ведрам на основе текущей цифры

collect(buckets, int_list) % Сбор всех чисел из корзин в один список

add_to_bucket(buckets, integer, integer, buckets) % Добавление числа в соответствующее ведро

digit_at(integer, integer, integer) % Получение цифры числа по заданной позиции

int_pow10(integer, integer) % Вычисление степени числа 10

max_list(int_list, integer) % Поиск максимального значения в списке

max_list_h(int_list, integer, integer) % Вспомогательный предикат для поиска максимума

digit_width(integer, integer) % Определение количества цифр в числе

digit_width_h(integer, integer, integer) % Вспомогательный предикат для подсчета ширины числа

append(int_list, int_list, int_list)

rev_append(int_list, int_list, int_list)

clauses

read_data(List) :-

write("Enter input-file name: "),

readln(FileName),

openread(text_file, FileName),

!,

readdevice(text_file),

readint(N),

read_n(N, List),

closefile(text_file).

read_data([]).

read_n(0, []) :- !.

read_n(N, [X|T]) :-

readint(X),

N1 = N - 1,

read_n(N1, T).

main :-

read_data(Numbers),

radix_sort_signed(Numbers, Sorted),

write("Sorted: "), write(Sorted), nl.

radix_sort_signed([], []) :- !.

radix_sort_signed(List, Final) :-

split_sign(List, Pos0, Neg0),

radix_sort(Pos0, PosSorted),

restore_sign(Neg0, NegAbs),

radix_sort(NegAbs, NegSortedAbs),

restore_sign(NegSortedAbs, NegSigned),

reverse_list(NegSigned, NegRev),

append(NegRev, PosSorted, Final).

split_sign([], [], []). % Разделяет список на положительные и отрицательные числа

split_sign([H|T], [H|Pos], Neg) :- H >= 0, !, split_sign(T, Pos, Neg).

split_sign([H|T], Pos, [H|Neg]) :- split_sign(T, Pos, Neg).

restore_sign([], []). % Восстанавливает знаки у отрицательных чисел

restore_sign([H|T], [NH|NT]) :- NH = -H, restore_sign(T, NT).

reverse_list(L, R) :- rev_append(L, [], R).

rev_append([], A, A).

rev_append([H|T], A, R) :- rev_append(T, [H|A], R).

radix_sort([], []) :- !. % Основной предикат для сортировки с использованием алгоритма радикс-сортировки

radix_sort(List, Sorted) :-

max_list(List, Max),

digit_width(Max, W),

radix_pass(List, 0, W, Sorted).

radix_pass(List, P, W, List) :- P = W, !. % Проход по цифрам завершен

radix_pass(List, P, W, Sorted) :-

count_sort(List, P, Tmp),

Тестирование

Для проверки работоспособности программы были выполнены тестовые запуски.

Первый тест:

7, 8, 0, -9

Рисунок 1. Результат теста для первого набора данных

Второй тест:

90, 9, -28, 4, 4, 5, 0, -1, -2, 45, 555

Рисунок 2. Результат теста для первого набора данных

Третий тест:

10, 100, 1000, -1, 1, 1, -1, 0

Рисунок 3. Результат теста для первого набора данных

Заключение

В результате выполнения работы была разработана программа цифровой сортировки чисел, реализованная в среде Turbo Prolog 2.0.