본문 바로가기

시스템 해석

오토바이 배달플랫폼, 배민/쿠팡/요기요 AI 배차 시스템 해설

  • 주의
    1. 이 글은 커뮤니티에 올라온 다음 글에 대한 로직 추정이다.
      오늘 디시 배달대행 기사들 갤러리에 올라온 글을 보고 거기에 답변을 쓸까 하다가 원래 긴 글 쓰면 틀딱이라 욕먹거든..
      어디까지나 시스템 root/프로그래머를 경험한 자칭 전문가로서 이런 구조일 수 있다는 하나의 예시이지 정답은 아님
    2. 커뮤니티의 성격이나 저 글의 신빙성과는 별개
      내가 모든 걸 경험해볼 수 없으므로 타인이 현상에 대해 말하면 그걸 듣고 원리를 추정하는 게 효율적이다.
      지지기를 구경도 못한 내가 지지기의 원리를 설명하는 것도 마찬가지.
    3. 기사지수 같은 용어는 임의로 정한 것
      궁금하면 내 다른 글을 읽어보든가 아니면 블로그 안에서 검색
      링크도 귀찮고 남들 다 쓰는 해시태그도 귀찮다.
  • 요약
    1. 구역이 정해져 있다.

      하지만 동(주소) 기준이 아니고 XY 좌표기준이다.
    2. 접속순서도 영향을 준다.

      접속순서라고 했는데 광의로 시간이라 하자.
      시간도 영향을 준다. 어떻게?
      지수연산의 하나의 변수로 영향을 줌.
    3. 구역이동 자체의 지수가감은 없다.

      그러나 기사들은 구역이동에 따라 배차가 다르다는 걸 느낄 수 있는데
      프로그램 전체의 전역변수가 있고
      각 구역별 지역변수가 있는데 지역변수는 모두 다르기 때문이며
      구역이동을 유도하는 로직에 응한 기사를 대상으로 서버차원의 보상이 있기 때문.
    4. 구역이동시 맨 뒷줄에 서지 않는다.

      물론 구역별 메모리블럭(버퍼)의 맨 마지막에 추가되는 건 맞다.
      그러나 거리지수 + 기사지수로 그 메모리 전체를 정렬해서 1번부터 오더를 푸시하기 때문.
    5. 시급에 따라 배차컨트롤을 한다.

      여기 나온 말은 아니지만 배기모 여기저기에 시급 2 찍으면 콜사 같은 얘기가 있는데 원리적으로 맞다.
    6. 거절 패널티는 심각하다.

      역시 여기 나온 말은 아닌데 답답해서
      거절할 수 있게 해놓으니까 딸배들이 거절도 권리인 줄 알고 함부로 거절을 남발한다 는 얘길 이미 했다.
      거절기능을 제공하지 않으면 근로감독이 되고 시비 붙으면 법적으로 노동자로 판결받을 위험이 있기에 이걸 피하고자 마련한 것이지 하기 싫으면 안 해도 좋다 는 말이 아니다.
  • 설명
    1. 구역분할없이 프로그래밍하게 되면
      배차로직이라는 건 오더리스트에서 1개씩 빼서 이걸 어떤 놈에게 제일 먼저 줘야 회사에 가장 이익이 되나 하는 문제다.
      구역분할을 안 하면 오더 1건 연산할 때마다 기사들 전체를 거리지수순으로 정렬한 후 특정거리나 아니면 상위 10개 안에 들어있는 기사를 대상으로 또 기사지수와 합산해 최종순위를 정해야 하는데 할 수 있다.
      할 수 있을 뿐만 아니라 제일 간단하고 또 로직상 구멍이 없다.

      근데 오더가 많거나 기사가 많거나 하면 시스템 부하가 너무 큼.

      따라서 그림처럼 XY 좌표의 일정 크기로 맵을 나누고 하나하나가 독립된 메모리블럭(버퍼)으로 되어 있다.
      동이름이 아니라 사각형인 이유는 동 이름으로 하면 그 동에 속한 GPS 의 XY 좌표를 모조리 또는, 적어도 점을 적분해서 면으로 판단할 수 있을 만큼 많이 저장하고 있어야 함(주소구획은 꼬불꼬불하니까).

      1번 구역에서 오더가 1개 들어오면
      1번 구역의 버퍼에 등록된 기사만을 대상으로 첫째 거리지수, 2번째 기사지수 연산하고 합해서 1등부터 푸시한다.
      그림에서 이 오더는 3사람 모두 연산의 대상이 된다. 누가 1등 하느냐의 문제만 남음.

      2번구역에서 뜬 오더는?
      1번기사는 아예 연산의 대상이 아님.

      이 구조에서 3번기사는 아주 절묘한 위치에 대기타고 있기에 4구역 어디서 나온 오더든 일단 줄까말까 계산하는 대상이 됨. 5시나 7시 등 사각형 구석탱이에서 뜬 오더라면 거리지수가 낮은게 문제지 일단 연산의 대상은 된다는 말.

      이렇게 되면 이제 내가 앞서 구역분할없이 메모리 전체를 연산할 땐 없던 로직상 구멍 이 발생한다.
      예를 들어 일원지하차도에서 뜬 오더는 1번기사가 제일 가깝지만 로직상 구멍으로 인해 1은 제외되므로 기사 3번에게 감.
      당연히 이 프로그래밍을 몇 년 한 사람하고 술먹고 자다 일어나 디시 보다가 바로 쓰는 틀딱딸배하고는 수준이 다르다.
      요점은 어떤식으로든 연산부하를 줄이기 위한 차단벽은 설계되어 있다는 것이고 내가 그 차단벽 건너편에 있으면 다소 배차가 비합리적으로 느껴질 수 있다는 점.
    2. 기사를 떠나게 만들면 회사 손해
      회사로 치면 일찍 출근하고 늦게 퇴근하는 건데 당연히 앱 켜고 끄는 시간도 지수연산에 변수로 작용하며
      너무 오래 길바닥 대기타는 걸 아무 로직없이 내비두면 열받아서 앱끄고 가버렸는데 재수없게도 그때부터 콜 터진다? 이렇게 되어도 회사 손해.
      다만 지수가감의 일부.
    3. 구역이동을 유발하는 로직은 있다.
      원문에서는 콜 들고 구역 이동하면 똥콜 잡은 거라 배려해주는 차원에서 콜이 더 잘 뜨는 느낌 이라 했는데 그 지역의 단가를 올리고 매우 바쁨 으로 표시하는 1차적 로직이 있지만 이걸로 멀리 있는 기사가 이동한다는 보장이 없다.
      아무도 이동 안 하면?
      플랫폼이 음식값 물어줘야 하므로 회사 손해.

      예를 들어 위 그림이 서버 전체 상황이라 가정하고 군자역에서 오다가 딱 뜨면
      3명 중 누군가를 그쪽으로 가게 만들어야 한다. 일대에서는 강배.
      지금 저 상황에서는 3명 모두 아예 연산대상에서 제외된 상태이므로 간단히, 인성급의 프로그래머가 쉽게 구현하는 건 관제 클릭질인데 그렇지 않다.
      난 오더지수도 이미 구현되었다는 얘기를 여러번 했다.
      다만 픽업지와 목적지까지 같은 오더가 통계상 유의미할 만큼 반복되는 DB 는 아직 수집하지 못했을 것이므로(그럴 확률도 낮다) 서로 다른 오더에 어떻게 변수를 적용하여 지수순으로 줄세울 것인가... 하는 문제가 쉽지는 않을 것.
      기사들의 배차순위에서 지수 낮은 기사가 지수 높은 기사를 픽업지에서 가까운 정도에 따라 역전하고 우선순위가 될 수 있듯이
      오더도 지수 낮은 오더가 요금이 높으면 쉽게 말해 제일 먼저 처리되어야 할 오더리스트 1번으로 올라가게 된다.
      프로그래밍은 로직에 일관성 없이 그때그때 땜빵하고 변수를 따로 두면 나중에 해골아파 아무도 손 못 대게 되므로 당연히, 오더지수 또한 기사지수를 구현한 설계와 동일하다.

      설계를 유지하면서 클릭질이 아니라 프로그래밍으로 해결하려면
      군자역 오더는 위 그림의 메모리블럭 밖에서 뜬 것이라 3명의 기사와 연산하고 자시고 할 게 아예 없는데 오더지수를 올려서 마치 기사의 영역 반경을 넓히듯 오더반경을 키워 오더가 메모리블럭 1과 2번에 걸치게 만들면?
      기사 3명 모두에게 이 오더가 연산의 대상이 된다.
      이 때 군자역 오더는 다른 4구역 안의 어떤 오더보다도 오더지수가 높아서 각 기사들에게 제일 먼저 푸시된다.(그렇게 되도록 오더지수를 계속 올리는 함수 존재)
      가격은 좋은데 픽업지가 너무 멀어서 3명 다 거절.
      프로그램은 오더지수가 많이 낮은 나머지 모든 오더를 블록킹시키고 다시 군자동 오더의 지수를 좀 더 올려서(조건은 같기에 결국 요금을 더 올려서) 기사 3명에게 트라이.
      이 과정에 거절을 때리면 평소보다 기사지수 감점이 더 심하지만 어쨌든

      이걸 여러번(회사가 음식을 물어주는 손해 + 알파와 비견할 만큼) 반복하는 동안 누군가 이걸 잡게 되면
      나머지 오더의 블로킹이 풀리고 그 중 군자역 오더와 비슷한 경로가 있다면 기사지수가 꼴찌일지라도 무시하고 이걸 잡아준 기사에게 제일 먼저 추가 푸시가 들어감.(AI 가 하는 보상)

      지금까지 시나리오를 사실상 AI 의 목표는 군자역이 아니라 3명 중 1명을 중량구로 유인 하기 위한 로직이었다고 상상하면 어떨까?
      1. 기사들이 몰려 있는 영역 밖의 어떤 오더에 임의로 지수가중을 줘서 오더반경이 기사들 영역에 겹치도록 만든다.
      2. 영역 안의 오더는 지수를 낮추어서 일시적인 블로킹 상태에 만든다.(이 시점에 4개의 영역에서 오더 100개가 뜨더라도 위 기사들에게는 보이지 않고 군자동만 신나게 들락날락.)
      3. 누군가 이걸 잡으면 AI 가 목표로 하는 경로상에서(예제에서는 중량구) 이 기사의 기사지수는 무시되며 서버 1등과 같은 특권을 받아 제일 좋은 오더가 추가로 푸시된다.
      물론, 이렇게 구현되어 있다는 얘기는 절대 아니지만 당신들이 말하듯 수동 클릭질 노가다도 아님. 프로그래밍으로 할 수 있음.
    4. 구역이동은 이렇게 구현된다.
      각 기사들에겐 4칸의 영역 버퍼가 있고(4원소 배열) 1번은 1개만 채워져 있으며 2번은 2개, 3번은 4개가 다 차 있다.

      위 예제 설계에서 1번기사가 2번 영역을 거쳐 4번 영역으로 이동할 때
      2번에 진입할 때 배열 2원소에 2의 영역고유번호 추가
      1번을 완전히 이탈할 때 배열 1의 영역버퍼로 가서 그 영역의 기사리스트에서 1번 삭제, 1원소 = null
      4번으로 진입하면 4원소 추가
      2번에 걸쳐있다면 2번도유지, 4번도 유지
      따라서 2번영역에서 뜨는 오더도 받을 확률이 있고 4번 오더도 있지만 1번은 아예 제외.

      구역별 지역변수가 다르다는 말은 예를 들어
      2번은 교통흐름이 복잡하고 4번은 좀 좋지?(내가 서울을 잘 모른다.) 이건 배민이 그간 수집한 기사들 수행DB 상 답이 나오는데 하여튼 그렇다 치고 이 때
      2번영역의 거리지수는 4번 영역의 거리지수보다 민감하다.
      민감하다는 말은 1번기사의 기사지수가 1000점이고 2번기사의 기사지수가 2000점일 때
      4번영역에서 뜬 오더의 거리지수가 이 기사지수를 뒤집고 1번이 먼저 잡으려면 픽업지에서 2번보다 1번이 1km 가까우면 되었었는데
      이게 2번영역에서 벌어지는 상황이라면 500m 만 가까워도 지수역전으로 1번이 먼저 푸시 받음.
      고급 프로그래밍에서 전역상수는 거의 없다.
    5. 시급 컨트롤은 이렇게 된다.
      가급적 많은 기사를 모집하고 그 기사들이 앱을 ON 으로 오래 유지하게 만들기 위한 로직
      소수의 괴수를 육성하는 로직
      기사가 많아야 회사에 이익이라는 건 뭐 더 설명할 게 없으니 너무 못 번 기사에게 위 2번의 시간변수가 개입해서 지수에 가산점을 주는 로직이 있다 정도로 하고 넘어가자.
      소수의 괴수 육성 이라니 뭔 소린가...
      내가 여러 글에서 얘기했는데... 당신이 일대 지사장이라면 광고낼 때, 면접볼 때, 하꼬기사가 못 벌었다고 투덜거릴 때... 우리 지사 탑은 작년 1억입니다가 좋겠어 아니면 5000만원입니다가 좋겠어?
      야! 김씨는 오늘 100개 쳤는데 너네들은 뭐하냐? 맨날 불만만 많아가지고선!!....
      이 얼마나 간편한 무기인데 이걸 포기해??

      작년 배민에서 뭐 뉴욕까지 갔습니다/파리까지 갔습니다 면서 수행건수와 거리 같은 게 있었지?
      이것도 그냥 재미로 보라고 만든 게 아니라 프로그램 로직상 일대지사장의 심리가 그대로 녹아있다는 얘기임.

      심리만 얘기하면 좀 긴가민가 할텐데 현실적으로도 꼭 필요하다.
      괴수육성 없이 되는대로 내비두면 비오는 날 작살남.
      괴수의 대상이 되기까지 우선 출퇴근/처리건수/수락... 등 모든 지수가 빵빵해야 하지만 된 후에도 기사가 컴퓨터를 모르고 로직은 모르지만 진짜 돌대가리가 아닌 한 뭔가 특혜를 받고 있다 는 느낌이 들게끔 밀어주면 혹시 그 특혜에서 빠질까봐 비오는 날 못 제낌.
      알지? 비오는 날 괴수 하나가 오합지졸 5를 커버친다는 거.
      거기다 대부분 출근율이 떨어지므로 실제로는 괴수 하나가 일당백임.
  • 뇌피셜
    1. 이 모든 건 테스트모듈이 있다.
      예를 들어 위 그림에서 기사가 어떤 영역에 몇 개나 걸쳐 있는가를 모두 획일적으로 반경 1km 로 그렸는데 고급 프로그래밍은 이렇지 않다.
      그럼 이 경우 반경을 어케 정할 것인가? 프로그래머가 오토바이를 타볼 수도 없고.
      기사들로부터 수집한 DB 로 연산한다.
      이 말은 기사들로부터 수집하기 위해 다소 무리한, 불합리한 오더를 꽂아보는 로직이 있다.
      요즘 말하는 AI 라는 것들은 웹에서 이미 만들어진 것을 DB화하는 것 뿐만 아니라 현재 프로그램 앞에 앉아 있는 인간의 반응을 보고 데이타+1 을 하며 만약 반응이 없으면 쓰잘데기 없는, 불합리한, 무리한 자극을 주어 인간이 반응하도록 유도를 하는데

      위 예제에서 8km 떨어진 픽업지 성남 시흥동을 3번기사에게 꽂아봄.
      이 때 3번기사가 기사지수 서버 1위인데 거절을 하면 매우 신뢰성 높다 고 판단하여 3번 위치에서의 연산 반경이 줄어들지만
      3번기사지수가 서버 꼴찌라면 반경이 줄어들지 않고 거절에 따른 지수만 까임. 서버는 다음기사에게 또 이 오더를 꽂아서 반응을 보는 거지...
      물론 커뮤니티 말대로 관제가 클릭하는 것도 있다. 그러나 일반적으로 엉터리 배차로 보이는 것들 중 대부분은 테스팅모듈임. 프로그램이 최상의 변수와 함수를 만들어가는 과정.
  • 잡담
    1. 이게 내가 뭐하는 짓이냐.
      자동매매 프로그래밍을 다시 손대게 되면 이런 글 쓸 시간 없다.
      이런 글 쓴다는 얘긴... 할 거 안 하고 논다는 얘기지.
      희한하단 말야. 내 혈액형이 지롤인가 뭐든지 80% 정도 게이지가 차면 진짜 하기싫어.
Recent Posts
Popular Posts
Tags
더보기
Recent Comments