Скачиваний:
2
Добавлен:
22.04.2026
Размер:
1.01 Mб
Скачать

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

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

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

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

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

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

Вариант №1. Экспертная система для консультации в отношении покупки японского легкового автомобиля

Выполнил студент: Яковлев М. А. Андреев А. А.

Блинов И. С. ИКПИ-32 Приняла работу: Березкин А. А. Дата выполнения: «20» марта 2026 г.

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

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

Целью работы является разработка экспертной системы (ЭС), основанной на правилах, для консультации пользователей по выбору японского легкового автомобиля. Система учитывает субъективные предпочтения, объективные потребности (количество пассажиров, тип езды) и финансовые возможности клиента.

В ходе выполнения работы необходимо:

·реализовать базу знаний, содержащую не менее 30 продукционных правил;

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

·обеспечить интерактивное взаимодействие с разными типами пользователей (неспециалист, специалист, студент, эксперт, инженер по знаниям);

·не использовать сторонних библиотек, реализовать все компоненты самостоятельно.

В качестве языка реализации выбран MATLAB (интерпретатор, встроенные средства для работы со структурами данных). Код системы приведён в приложении.

Ход работы

Экспертная система (ЭС) – это компьютерная программа, которая имитирует рассуждения человека-эксперта в узкой предметной области. Классическая архитектура ЭС включает три основных компонента: базу знаний (БЗ), содержащую формализованные знания эксперта; механизм вывода (МВ), который управляет процессом применения знаний к текущей ситуации; и интерфейс пользователя, обеспечивающий общение с системой. В системах, базирующихся на правилах, знания представляются в виде продукций – конструкций вида «ЕСЛИ (условия) ТО (заключения)». Прямой цепочечный вывод (forward chaining) является одним из основных методов обработки правил. Он начинается с набора исходных фактов (рабочей памяти) и многократно применяет правила, добавляя новые факты, пока не будет достигнуто состояние насыщения.

Разработанная экспертная система состоит из трёх основных модулей, реализованных в виде функций MATLAB.

1.Модуль базы знаний представляет собой массив структур rules, каждая структура содержит три поля: conditions – список условий в виде пар «имя атрибута – значение»; conclusions – список заключений в аналогичном формате; description – текстовое описание правила, используемое для отладки и обучения.

2.Модуль механизма вывода реализован в функции run_inference, которая принимает начальные факты и возвращает итоговую рабочую память, а также список применённых правил. Алгоритм функции следующий: сначала рабочая память инициализируется начальными фактами. Затем в цикле, пока добавляются новые факты, производится последовательный просмотр всех правил. Для каждого правила проверяется, все ли его условия присутствуют в рабочей памяти. Если да, то для каждого заключения проверяется, отсутствует ли оно в памяти. Если хотя бы одно заключение является новым, то правило считается активированным.

3.Модуль интерфейса пользователя включает главную функцию main, которая выводит меню выбора типа пользователя.

Вспомогательные функции add_fact, has_fact, get_facts_by_name и get_first_value обеспечивают работу с рабочей памятью как с набором пар «атрибут–значение».

База знаний включает ровно 30 продукционных правил (рис. 1), каждое из которых отражает некоторую взаимосвязь между параметрами покупателя и характеристиками автомобиля. Правила сгруппированы по разным аспектам выбора: бюджет и тип езды, количество пассажиров,

2

приоритеты (экономичность, надёжность, безопасность, динамика, престиж, внедорожные качества), климатические условия, условия парковки, необходимость грузоперевозок и полного привода.

Рисунок 1 – Правила

Например, для покупателей, предъявляющих повышенные требования к комфорту и безопасности в холодном климате, предусмотрено правило 21: «ЕСЛИ климат холодный, ТО добавить опции подогрева сидений и подогрева зеркал». При наличии высокого бюджета правило 22 добавляет также подогрев руля и предпусковой подогреватель.

Механизм вывода построен на классическом алгоритме прямого цепочечного вывода. Рассмотрим его работу подробнее.

