Найти мин из списка с числами и строками - PullRequest
0 голосов
/ 21 октября 2018

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

%city(name,latitude,longitude)
city(brussels,50.8462807,4.3547273).
city(tirana,41.33165,19.8318).
city(andorra,42.5075025,1.5218033).
city(vienna,48.2092062,16.3727778).
city(minsk,53.905117,27.5611845).
city(sarajevo,43.85643,18.41342).
city(sofia,42.6976246,23.3222924).
city(zagreb,45.8150053,15.9785014).

И данные предикаты для расчета расстояния между двумя городами

%  dist_cities(brussels,prague,D).
%  D = 716837.
dist_cities(C1,C2,Dist):-
    city(C1,Lat1,Lon1),
    city(C2,Lat2,Lon2),
    distance(Lat1,Lon1,Lat2,Lon2,Dist).

degrees2radians(Deg,Rad):-
    Rad is Deg*0.0174532925.

% distance(latitude_first_point,longitude_first_point,latitude_second_point,longitude_second_point,distance
% in meters)
distance(Lat1, Lon1, Lat2, Lon2, Dis2):-
    degrees2radians(Lat1,Psi1),
    degrees2radians(Lat2,Psi2),
    DifLat is Lat2-Lat1,
    DifLon is Lon2-Lon1,
    degrees2radians(DifLat,DeltaPsi),
    degrees2radians(DifLon,DeltaLambda),
    A is sin(DeltaPsi/2)*sin(DeltaPsi/2)+ cos(Psi1)*cos(Psi2)*sin(DeltaLambda/2)*sin(DeltaLambda/2),
    C is 2*atan2(sqrt(A),sqrt(1-A)),
    Dis1 is 6371000*C,
    Dis2 is round(Dis1).

То, чего я сейчас пытаюсь достичь, это, учитывая город, найдите город с кратчайшим расстоянием.

Я придумал это, чтобы собрать все города и их соответствующие расстояния до начальной точки

visit(_, [], []).

visit(S, [H | T], [(H, D) | T1]):-
  dist_cities(S, H, D),
  visit(S, T, T1).

Но яЯ не уверен, как вывести название города и соответствующее расстояние, учитывая, что это мой результирующий список

?- visit(brussels, [minsk, zagreb, tirana], L).
L = [(minsk, 1603870),  (zagreb, 1023569),  (tirana, 1589189)] .

Я знаю, как найти мин из списка чисел, но я не уверен здесь, так как список написанas (CityName, Distance).

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 24 октября 2018

Я бы использовал рекурсию в стиле аккумулятора, распаковывая пару значений, используя сопоставление с образцом.Если два города находятся на одинаковом минимальном расстоянии, точки выбора находятся на месте, поэтому их можно найти.Начиная с L:

closest(City, Distance) :-
    L = [(minsk, 1603870),  (zagreb, 1023569),  (tirana, 1589189)],
    % use first case as starting point
    L = [(TestCity, TestDistance)|Cities],
    % call accumulator recursive function, City and Distance unground.
    closest(Cities, City, Distance, TestCity, TestDistance).

% base case, set returned values to min found
closest([], City, Dist, City, Dist).
% case where new test case is min
closest([(NewCity, NewDist)|Cities], City, Distance, _, TestDist) :-
    NewDist is min(NewDist, TestDist),
    closest(Cities, City, Distance, NewCity, NewDist).
% case where old test case is min
closest([(_, NewDist)|Cities], City, Distance, TestCity, TestDist) :-    
    TestDist is min(NewDist, TestDist),
    closest(Cities, City, Distance, TestCity, TestDist).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...