从列表中查找带有数字和字符串的分钟

时间:2018-10-21 17:43:28

标签: prolog

我有这样定义的城市列表

angular.module('myApp').factory('Service'function() {
  var service = {
    foo: function() {
      return 1
    },
    sub: {
      bar: function() {
        var foo = service.foo();
                  ^^^^^^^
      }
    }
  };

  return service;
});

给定的谓词可以计算两个城市之间的距离

%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).

我知道如何从数字列表中找到最小值,但是由于列表写为(CityName,Distance),所以我不确定。

不胜感激。

1 个答案:

答案 0 :(得分:0)

我将使用累加器样式递归,使用模式匹配将这对值拆包。如果两个城市的最小距离相同,则选择点就位,这样就可以找到它们。以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).