Входными данными для run_inference служат массив начальных фактов (каждый факт – это ячейка из двух элементов: имя атрибута и значение) и массив правил. Выходными – итоговая рабочая память и массив применённых правил.

Рисунок 2 - Механизм вывода

На первом этапе рабочая память инициализируется начальными фактами. Затем запускается внешний цикл while new_facts_added. Внутри этого цикла переменная new_facts_added изначально устанавливается в false. Далее последовательно перебираются все правила.

3

Реализовано несколько вариантов общения с системой, например, сценарий неспециалист – пользователь без технических знаний. Ему задаются простые вопросы (количество пассажиров, бюджет, тип езды, приоритет и т. д.) с вариантами ответов (рис. 3). На выходе – понятная рекомендация (марка, модель, основные характеристики). Студент – сценарий для обучения: пользователь вводит факты вручную в формате «имя значение», система показывает все факты в рабочей памяти, список применённых правил и полученную рекомендацию. Это позволяет изучить механизм вывода. Также реализовано взаимодействие с экспертом, специалистом и инженером по знаниям.

Рисунок 3 - Сценарий взаимодействия с системой

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

Пример тестирования в случае, когда пользователь выбрал в главном меню пункт «Неспециалист» (рис. 4). Пользователь получил от системы рекомендацию «Toyota Yaris».

4

Рисунок 4 - Первое тестирование

Второе тестирование было нацелено на то, чтобы продемонстрировать студенту цепочку правил и рассуждений при выборе ответа системой (рис. 5).

Рисунок 5 - Второе тестирование

5

Вывод

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

Разработанная система демонстрирует возможности применения экспертных систем в области консультационных услуг. Она позволяет пользователям без специальных знаний получить квалифицированную рекомендацию по выбору автомобиля, а специалистам – проверить и дополнить свои знания. Студенты могут изучать на её примере принципы работы механизмов вывода, а инженеры по знаниям – отлаживать и расширять базу знаний.

Программа

function main()

% ЭС подбор японского авто: 30 правил, 5 типов пользователей rules = struct('conditions',{},'conclusions',{},'description',{});

% Правило 1

r.conditions = {{'бюджет','низкий'},{'тип_езды','город'},{'приоритет','экономичность'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Yaris'},{'двигатель','бензин'},{'коробка','автомат'}};

r.description = 'Низкий бюджет, город, экономичность → Toyota Yaris'; rules(end+1)=r; % Правило 2

r.conditions = {{'бюджет','низкий'},{'тип_езды','город'},{'приоритет','надежность'}};

r.conclusions = {{'рекомендация_марки','Suzuki'},{'рекомендация_модели','Swift'},{'двигатель','бензин'},{'коробка','механика'}};

r.description = 'Низкий бюджет, город, надёжность → Suzuki Swift'; rules(end+1)=r; % Правило 3

r.conditions = {{'бюджет','средний'},{'пассажиры',4},{'потребность','простор'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Camry'},{'кузов','седан'},{'двигатель','бензин'}}; r.description = 'Средний бюджет, семья 4+, простор → Toyota Camry'; rules(end+1)=r;

% Правило 4

r.conditions = {{'бюджет','средний'},{'пассажиры',4},{'потребность','простор'},{'предпочтение','полный_привод'}}; r.conclusions = {{'рекомендация_марки','Subaru'},{'рекомендация_модели','Legacy'},{'кузов','седан'},{'привод','полный'}}; r.description = 'Средний бюджет, семья, простор и полный привод → Subaru Legacy'; rules(end+1)=r;

% Правило 5

r.conditions = {{'бюджет','средний'},{'пассажиры',2},{'тип_езды','город'}};

r.conclusions = {{'рекомендация_марки','Honda'},{'рекомендация_модели','Civic'},{'кузов','хэтчбек'},{'коробка','вариатор'}};

r.description = 'Средний бюджет, 2 пассажира, город → Honda Civic'; rules(end+1)=r; % Правило 6

r.conditions = {{'бюджет','высокий'},{'приоритет','престиж'}};

6

r.conclusions = {{'рекомендация_марки','Lexus'},{'рекомендация_модели','ES'},{'кузов','седан'},{'двигатель','гибрид'}}; r.description = 'Высокий бюджет, престиж → Lexus ES гибрид'; rules(end+1)=r;

% Правило 7

r.conditions = {{'бюджет','высокий'},{'приоритет','внедорожные_качества'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Land Cruiser'},{'кузов','внедорожник'},{'привод','полный'}};

r.description = 'Высокий бюджет, внедорожные качества → Land Cruiser'; rules(end+1)=r; % Правило 8

r.conditions = {{'бюджет','высокий'},{'приоритет','спортивность'}};

r.conclusions = {{'рекомендация_марки','Nissan'},{'рекомендация_модели','GT- R'},{'кузов','купе'},{'двигатель','бензин_турбо'}};

r.description = 'Высокий бюджет, спортивность → Nissan GT-R'; rules(end+1)=r; % Правило 9

r.conditions = {{'бюджет','средний'},{'тип_езды','трасса'}};

r.conclusions = {{'рекомендация_марки','Mazda'},{'рекомендация_модели','6'},{'кузов','седан'},{'двигатель','бензин'}}; r.description = 'Средний бюджет, трасса → Mazda 6'; rules(end+1)=r;

% Правило 10

r.conditions = {{'бюджет','высокий'},{'тип_езды','трасса'}};

r.conclusions = {{'рекомендация_марки','Lexus'},{'рекомендация_модели','LS'},{'кузов','седан'},{'двигатель','гибрид'}}; r.description = 'Высокий бюджет, трасса → Lexus LS гибрид'; rules(end+1)=r;

% Правило 11

r.conditions = {{'пассажиры',5},{'потребность','простор'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Sienna'},{'кузов','минивэн'},{'привод','передний'}};

r.description = 'Большая семья (5+), простор → Toyota Sienna'; rules(end+1)=r; % Правило 12

r.conditions = {{'пассажиры',5},{'потребность','простор'},{'предпочтение','полный_привод'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Sienna'},{'кузов','минивэн'},{'привод','полный'}};

r.description = 'Большая семья, простор и полный привод → Sienna AWD'; rules(end+1)=r; % Правило 13

r.conditions = {{'бюджет','низкий'},{'тип_езды','смешанный'}};

r.conclusions = {{'рекомендация_марки','Suzuki'},{'рекомендация_модели','Vitara'},{'кузов','кроссовер'},{'привод','полный'}};

r.description = 'Низкий бюджет, смешанная езда → Suzuki Vitara'; rules(end+1)=r; % Правило 14

r.conditions = {{'бюджет','средний'},{'тип_езды','смешанный'}};

r.conclusions = {{'рекомендация_марки','Honda'},{'рекомендация_модели','CR- V'},{'кузов','кроссовер'},{'привод','полный'}};

r.description = 'Средний бюджет, смешанная езда → Honda CR-V'; rules(end+1)=r; % Правило 15

7

r.conditions = {{'бюджет','высокий'},{'тип_езды','смешанный'}};

r.conclusions = {{'рекомендация_марки','Lexus'},{'рекомендация_модели','RX'},{'кузов','кроссовер'},{'привод','полный'}}; r.description = 'Высокий бюджет, смешанная езда → Lexus RX'; rules(end+1)=r;

% Правило 16

r.conditions = {{'приоритет','экономичность'},{'бюджет','средний'}};

r.conclusions = {{'двигатель','гибрид'},{'рекомендация_марки','Toyota'},{'рекомендация_модели','Prius'},{'кузов','хэтчбек'}};

r.description = 'Экономичность, средний бюджет → Toyota Prius гибрид'; rules(end+1)=r; % Правило 17

r.conditions = {{'приоритет','экономичность'},{'бюджет','низкий'}};

r.conclusions = {{'двигатель','бензин'},{'рекомендация_марки','Suzuki'},{'рекомендация_модели','Ignis'},{'кузов','хэтчбек'}};

r.description = 'Экономичность, низкий бюджет → Suzuki Ignis'; rules(end+1)=r; % Правило 18

r.conditions = {{'приоритет','надежность'},{'бюджет','средний'}};

r.conclusions = {{'рекомендация_марки','Toyota'},{'рекомендация_модели','Corolla'},{'кузов','седан'}}; r.description = 'Надёжность, средний бюджет → Toyota Corolla'; rules(end+1)=r;

% Правило 19

r.conditions = {{'приоритет','надежность'},{'бюджет','высокий'}};

r.conclusions = {{'рекомендация_марки','Lexus'},{'рекомендация_модели','NX'},{'кузов','кроссовер'}}; r.description = 'Надёжность, высокий бюджет → Lexus NX'; rules(end+1)=r;

% Правило 20

r.conditions = {{'приоритет','безопасность'},{'бюджет','высокий'}};

r.conclusions = {{'рекомендация_марки','Subaru'},{'рекомендация_модели','Outback'},{'кузов','универсал'},{'привод','полный'}};

r.description = 'Безопасность, высокий бюджет → Subaru Outback'; rules(end+1)=r; % Правило 21

r.conditions = {{'климат','холодный'}};

r.conclusions = {{'опция','подогрев_сидений'},{'опция','подогрев_зеркал'}}; r.description = 'Холодный климат → подогрев сидений и зеркал'; rules(end+1)=r; % Правило 22

r.conditions = {{'климат','холодный'},{'бюджет','высокий'}};

r.conclusions = {{'опция','подогрев_руля'},{'опция','предпусковой_подогреватель'}};

r.description = 'Холодный климат + высокий бюджет → подогрев руля и предпусковой подогреватель'; rules(end+1)=r; % Правило 23

r.conditions = {{'парковка','ограничена'}};

r.conclusions = {{'опция','парктроник'},{'кузов','компактный'}};

r.description = 'Ограниченная парковка → парктроник и компактный кузов'; rules(end+1)=r; % Правило 24

8

r.conditions = {{'парковка','ограничена'},{'бюджет','низкий'}};

r.conclusions = {{'рекомендация_марки','Suzuki'},{'рекомендация_модели','Ignis'},{'кузов','хэтчбек'}}; r.description = 'Ограниченная парковка и низкий бюджет → Suzuki Ignis'; rules(end+1)=r;

% Правило 25

r.conditions = {{'бюджет','средний'},{'пассажиры',2},{'приоритет','динамика'}};

r.conclusions = {{'рекомендация_марки','Mazda'},{'рекомендация_модели','MX-5'},{'кузов','родстер'},{'привод','задний'}}; r.description = 'Средний бюджет, 2 пассажира, динамика → Mazda MX-5'; rules(end+1)=r;

% Правило 26

r.conditions = {{'бюджет','высокий'},{'пассажиры',2},{'приоритет','динамика'}};

r.conclusions = {{'рекомендация_марки','Nissan'},{'рекомендация_модели','370Z'},{'кузов','купе'}}; r.description = 'Высокий бюджет, 2 пассажира, динамика → Nissan 370Z'; rules(end+1)=r;

% Правило 27

r.conditions = {{'потребность','грузоперевозки'}}; r.conclusions = {{'кузов','универсал'}};

r.description = 'Нужны грузоперевозки → рекомендуем универсал'; rules(end+1)=r; % Правило 28

r.conditions = {{'потребность','грузоперевозки'},{'бюджет','средний'}};

r.conclusions = {{'рекомендация_марки','Subaru'},{'рекомендация_модели','Outback'},{'кузов','универсал'}}; r.description = 'Грузоперевозки, средний бюджет → Subaru Outback'; rules(end+1)=r;

% Правило 29

r.conditions = {{'потребность','грузоперевозки'},{'бюджет','высокий'}};

r.conclusions = {{'рекомендация_марки','Lexus'},{'рекомендация_модели','RX'},{'кузов','кроссовер'}}; r.description = 'Грузоперевозки, высокий бюджет → Lexus RX'; rules(end+1)=r;

% Правило 30

r.conditions = {{'предпочтение','полный_привод'},{'бюджет','средний'}};

r.conclusions = {{'привод','полный'},{'рекомендация_марки','Subaru'},{'рекомендация_модели','Forester'},{'кузов','кроссовер'}};

r.description = 'Полный привод и средний бюджет → Subaru Forester'; rules(end+1)=r;

fprintf('База знаний загружена, правил: %d\n', length(rules)); while true

fprintf('1. Неспециалист\n2. Специалист\n3. Студент\n4. Эксперт\n5. Инженер по знаниям\n0. Выход\n'); choice = input('Ваш выбор: ');

switch choice

case 1, scenario_non_specialist(rules); case 2, scenario_specialist(rules); case 3, scenario_student(rules);

case 4, scenario_expert(rules);

case 5, scenario_knowledge_engineer(rules);

9

case 0, fprintf('До свидания!\n'); return; otherwise, fprintf('Неверный выбор.\n');

end end end

function scenario_non_specialist(rules) fprintf('\n--- НЕСПЕЦИАЛИСТ ---\n'); facts = {};

while true, a=input('Сколько человек будет постоянно ездить? (1-7): '); if isnumeric(a)&&a>=1&&a<=7, facts{end+1}={'пассажиры',a}; break; end; end

fprintf('Бюджет: 1-низкий 2-средний 3-высокий\n');

b=input('Ваш выбор: '); while ~ismember(b,1:3), b=input('1-3: '); end; if b==1, facts{end+1}={'бюджет','низкий'}; elseif b==2, facts{end+1}={'бюджет','средний'}; else facts{end+1}={'бюджет','высокий'}; end

fprintf('Тип езды: 1-город 2-трасса 3-смешанный\n');

d=input('Ваш выбор: '); while ~ismember(d,1:3), d=input('1-3: '); end; if d==1, facts{end+1}={'тип_езды','город'}; elseif d==2, facts{end+1}={'тип_езды','трасса'}; else facts{end+1}={'тип_езды','смешанный'}; end

fprintf('Приоритет: 1-экономичность 2-надёжность 3-безопасность 4-динамика\n');

p=input('Ваш выбор: '); while ~ismember(p,1:4), p=input('1-4: '); end; if p==1, facts{end+1}={'приоритет','экономичность'}; elseif p==2, facts{end+1}={'приоритет','надежность'}; elseif p==3, facts{end+1}={'приоритет','безопасность'}; else facts{end+1}={'приоритет','динамика'}; end

if facts{1}{2}>=3, s=input('Важен простор? (да/нет): ','s'); if strcmpi(s,'да'), facts{end+1}={'потребность','простор'}; end; end awd=input('Нужен полный привод? (да/нет): ','s'); if strcmpi(awd,'да'), facts{end+1}={'предпочтение','полный_привод'}; end

park=input('Парковка ограничена? (да/нет): ','s'); if strcmpi(park,'да'), facts{end+1}={'парковка','ограничена'}; else facts{end+1}={'парковка','свободная'}; end

clim=input('Суровая зима? (да/нет): ','s'); if strcmpi(clim,'да'), facts{end+1}={'климат','холодный'}; else facts{end+1}={'климат','умеренный'}; end

[wm,~]=run_inference(rules,facts); fprintf('\n--- Результат ---\n');

brand=get_first_value(wm,'рекомендация_марки'); model=get_first_value(wm,'рекомендация_модели'); if ~isempty(brand) && ~isempty(model), fprintf('Рекомендация: %s %s\n',brand,model);

else fprintf('Не удалось подобрать автомобиль.\n'); end body=get_first_value(wm,'кузов'); if ~isempty(body), fprintf('Кузов: %s\n',body); end eng=get_first_value(wm,'двигатель'); if ~isempty(eng), fprintf('Двигатель: %s\n',eng); end trans=get_first_value(wm,'коробка'); if ~isempty(trans), fprintf('Коробка: %s\n',trans); end drive=get_first_value(wm,'привод'); if ~isempty(drive), fprintf('Привод: %s\n',drive); end

opts=get_facts_by_name(wm,'опция'); if ~isempty(opts), fprintf('Опции: %s\n',strjoin(opts,', ')); end end

function scenario_specialist(rules) fprintf('\n--- СПЕЦИАЛИСТ ---\n'); facts = get_facts_from_user();

10