Algorithm/알기 쉬운 알고리즘
2021. 5. 3. 22:56
부분 배낭 문제 (Fractional Kanpsack Problem)
배낭 문제
- n개의 물건이 각 무게와 가치를 가지고 있을 때, 한정된 용량의 배낭에 최대의 가치를 갖도록 넣는 방법에 대한 문제이다.
부분 배낭 문제는 물건을 부분적으로 담는 것이 허용된다.
알고리즘
물건을 부분적으로 담을 수 있으므로, 단위 무게당 가치가 제일 높은 것부터 배낭에 넣는다.
- 만약 통째로 넣을 수 없다면, 넣을 수 있는 만큼만 부분적으로 넣는다.
입력으로 각 물건의 무게와 가치, 배낭의 용량을 받는다.
출력은 배낭에 담은 물건 리스트와 배낭에 담은 가치의 총합이다.
Pseudo Code
FractionalKnapsack(Item *arr, int capacity) { 각 물건의 단위 무게당 가치를 계산한다. 단위 무게당 가치를 기준으로 내림차순 정렬하여 저장한다. int weight = 0; // 배낭에 담긴 무게 int value = 0; // 배낭에 담긴 가치의 총합 Item highest = 단위 무게당 가치가 가장 큰 물건; Item *list; // 배낭에 담긴 물건의 리스트 while (weight + highest.weight <= capacity) { highest를 list에 추가한다. weight += highest.weight; value += highest.value; highest를 arr에서 제거한다. 새로운 highest를 선정한다. } if (capacity > weight) { highest를 (capacity - weight)만큼만 list에 추가한다. value += capacity - weight; } return list, value; }
시간 복잡도
각 물건의 단위 무게당 가치를 계산할 때 O(n) 시간이 걸린다.
정렬할 때 O(nlogn) 시간이 걸린다.
반복문에서 최대 O(n) 시간이 걸린다.
따라서 시간 복잡도는 O(nlogn)이다.
0-1 배낭 문제
부분 배낭 문제의 원형이다.
0/1 배낭 문제라고도 표기한다.
- 0은 물건을 배낭에 넣지 않는다는 뜻이고, 1은 넣는다는 뜻이다.
그리디 알고리즘으로 해결할 수 없고, 다음 알고리즘들로 해결 가능하다.
동적 계획(Dynamic Programming) 알고리즘
백트래킹(Backtracking) 기법
분기 한정(Branch-and-Bound)
'Algorithm > 알기 쉬운 알고리즘' 카테고리의 다른 글
작업 스케줄링(Task Scheduling) (0) | 2021.05.03 |
---|---|
집합 커버 문제 (Set Cover Problem) (0) | 2021.05.03 |
최단 경로 찾기(Shortest Path) (0) | 2021.05.03 |
최소 신장 트리(Minimum Spanning Tree) (0) | 2021.05.03 |
03. 분할 정복 알고리즘 (0) | 2021.04.30 |