오늘 프로젝트의 발표를 맞게된 홍지용입니다.
목차는 다음과 같습니다.
먼저 수리최적화 모형에 대한 설명입니다.
저희 조가 설정한 의사결정 변수에 대해 설명해드리겠습니다.
x는 차량 v가 i에서 j로 이동했는지 여부를 나타내는 변수입니다.
z는 고객의 도보 이동 여부를 나타내는 이진 변수입니다.
w는 고객 o가 탑승노드로 p를 선택해서 차량 v에 탑승 했는지 여부를 나타내는 이진 변수입
니다.
srv(d,v)는 차량 v가 목적지 d에서 고객을 하차 시켰는지의 유무를 나타내는 이진 변수입니
다.
a는 차량 v가 노드 I에 도착하는 시간을 나타내는 변수입니다.
g는 차량 v가 I에서 j노드로 이동할 때 운송한 고객 수입니다.
u는 차량 v가 노드 I에서 고객을 탑승시켰는지 여부를 나타내는 이진 변수입니다.
getoff는 차량 v가 I에서 하차시킨 고객 수를 의미합니다.
다음으로는 제약식에 관한 설명입니다.
첫 번째 가정과 두 번째 가정에 대해서는 별다른 수식상의 제약은 없습니다.
세 번째 가정입니다,
세 번째 제약식은, 의사결정 변수 srv를 이용해 표현했습니다. srv는 아래와 같이 파라미터
델타와 의사결정변수 w를 이용해 설정했습니다.
네 번째 가정입니다.
각 고객이 도보 이동거리 한계 내에서 하나의 승차지를 선택하도록 하였습니다.
다섯 번째 가정은 도보 이동시간을 고려하지 않기 위한 가정이므로 넘어가겠습니다.
여섯 번째 가정입니다. 차량이 각 아크에 대해 운송한 양이 q를 넘지 못하도록 하여 최대 용
량을 제한했습니다.
7번째 가정은 차량 v가 d에 하차시켜야 하는 고객이 있을때만 타임윈도를 만족하도록하여 구
현했습니다.
8번째 가정입니다. 고객이 선택한 승차지까지의 도보 비용이 U를 넘지 못하도록 설정하였습
니다.
9번째 가정입니다. 모든 차량에 대한 반드시 depot에서 출바하고 복귀하도록 제약식을 설정
했습니다.
추가적인 제약식입니다.
위에서부터,
같은 노드를 연속적으로 방문하지 못하도록 하는 제약,
고객이 탑승 노드로 선택한 노드에 차량이 반드시 방문하도록 하는 제약,
의사결정 변수 w를 설정하는 제약,
서비스 타임을 반영하기 위한 의사결정 변수 u를 설정하는 제약입니다.
이어서
흐름보존 제약,
depot에서 출발하고 복귀하는 차량은 빈 차 상태여야 한다는 제약
고객의 승하차 노드에 대한 서비스 타임을 반영하는 제약입니다.
이번에는 휴리스틱 알고리즘에 대해서 설명해 드리겠습니다.
사용한 언어는 c++입니다. 1분 내에 빠르게 해를 찾아야 하기 때문에 속도가 빠른 언어중 익
숙한 c++을 선택했습니다.
메타 휴리스틱스 알고리즘은 alns를 선택 했습니다. 다양한 연산자를 도입해서 복잡한 제약에
대응할 수 있다고 생각하여 선택했습니다.
수도 코드를 보면서 알고리즘에 대한 전반적인 설명을 해드리겠습니다.
먼저 alns 메인 루프에 진입하기 전에 데이터 파싱부터 초기해 생성 과정입니다.
첫 번째 박스는 input/output 데이터에 대한 notation입니다.
다음으로 txt 파일로부터 데이터를 load하고 데이터를 파싱하여 parmeter 객체에 담습니다.
customer에 대한 정보는 이후 재사용성을 고려하여 별도의 객체로 만들어 demand와 time
window, 후보 탑승 노드 등의 정보를 담습니다.
초기해는 모두 차량에 고객을 한명씩 할당하는 것부터 시작합니다. 그리고 남은 고객들을 수
요과 타임 윈도우 순으로 정렬하여 할당합니다. 이때 초기해는 infeasible해도 상관없습니다.
이제 alns 메인 루프입니다.
메인루프에 진입하면, 먼저 현재 솔루션에서 고객을 삭제하는 연산을 진행합니다. 이때, 저희
알고리즘에서 사용한 삭제연산자는 random(무작위), path_aware(경로 유사성 기반 제거),
worst(비용감소가
큰
고객
제거),
shaw(시간창과
거리
유사도가
높은
묶음
제거),
boarding_mutation(고객의 탑승 노드를 바꾼 뒤 제거), overload(적재량 초과에 크게 기여한
고객 제거), force_redistribution(차량 분산을 위해 고객을 일부 차량에서 제거) 등이 있습니
다. 각 이터레이션에서 연산자는 적응형 가중치를 바탕으로 선택됩니다.
다음으로 차량에 미할당된 고객들을 삽입하는 과정입니다. greedy삽입, regret_k삽입, 빈차량
우선 삽입 연산자 등이 있습니다. 삭제 연산자와 마찬가지로 적응형 가중치를 바탕으로 선택
됩니다.
다음으로 해의 평가 및 수락 과정입니다.
위에서 삭제 및 삽입 연산자를 거쳐 생성된 후보해에 대해서 feasibility와 cost를 계산합니
다. 비용이 감소하거나, infeasible에서 feasible로 넘어가는 경우는 무조건 해를 수락합니다.
이때 탐색 범위를 넓히기 위해서 feasilbe에서 infeasible로 넘어가는 경우는 1%확률로 허용
하도록 했습니다. 그 외의 경우는 시뮬레이티드 어닐링을 기반으로 확률을 계산하여 해를 수
락하도록 하였습니다.
이때 초기 온도는 100으로 설정했으며, 이터레이션을 반복할 때, 온도는 0.9999를 곱해서 낮
아지도록 하였습니다.
각 이터레이션의 마지막에는 2-opt 방식으로 loaca search를 진행합니다. 마지막으로 각 연
산자에 대한 가중치를 updata하고 다음 iteration으로 넘어갑니다.
flow chart에 대한 설명은 sudo code와 중복되기 때문에 넘어가겠습니다.
이제 알고리즘이 가정사항을 어떻게 만족시키는지 설명하겠습니다.
1,2번 가정은 파라미터에 내제되어 있기 때문에 넘어가겠습니다.
3번 고객의 destination 노드는 무조건 방문되어야 한다는 가정입니다. 저희가 알고리즘에서
는 차량에 고객을 할당할 때, 반드시 픽업 노드와 드롭 노드를 포함하도록 했습니다. 따라서
고객이 할당된 이상, 해당 고객의 목적지는 반드시 어떤 차량 경로에 존재하게 됩니다. 미할
당 고객은 패널티 부여 및, 후보해에 대한 feasibility를 계산할 때 배제 되기 때문에 결과적
으로 3번 가정을 만족시킨 해를 출력하게 됩니다.
4번 가정은, 고객이 도보 한계 내에서 이동할 수 있는 후보 탑승 노드를 벡터로 만들어 두고,
그 안에서 탑승 노드를 고르게 하여 만족시킵니다.
5번 가정은 도보이동시간을 고려하지 않도록 하기 위한 가정이므로 넘어가겠습니다.
6번 가정은 모든 차량이 동일한 적재 용량을 가진다는 가정입니다. 전체모델에서 공유되는 고
정 용량인 Q값을 설정하여 적재량 체크 로직에 사용되도록 하였습니다.
7번은 고객 별로 인스턴스를 만들어서 각 고객의 time window를 저장하여 관리했습니다. 후
보해의 타임 윈도우를 체크할 때, 고객 인스턴스의 time window를 불러와서 비교하도록 하
였습니다.
8번 가정입니다. 이미 4번 가정에서 만족하는 것을 보였으므로 넘어가도록 하겠습니다.
9번 가정입니다. 모든 차량의 경로에 대해 비용이나 위반사항을 확인할 때, 시작 및 종료 노
드를 depot로 설정해놓았기 때문에 모든 차량이 depot에서 출발하도록 설계되어 있습니다.
다음으로 결과 해석 및 비교입니다.
small size의 data1에 대해서는 111의 objective 값이 도출되었습니다. 시각화 자료를 보시
면 서브 투어없이 고객을 잘 운송시킨 것을 확인할 수 있습니다. 1번 노드에 위치했던 고객만
7번 노드로 도보이동 후 탑승하였습니다.
data1 솔루션의 차량이동 및 각 노드에 도착한 시간입니다. 고객의 타임윈도우를 모두 만족시
키는 것을 확인했습니다.
small size의 data2에 대해서는 107의 objective 값이 도출되었습니다. 시각화 자료를 보시
면 서브 투어없이 고객을 잘 운송시킨 것을 확인할 수 있습니다. 1번 노드의 고객은 6번으로
2번 노드의 고객은 8번으로 도보이동하여 탑승했습니다.
data2 솔루션의 차량이동 및 각 노드에 도착한 시간입니다. 고객의 타임윈도우를 모두 만족시
키는 것을 확인했습니다.
다음으로 largedata를 휴리스틱 알고리즘으로 해결한 결과입니다.
첫 번째 largedata에 대해서 383의 솔루션을 얻었습니다. 이때 사용하도록 한 차량수는 6대
입니다. 총 런타임은 55.03초 였습니다. 도보 이동 후 탑승 한 고객은 전체 고객 23명 중 20
명이었습니다. 각 차량에 대한 이동 경로 및 각 노드에 대한 도착 시간 정보입니다. 6대의 차
량이 모두 타임 윈동 및 적재 용량 위반없이 모든 고객을 운송한 것을 확인했습니다.
두 번째 largedata에 대해서 268의 솔루션을 얻었습니다. 이때 사용하도록 한 차량수는 6대
입니다. 총 런타임은 55.04초 였습니다. 도보 이동 후 탑승 한 고객은 전체 고객 13명 중 10
명이었습니다. 각 차량에 대한 이동 경로 및 각 노드에 대한 도착 시간 정보입니다. 6대의 차
량이 모두 타임 윈도우 및 적재 용량 위반없이 모든 고객을 운송한 것을 확인했습니다.
마지막으로 xpress-mp와 휴리스틱 코드에 대한 비교입니다.
small size의 인스턴스에 대해서 테스트 해봤습니다. 이때 휴리스틱 코드는 800iter을 탐색하
도록 하였으며, 결과적으로 objective value의 gap이 0이고, 동일한 경로의 솔루션을 도출하
는 것을 확인했습니다. 런타임은 휴리스틱 알고리즘이 약 14배 가량 빨랐습니다.
이상으로 발표를 마치겟습니다. 감사합니다.