Запоминание списка посещенных мест

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

Первым аргументом процедуры "тснр_путешествоватьЗ" является список всех посещенных мест. В соответствии со вторым правилом этой процедуры, после того, как подцель "сим_путешествие" сгенерирует новый промежуточный пункт В, подцель "элемент" выполнит проверку того, чтобы В не содержался в списке мест, которые уже были посещены. Если В — новый пункт, то он добавляется в начало списка при помощи рекурсивного обращения к процедуре тснр_путешествовать3", так что при любых последующих рекурсивных вызовах этой процедуры В не будет приниматься в качестве промежуточного пункта. Промежуточная процедура "путешествиеЗ" преобразует три исходных аргумента в четыре аргумента, которые требуются в процедуре "тснр_путешествоватьЗ". При первом вызове процедуры "тснр_путешествоватьЗ" исходный пункт А помещается в список посещенных мест. Процедура "сим_путешествие" и база данных "путешествие" остались такими же, как и ранее.

% Промежуточная процедура для "тснр_путешествоватьЗ"

% + + -

путешествиеЗ (А, Б, М): —

тснр_путешествовать3 ([А], А, Б, М). % Добавить А к

% След.

% Либо один вид транспорта соединяет пункты А и Б:

% + + + -

тснр_путешествоватьЗ (След, А, Б, м (Вид_тр, Б)): — % (1)

А\==Б,

сим_путешествие (А, Б, Вид_тр).

% Либо более чем один вид транспорта соединяет пункты

% А и Б (т. е. нужны пересадки):

% + + + -

тснр_путешествоватьЗ (След, А, Б, м (Вид_тр1, В, Вид_тр2)):— % (2)

А\==Б,

сим_путешествие (А, В, Вид_тр1), % сгенерировать В

not (элемент (В, След)), % проверка В

тснр_путешествоватьЗ ([В | След], В, Б, Вид_тр2).

Посмотрим, как данная процедура будет обрабатывать все тот же запрос:

|?— тснр_путешествовать3 (ньюарк, куинс, М).

М = м (автомобиль, бронкс, м (автобус, куинс));

М = м (автомобиль, бронкс,

м (метро, манхэттен, м (жел_дорога, куинс)));

М = м (автомобиль, принстон,

м (автобус, манхэттен, м (жел_дорога, куинс)));

М = м (автомобиль, принстон, м (автобус, манхэттен,

м (метро, бронкс, м (автобус, куинс))));

М=м (автобус, манхэттен, м (жел_дорога, куинс));

М = м (автобус, манхэттен,

м (метро, бронкс, м (автобус, куинс)));

нет :

Если Вы изучите рис. 4. 5, то обнаружите, что данная программа выдает все правильные ответы, включая наиболее разумный ответ (проехать автобусом до Манхэттена, а затем - поездом Лонг-Айлендской железной дороги до Куинса). Итак, причинами успешной работы процедуры "тснр_путешествоватьЗ" являются следующие обстоятельства:

1) эта процедура, как было показано, симметрична, транзитивна и нерефлексивна;

2) запрос к процедуре позволяет получить полное множество ответов;

3) при запросе о том, как добраться из Куинса в Ньюарк, будет получено множество ответов, являющееся зеркальным отображением множества ответов на запрос о том, как добраться из Нюарка в Куинс.

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

Соседние файлы в папке Гл.0,1,2,3,4,5,Предисловие