Blog

  • 당신이 모르는 그 곳 안동

    여행을 한 참 앞두고 관련 정보를 얻을까 해서 상호대차하였다. 리뷰의 적절성은 직접 방문해야만 알 수 있을테니 일단은 기록을 위하여 기록한다. 🙂

  • 주식 시장의 17가지 미신

    이 사람의 다른 책을 보다가 이 사람의 책을 좀 읽어보기로 결심했다. 그래서 도서관에서 바로 빌릴 수 있는 책을 선정했다. 17가지가 많다고 생각되면 첫 번째 것의 일부를 명심해야 한다. 첫 번째에서 30년 장기 투자를 설명하고 있다. 10년도 짧은 것이다. 이 책은 꼭 읽어보는게 좋다. 어렵지 않게 술술 읽힌다.

  • 여행 이동 경로 최적화

    지난 번 공주와 서천 여행에서 여행 경로를 최적화하지 못해서 조금 시간이 촉박했다. 그래서 이번 경주 여행은 사전에 경로를 최적화해보고 싶었다. 여행 일정이야 얼마든지 변경되지만 사전에 최적 경로는 설정해 두어도 괜찮으니까 말이다.

    시작점(집)과 도착지(숙소)가 정해져 있다. 그리고 중간에는 사전에 골라둔 경유지들이 있다. 그리고 이동 시간을 최소화 할 수 있는 경유지 순서를 정하는 것을 문제로 한다. 이렇게 문제를 정의해두면 이것은 외판원 순회 문제(traveling salesman problem, TSP)와 유사해 진다.

    경유지가 3군데라면 3!(=6) 조합을 검토해 보아야 한다. 그러면 다음과 같은 방식이 될 것이다.

    시작 – 경유지1 – 경유지2 – 경유지3 – 목적지

    국내에서 쉽게 이용할 수 있는 지도 API는 T map, 카카오, 네이버가 있다. 이 중에서 네이버는 설명을 알아볼 수 없으므로 제외한다. 카카오의 경우 두 지점 사이의 이동 시간을 계산해주는 기능은 없다. 그러므로 T map 을 이용하도록 한다.

    T map API는 SK open API (https://openapi.sk.com/)를 통해서 키를 발급받을 수 있다. 앱을 만들어서 사용하지 않는다면 개인 사용자가 무료 사용량을 넘기는 것도 쉽지 않을 것이다. 기술 문서가 불친절한 것은 아닌데 웹으로 구현하는 부분은 Javascript를 잘 알지 못하면 매우 진입 장벽이 높다. 그렇기 때문에 여러 부분으로 나누어서 프로그래밍 난이도를 낮추도록 한다.

    T map API에서 경유지를 포함하여 이동 시간을 계산할 수는 있다. 그런데 경유지 지정하는 부분에서 손이 좀 많이 간다. 시작 지점과 도착 지점을 이용해서 개별 이동 시간을 구한 후 더하는 방법으로 구현하도록 한다.

    여기까지 도달했으면 정말 중요한 것을 확인해야 한다. 바로 여러 지점의 정확한 좌표이다. 보통 유사 검색으로 결과를 제공받는다. 그러면 비슷한 이름 혹은 위치의 여러 결과를 얻게 된다. 비슷한 위치에 있다면 별 문제는 없다. 그런데 비슷한 이름이 서로 다른 지역에 있다면 결과가 매우 어긋나게 되므로 이를 확인해야 한다.

    url = 'https://apis.openapi.sk.com/tmap/pois'
    params ={
    	'version' : 'F00',
    	'searchKeyword' : loc,
    	'appKey' : key
    }
    data = requests.get(url, params=params, timeout=10)
    response = json.loads(bytes.decode(data.content))

    이러면 아래의 같은 결과를 얻을 수 있고, 이 중에서 frontLon과 frontLat이 출입 가능한 장소의 WGS84 좌표이다.

    {'id': '693489', 'pkey': '69348901', 'navSeq': '1', 'collectionType': 'poi', 'name': '천주교우곡성지', 'telNo': '054-673-7093', 'frontLat': '36.94561570', 'frontLon': '128.82953881', 'noorLat': '36.94550459', 'noorLon': '128.82928884', 'upperAddrName': '경북', 'middleAddrName': '봉화군', 'lowerAddrName': '봉성면', 'detailAddrName': '우곡리', 'mlClass': '1', 'firstNo': '150', 'secondNo': '1', 'roadName': '', 'firstBuildNo': '', 'secondBuildNo': '', 'radius': '0.0', 'bizName': '', 'upperBizName': '여행/레저', 'middleBizName': '관광명소', 'lowerBizName': '문화유적지', 'detailBizName': '기타', 'rpFlag': '16', 'parkFlag': '1', 'detailInfoFlag': '0', 'desc': '', 'dataKind': '', 'zipCode': '', 'newAddressList': {'newAddress': [{'centerLat': '36.94550459', 'centerLon': '128.82928884', 'frontLat': '36.94561570', 'frontLon': '128.82953881', 'roadName': '', 'bldNo1': '', 'bldNo2': '', 'roadId': '', 'fullAddressRoad': '경북 봉화군 봉성면'}]}, 'evChargers': {'evCharger': []}}

    다음에는 시작 지점과 도착 지점을 기준으로 소형 차량의 이동 시간을 구하도록 한다.

    url = 'https://apis.openapi.sk.com/tmap/routes'
    
    params ={
    	'version' : '1',
    	'reqCoordType' : 'WGS84GEO',
    	'resCoordType' : 'WGS84GEO',
    	'carType' : '1',
    	'endX' : endX,
    	'endY' : endY,
    	'startX' : startX,
    	'startY' : startY,
    	'appKey' : key,
    	'totalValue' : '1'
    }
    
    data = requests.get(url, params=params, timeout=10)
    response = json.loads(bytes.decode(data.content))

    이러면 매우 기~인 결과를 확인할 수 있다. 이 중에서 totalTime이 이동 시간(초)이다. 그리고 LineString 으로 이동 경로를 나타내는 WGS84 좌표를 확인할 수 있다.

    {'type': 'FeatureCollection', 'features': [{'type': 'Feature', 'geometry': {'type': 'Point', 'coordinates': [127.12430457889762, 37.38419236522808]}, 'properties': {'totalDistance': 148043, 'totalTime': 7004, 'totalFare': 7300, 'taxiFare': 136620, 'index': 0, 'pointIndex': 0, 'name': '', 'description': '성남대로 을 따라  방면으로 319m 이동', 'nextRoadName': '성남대로', 'turnType': 200, 'pointType': 'S'}}, {'type': 'Feature', 'geometry': {'type': 'LineString', 'coordinates': [[127.12430457889762, 37.38419236522808], [127.12287418116846, 37.38320356529847], [127.12245478304723, 37.3829119249148], [127.1220131688769, 37.38247307898179], [127.12171320239246, 37.38225087713673], [127.12168542776442, 37.38222865699216]]}, 'properties': {'index': 1, 'lineIndex': 0, 'name': '성남대로', 'description': '성남대로, 319m', 'distance': 319, '

    개별 경로 이동 시간을 모두 더해서 총 이동 시간을 구하고, 이동 시간이 가장 짧은 경로를 선택해서 전체 이동 시간과 전체 이동 경로를 구하도록 한다.

  • 수학으로 생각하는 힘

    여러 수학적인 내용을 언급하고 있는 책이다. 이 책은 수학적 개념을 상식 수준에서 습득하고 싶은 사람에게 유용할 것 같다.

    검사의 위양성 개념을 설명하면서 항상, 그리고 어느 책에서나 언급하고 있는 베이지안 규칙은 매우 중요하다.

    가장 도움되는 내용으로 ‘최적 정지 전략(optimal stopping strategy)’가 있다. 이 이론은 여러 다른 이름으로도 불리고 있는데, 대표적인 것은 비서 문제이다. 면접 대상자가 n명 있고, 이 면접 대상자에게는 면접이 끝나면 합격과 불합격 여부를 알려주어야 한다. 그렇다면 언제 합격자를 선별해야 하는가이다. 이럴 경우 n/e 에 해당하는 값을 기준으로 하면 된다는 것이다. 자연상수 e가 2.7정도 되고, 1/e는 0.37 정도이다. 적당히 잡으면 대략 1/3 정도는 일단 그냥 상태를 보면서 제낀다. 그리고 1/3 정도부터 이전 사람들보다 좋다는 판단이 든다면 그 사람을 합격자로 한다는 것이다. 어디선가 들어봤던 내용인데, 한 번 더 알게 되어서 좋은 것 같다. 실제 생활에서 이 전략이 가장 도움이 되는 것인 바로 식당을 선별할 때이다. 보통 많아야 3개 정도 옵션을 두니까 1번째에서 상태를 보고 2번째부터 결정하는 것이다.

    더 일반적으로는, 누가 어떤 통계 수치를 내놓으면, 다음 질문들을 스스로에게 던져보라. “비교 수치는 무엇인가?” “동기는 무엇일까?” “이것이 이야기의 전부일까?” 이 세 가지 질문에 답을 얻으면, 통계 수치의 진실성을 판단하는 데 큰 도움이 될 것이다. 그 답을 찾을 수 없다면, 당연히 그 수치는 믿을 수 없는 것이다.

    214페이지