Skip to content

Conversation

@Hoyeol-Yoon
Copy link
Collaborator

@Hyelim-P @Hoyeol-Yoon
지난 일요일 회의 때 얘기했던 중점 아이디어 코드

for length, count in sorted(data['lengths'].items()):
print(f" 길이 {length}: {count}개")

def avg_loc(all_orders, all_bundles):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avg_loc 함수: all_bundles를 넣으면, 각 번들의 픽업 지점과 배송 지점의 중점 좌표를 계산해서 return해주는 함수
(픽업 위도, 픽업 경도), (배송 위도, 배송 경도) 형태


return bundles_avg_loc

def haversine_distance(coord1, coord2):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haversine_distance 함수: 두 지점의 위도와 경도를 입력하면 두 지점 사이의 거리를 계산해주는 함수

distance = R * c
return distance

def dist_mat_by_loc(all_bundles_avg_loc):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dist_mat_by_loc 함수: 모든 번들들의 중점 좌표를 입력하면, 이를 통해 번들 간의 거리 matrix를 return해주는 함수. 이때 거리는 픽업, 배송을 모두 고려하여(회의 때 설명한 0.25 가중치 사용하는 그 공식) 하나의 값으로 계산함.

for j in range(i+1, N):
dist = all_bundles_dist_mat[i, j] + all_bundles_dist_mat[i+N, j+N] + (all_bundles_dist_mat[i, i+N] + all_bundles_dist_mat[i, j+N] + all_bundles_dist_mat[i+N, j] + all_bundles_dist_mat[j, j+N])*0.25

heapq.heappush(dist_heap, [dist, i, len(all_bundles[i].shop_seq), j, len(all_bundles[j].shop_seq)])
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

두 번들 간의 거리를 계산하여 heapq에 넣어 거리가 작은 순서로 뽑아낼 수 있게 함

if len_one >= 3:
len_one_heap = [item for item in dist_heap if item[2] == 1 or item[4] == 1]
heapq.heapify(len_one_heap)
dist_heap = len_one_heap
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

길이가 1인 번들이 있는 경우에 우선권을 주기 위한 코드.
그렇다고 모든 길이가 1인 번들을 처리하려고 하면, 마지막 남은 몇개의 번들이 억지로 묶일 가능성이 있어서, 길이가 1인 번들이 3개 일 때 까지만 우선권을 부여.

cant_merge_list = []

while True :
no_walk_bundles = [bundle for bundle in all_bundles if bundle.rider.type != 'WALK']
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뒤에서 발생하는 Bike 부족 문제로 인해 혹시 맨 처음 할당한 walk들은 안 건드리면 어떻게 될까 싶어 추가했던 코드. 결론적으로는 효용이 크지 않은 것 같음. 다시 원래대로 돌리려면 밑에 나오는 no_walk_bundles를 다 all_bundles로 수정하면 됨.

while True :
no_walk_bundles = [bundle for bundle in all_bundles if bundle.rider.type != 'WALK']
single_order_bundles = [(-bundle.cost, bundle) for bundle in all_bundles if len(bundle.shop_seq) == 1 and bundle.shop_seq[0] not in cant_merge_list]
if len(single_order_bundles) <= 3 :
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중점 때와 마찬가지로, 길이가 1인 번들을 전부 다 없애려고 하면, 억지로 묶이는 비효율이 발생하는 것 같아 적당히 3개 정도에서 멈추게 함.

while time.time() - start_time < timelimit and len(all_bundles) > 1:
no_walk_bundles = [bundle for bundle in all_bundles if bundle.rider.type != 'WALK']
iter += 1
num_less_two = len([bundle for bundle in no_walk_bundles if len(bundle.shop_seq) <= 2])
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 번들을 다 고려해서 해체 후 재조립을 하려고 하니 큰 번들들이 대상이 되었을 때는 시간을 너무 많이 잡아먹어서, 일단은 길이가 2 이하인 번들들만 우선적으로 해체 후 재조립을 시행하도록 함. 코드 돌려보면 확실히 개선이 빨리빨리 이루어짐.

no_walk_bundles = [bundle for bundle in all_bundles if bundle.rider.type != 'WALK']
iter += 1
num_less_two = len([bundle for bundle in no_walk_bundles if len(bundle.shop_seq) <= 2])
if num_less_two >= 20:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

적당히 20개 보다 많을 때 까지만 우선권을 줌

bundle_triples = sorted(bundle_triples, key=lambda x: x[0])
return bundle_triples

def find_nearest_triples_with_middle(all_orders, all_bundles):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중점 아이디어를 이용하여 가장 가까운 세개의 번들을 찾는 함수.

#print(f'one bundle : {best_bundles}')

# Try to split into two bundles
if len(merged_orders) > 1:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래 0이었는데 1보다 클 때로 수정(즉, 2명 이상 남아있어야 함.). 두 개로 나누는 상황에서, 만약 배달원이 1명만 남아 있다면 두 개로 못 쪼개야 하는데, 0을 사용하면 그러한 상황을 걸러낼 수 없음.

#print(f'two bundles : {best_bundles}')

# Try to split into three bundles
if len(merged_orders) > 2:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위와 같은 이유에서 0을 2로 수정함.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants