Top 29 Knapsack 알고리즘 The 176 Correct Answer

You are looking for information, articles, knowledge about the topic nail salons open on sunday near me knapsack 알고리즘 on Google, you do not find the information you need! Here are the best content compiled and compiled by the https://chewathai27.com/to team, along with other related topics such as: knapsack 알고리즘 0-1 knapsack 알고리즘, Knapsack 알고리즘 파이썬, Knapsack Problem, 동적 계획 알고리즘 배낭, 배낭문제 백트래킹, 배낭문제 시간복잡도, Knapsack 뜻, Knapsack problem Dynamic Programming


코딩테스트, 중급, knapsack problem
코딩테스트, 중급, knapsack problem


Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem)

  • Article author: gsmesie692.tistory.com
  • Reviews from users: 30159 ⭐ Ratings
  • Top rated: 3.2 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem) 0-1 Knapsack 문제는 다이나믹 프로그래밍 (Dynamic Programming: DP) 이라는 방법을 쓰는 기본적인 문제로 알려져 있다. 알고리즘 문제를 푸는 방법론들 … …
  • Most searched keywords: Whether you are looking for Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem) 0-1 Knapsack 문제는 다이나믹 프로그래밍 (Dynamic Programming: DP) 이라는 방법을 쓰는 기본적인 문제로 알려져 있다. 알고리즘 문제를 푸는 방법론들 … 도둑이 보석가게에 배낭을 메고 침입했다. 배낭의 최대 용량은 W이며, 이를 초과해서 보석을 담으면 배낭이 찢어질 것이다. 각 보석들의 무게와 가격은 알고 있다. 배낭이 찢어지지 않는 선에서 가격 합이 최대가..
  • Table of Contents:
Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem)
Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem)

Read More

[알고리즘] 배낭 문제(Knapsack Problem)

  • Article author: dheldh77.tistory.com
  • Reviews from users: 28288 ⭐ Ratings
  • Top rated: 4.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [알고리즘] 배낭 문제(Knapsack Problem) 배낭 문제(Knapsack Problem) … 배낭 문제란 배낭에 담을 수 있는 무게의 최대값이 정해져 있고,. 일정한 가치와 무게가 정해져있는 짐들을 배낭에 닮을 … …
  • Most searched keywords: Whether you are looking for [알고리즘] 배낭 문제(Knapsack Problem) 배낭 문제(Knapsack Problem) … 배낭 문제란 배낭에 담을 수 있는 무게의 최대값이 정해져 있고,. 일정한 가치와 무게가 정해져있는 짐들을 배낭에 닮을 … 배낭 문제(Knapsack Problem) 배낭 문제란 배낭에 담을 수 있는 무게의 최대값이 정해져 있고, 일정한 가치와 무게가 정해져있는 짐들을 배낭에 닮을 때, 가치의 합이 최대가 되도록 짐을 고르는 방법을 찾는 문제..https://github.com/dheldh77
  • Table of Contents:
[알고리즘] 배낭 문제(Knapsack Problem)

티스토리툴바

[알고리즘] 배낭 문제(Knapsack Problem)
[알고리즘] 배낭 문제(Knapsack Problem)

Read More

[알고리즘 정리] 배낭 문제(Knapsack Problem)

  • Article author: jeonyeohun.tistory.com
  • Reviews from users: 9491 ⭐ Ratings
  • Top rated: 4.5 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [알고리즘 정리] 배낭 문제(Knapsack Problem) Knapsack Problem, 배낭문제는 다이나믹 프로그래밍에서 매우 유명한 문제이다. 어떤 배낭이 있고 그 배낭안에 넣을 수 있는 최대 무게가 K라고 하자. …
  • Most searched keywords: Whether you are looking for [알고리즘 정리] 배낭 문제(Knapsack Problem) Knapsack Problem, 배낭문제는 다이나믹 프로그래밍에서 매우 유명한 문제이다. 어떤 배낭이 있고 그 배낭안에 넣을 수 있는 최대 무게가 K라고 하자. Knapsack Problem Knapsack Problem, 배낭문제는 다이나믹 프로그래밍에서 매우 유명한 문제이다. 어떤 배낭이 있고 그 배낭안에 넣을 수 있는 최대 무게가 K라고 하자. 배낭에 넣을 수 있는 N개의 물건이 각기 다..
  • Table of Contents:

Brute Force Approach

Dynamic Programming

Pseudo code

implementation – BOJ 12865

Algorithm Analysis

댓글

이 글 공유하기

다른 글

[알고리즘 정리] 깊이 우선 탐색(DFS)

[알고리즘 정리] 너비 우선 탐색(BFS)

[알고리즘 정리] 허프만 코드(Huffman Code Problem)

[알고리즘 정리] 그리디 알고리즘(Greedy Alogorithm)

티스토리툴바

[알고리즘 정리] 배낭 문제(Knapsack Problem)
[알고리즘 정리] 배낭 문제(Knapsack Problem)

Read More

Knapsack problem – Wikipedia

  • Article author: en.wikipedia.org
  • Reviews from users: 17899 ⭐ Ratings
  • Top rated: 4.3 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about Knapsack problem – Wikipedia The knapsack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to … …
  • Most searched keywords: Whether you are looking for Knapsack problem – Wikipedia The knapsack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to …
  • Table of Contents:

Contents

Applications[edit]

Definition[edit]

Computational complexity[edit]

Solving[edit]

Variations[edit]

See also[edit]

Notes[edit]

References[edit]

External links[edit]

Navigation menu

Knapsack problem - Wikipedia
Knapsack problem – Wikipedia

Read More

[DP] 배낭 문제 (Knapsack Problem)

  • Article author: velog.io
  • Reviews from users: 35688 ⭐ Ratings
  • Top rated: 3.6 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [DP] 배낭 문제 (Knapsack Problem) 배낭 문제는 n개의 물건과 각 물건 i의 무게 wi와 가치 vi가 주어지고, 배낭의 용량이 C일 때, 배낭에 담을 수 있는 물건의 최대 가치를 찾는 문제 … …
  • Most searched keywords: Whether you are looking for [DP] 배낭 문제 (Knapsack Problem) 배낭 문제는 n개의 물건과 각 물건 i의 무게 wi와 가치 vi가 주어지고, 배낭의 용량이 C일 때, 배낭에 담을 수 있는 물건의 최대 가치를 찾는 문제 … DP의 대표적인 문제
  • Table of Contents:

알고리즘

의사코드

예제

시간복잡도 분석

[DP] 배낭 문제 (Knapsack Problem)
[DP] 배낭 문제 (Knapsack Problem)

Read More

[알고리즘] 배낭 문제 (Knapsack Problem)

  • Article author: propercoding.tistory.com
  • Reviews from users: 34703 ⭐ Ratings
  • Top rated: 4.8 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [알고리즘] 배낭 문제 (Knapsack Problem) 배낭 문제란 담을 수 있는 최대 무게가 정해진 배낭이 있고 각각의 무게와 가치가 주어진 물건들이 주어졌을 때, 배낭에 담은 물건들의 가치가 최대가 … …
  • Most searched keywords: Whether you are looking for [알고리즘] 배낭 문제 (Knapsack Problem) 배낭 문제란 담을 수 있는 최대 무게가 정해진 배낭이 있고 각각의 무게와 가치가 주어진 물건들이 주어졌을 때, 배낭에 담은 물건들의 가치가 최대가 … 목차 배낭 문제란? 배낭 문제란 담을 수 있는 최대 무게가 정해진 배낭이 있고 각각의 무게와 가치가 주어진 물건들이 주어졌을 때, 배낭에 담은 물건들의 가치가 최대가 되도록 하게 물건을 고르는 방법을 찾는..
  • Table of Contents:

태그

관련글

댓글0

최근글

인기글

태그

전체 방문자

티스토리툴바

[알고리즘] 배낭 문제 (Knapsack Problem)
[알고리즘] 배낭 문제 (Knapsack Problem)

Read More

0-1 Knapsack Problem | DP-10 – GeeksforGeeks

  • Article author: www.geeksforgeeks.org
  • Reviews from users: 4139 ⭐ Ratings
  • Top rated: 3.5 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about 0-1 Knapsack Problem | DP-10 – GeeksforGeeks 0-1 Knapsack Problem | DP-10 … Given weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value … …
  • Most searched keywords: Whether you are looking for 0-1 Knapsack Problem | DP-10 – GeeksforGeeks 0-1 Knapsack Problem | DP-10 … Given weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value … Data Structures,Algorithms,Python,C,C++,Java,JavaScript,How to,Android Development,SQL,C#,PHP,Golang,Data Science,Machine Learning,PHP,Web Development,System Design,Tutorial,Technical Blogs,School Learning,Interview Experience,Interview Preparation,Programming,Competitive Programming,SDE Sheet,Jobathon,Coding Contests,GATE CSE,Placement,Learn To Code,Aptitude,Quiz,Tips,CSS,HTML,jQuery,Bootstrap,MySQL,NodeJS,React,Angular,Tutorials,Courses,Learn to code,Source codeA Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
  • Table of Contents:

Related Articles

C++

C

Java

Python

C#

PHP

Javascript

C++

C

Java

Python

C#

PHP

Javascript

C++

Java

Python3

C#

Javascript

C++

Java

Python3

C#

Javascript

C++

Java

Python3

C#

Javascript

Start Your Coding Journey Now!

0-1 Knapsack Problem | DP-10 - GeeksforGeeks
0-1 Knapsack Problem | DP-10 – GeeksforGeeks

Read More

[알고리즘 트레이닝] 5장 – 동적계획법과 냅색(Knapsack) (백준 12865번 평범한 배낭 문제로 살펴보기) | ChanBLOG

  • Article author: chanhuiseok.github.io
  • Reviews from users: 36825 ⭐ Ratings
  • Top rated: 4.0 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [알고리즘 트레이닝] 5장 – 동적계획법과 냅색(Knapsack) (백준 12865번 평범한 배낭 문제로 살펴보기) | ChanBLOG 짐 싸기 문제(Knapsack)는 동적 계획법으로 풀 수 있는 경우가 많습니다. 여러 물건이 있을 때, 특정한 조건을 만족하는 조합을 구하는 문제입니다. 백준 온라인 저지의 … …
  • Most searched keywords: Whether you are looking for [알고리즘 트레이닝] 5장 – 동적계획법과 냅색(Knapsack) (백준 12865번 평범한 배낭 문제로 살펴보기) | ChanBLOG 짐 싸기 문제(Knapsack)는 동적 계획법으로 풀 수 있는 경우가 많습니다. 여러 물건이 있을 때, 특정한 조건을 만족하는 조합을 구하는 문제입니다. 백준 온라인 저지의 … 컴퓨터/IT/알고리즘 정리 블로그
  • Table of Contents:
[알고리즘 트레이닝] 5장 - 동적계획법과 냅색(Knapsack) (백준 12865번 평범한 배낭 문제로 살펴보기) | ChanBLOG
[알고리즘 트레이닝] 5장 – 동적계획법과 냅색(Knapsack) (백준 12865번 평범한 배낭 문제로 살펴보기) | ChanBLOG

Read More

[알고리즘 – 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제, 분할 가능한 배낭 문제)

  • Article author: hi-guten-tag.tistory.com
  • Reviews from users: 11772 ⭐ Ratings
  • Top rated: 3.7 ⭐
  • Lowest rated: 1 ⭐
  • Summary of article content: Articles about [알고리즘 – 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제, 분할 가능한 배낭 문제) 1. 0-1 KnapSack Problem이란? 도둑이 배낭을 메고 보석 가게에 들어왔다. 훔친 보석의 총 무게가 배낭의 용량 W를 초과하면 배낭이 찢어진다. …
  • Most searched keywords: Whether you are looking for [알고리즘 – 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제, 분할 가능한 배낭 문제) 1. 0-1 KnapSack Problem이란? 도둑이 배낭을 메고 보석 가게에 들어왔다. 훔친 보석의 총 무게가 배낭의 용량 W를 초과하면 배낭이 찢어진다. 1. 0-1 KnapSack Problem이란? 도둑이 배낭을 메고 보석 가게에 들어왔다. 훔친 보석의 총 무게가 배낭의 용량 W를 초과하면 배낭이 찢어진다. 각 보석의 무게와 값어치는 알고 있다. 이때 밤손님의 딜레마는 훔친..Hallo!
  • Table of Contents:
[알고리즘 – 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제 분할 가능한 배낭 문제)

1 0-1 KnapSack Problem이란

2 Fractional KnapSack Problem (분할 가능한 배낭 문제)

3 0-1 KnapSack Problem (0-1 배낭 문제)

티스토리툴바

[알고리즘 - 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제, 분할 가능한 배낭 문제)
[알고리즘 – 이론] 0-1 KnapSack Problem and Fractional KnapSack Problem (0-1 배낭 문제, 분할 가능한 배낭 문제)

Read More


See more articles in the same category here: Chewathai27.com/to/blog.

Dynamic Programming: 배낭 채우기 문제 (Knapsack Problem)

도둑이 보석가게에 배낭을 메고 침입했다.

배낭의 최대 용량은 W이며, 이를 초과해서 보석을 담으면 배낭이 찢어질 것이다.

각 보석들의 무게와 가격은 알고 있다.

배낭이 찢어지지 않는 선에서 가격 합이 최대가 되도록 보석을 담는 방법은?

흔히 알고리즘을 배울 때 자주 등장하는 문제 중 하나인 배낭 채우기 문제 (Knapsack Problem) 이다. 그 중에서도 보석을 자를 수 있다고 가정하는 Fractional Knapsack 문제와 자를 수 없다고 가정하는 0-1 Knapsack 문제가 있는데, 전자보다는 후자가 주로 다루어진다.

0-1 Knapsack 문제는 다이나믹 프로그래밍 (Dynamic Programming: DP) 이라는 방법을 쓰는 기본적인 문제로 알려져 있다. 알고리즘 문제를 푸는 방법론들에 대해서 아직 잘 모르는 상태에서 이 문제를 보면 딱 생각나는 방법은 두 가지 정도가 있을 것이다.

1) 모든 경우의 수를 넣어본다 (Brute-Force)

n개의 보석이 있다고 치면, n개 보석으로 만들 수 있는 가능한 부분집합 (power set) 의 수는 2^n개이다. 최악의 경우에 2^n번까지 봐야 하는, 즉 O(2^n) 의 알고리즘은 너무 느리다.

2) 가격이 높은 보석, 혹은 (가격/무게) 의 값이 제일 높은 보석부터 먼저 골라서 넣는다 (Greedy)

아래의 그림을 보자. 가격이 제일 높은 보석을 먼저 고르는 방법을 쓴다고 하면, 오른쪽 아래에 있는 빨간 보석을 먼저 고르고 그 다음 왼쪽에 있는 노란 보석을 고를 것이다. 그러면 10kg가 차고 가격의 합은 $16이 된다.

그렇지만 그림을 잘 보면서 다른 방법을 찾아보면, 왼쪽 보석 3개를 넣으면 10kg/$17이 된다는 걸 쉽게 알 수 있고, 1/2/3/4kg짜리를 하나씩 조합해서 넣으면 $19까지도 나온다. 즉 이 방법은 최적의 답을 보장하지 못한다.

단순히 가격만 보지 말고, ‘무게당 가격’ 을 계산해서 제일 높은 것부터 넣으면 되지 않겠느냐고 생각할 수 있다. 실제로 위 그림의 예시에서는 그렇게 하면 최적의 답이 나오긴 한다. 하지만 언제나 그렇지는 않다. 다른 예시를 보자.

W=30kg

보석1: 5kg/$5 — kg당 $1

보석2: 10kg/$6 — kg당 $0.6

보석3: 20kg/$14 — kg당 $0.7

이 경우에 ‘무게당 가격’ 순으로 보석을 넣으면 보석1, 보석3이 들어가며 가격의 합은 $19이다. 그런데 배낭 무게가 5kg가 남는다. 보석2를 넣을 수는 없으므로 5kg는 그냥 쓸데없이 남는 공간이다. 보석2, 보석3을 넣으면 30kg가 꽉 차고 가격의 합이 $20이다. 도둑 입장에서 도망갈 때 배낭이 좀 더 무거울 수 있겠지만 어쨌든 문제의 조건은 배낭이 안 터지는 한도 내에서 가격 합을 최대화하는 것이므로 보석2, 3을 가져가는 것이 정답이다.

이처럼 특정한 기준을 정해놓고 그 기준의 값이 가장 높은 순으로 집는 걸 Greedy 알고리즘이라 하는데 0-1 배낭 채우기 문제는 Greedy한 방법으로는 풀 수 없는 문제이다.

참고: Fractional Knapsack 문제는 Greedy로 풀 수 있다. 위 예시에서 보석2를 반으로 잘라서 남은 5kg짜리 공간에 넣으면 그게 최적의 답이 된다

그래서 DP라는게 등장한다. DP는 큰 문제를 작은 문제로 쪼개서 해결한다 (Devide-and-Conquer) 라는 원리에 기반을 두고 있으며, 이전에 계산해둔 값을 메모리 (배열 등) 에 저장해서 반복 작업을 줄이는 기법 (Memoization) 이 핵심이다. 뭔 소리냐면 아래의 피보나치 수열을 계산하는 함수의 예시를 보자.

왼쪽은 피보나치 수열을 계산하는 파이썬 함수이다. 피보나치 수열을 구하는 문제는 재귀함수를 이용하는 대표적인 문제로 잘 알려져 있다. 여기서도 재귀를 사용해서 가장 기본적인 방법으로 구현했다.

fib(5) 를 호출했다고 생각해보면 오른쪽 그림과 같이 재귀함수가 호출된다. 근데 빨간색으로 표시한 부분을 보면 왼쪽에서 이미 f(3) 을 한번 호출했는데, 오른쪽에서도 또 호출하고 있다. DP의 아이디어는 계산하는 값들을 어디다 저장해뒀다가, 저런 식으로 중복되는 계산이 나오면 저장해뒀던 값을 갖다 쓰자는 것이다. 그림에서 f(3) 의 값이 저장되어 있는 상태에서 f(3) 이 호출되면 그 값을 갖다 쓰도록 만들면, 오른쪽 트리의 f(3) 아래쪽 부분은 계산할 필요가 없게 된다.

아래는 DP를 적용한 피보나치 함수와 fib(40) 을 실행했을 때의 실행 시간 차이를 보여주는 것이다. ‘memo’ 라는 dict를 만드는데 메모리 공간을 소비하는 대신, 속도가 비약적으로 빨라지는 것을 알 수 있다.

왼쪽: 기본적인 방법 / 오른쪽: DP를 이용한 방법

이런 방법이 대체 어디가 다이나믹하냐 하면… 사실 다이나믹이라는 단어는 별 의미 없다. DP의 창시자에 따르면 다이나믹 프로그래밍이라는 이름은 연구비를 따와야 하는데 뭔가 있어보이는 이름이 필요해서 적당히 붙인 이름이라고 한다. (…) 대학원 다녀본 입장에서 공감된다

여튼 이 방법, DP를 0-1 배낭 채우기 문제를 푸는데 적용해보자. 어떤 문제를 DP로 풀기 위해서는 ‘최적의 원리’ (Principle of Optimality) 가 성립하는지를 확인해야 하는데, 최적의 원리란 다음과 같다.

“어떤 문제의 입력사례의 최적해가 그 입력사례를 분할한 부분사례에 대한 최적해를 항상 포함하고 있으면, 그 문제에 대하여 최적의 원리가 성립한다.”

이 문제에서 이 원리가 성립할까? 집합 A를 n개의 보석들 중에 최적으로 고른 부분집합이라고 가정하자.

– 집합 A가 n번째 보석을 포함하고 있지 않다면, A는 n번째 보석을 뺀 나머지 n-1개의 보석들 중에서 최적으로 고른 부분집합과 같다.

– 집합 A가 n번째 보석을 포함하고 있다면, A에 속한 보석들의 총 가격은 n-1개의 보석들 중에서 최적으로 고른 가격의 합에다가 보석 n의 가격을 더한 것과 같다. (단, n번째 보석을 넣었을 때 배낭이 터지지 않아야 한다)

지금 쓴 얘기를 점화식으로 풀어보면 아래와 같다.

P[i, w] 란 i개의 보석이 있고 배낭의 무게 한도가 w일 때 최적의 이익을 의미한다. 식을 좀 문장으로 풀어보면 이렇다.

– i번째 보석이 배낭의 무게 한도보다 무거우면 넣을 수 없으므로 i번째 보석을 뺀 i-1개의 보석들을 가지고 구한 전 단계의 최적값을 그대로 가져온다

– 그렇지 않은 경우, i번째 보석을 위해 i번째 보석만큼의 무게를 비웠을 때의 최적값에 i번째 보석의 가격을 더한 값 or i-1개의 보석들을 가지고 구한 전 단계의 최적값 중 큰 것을 선택한다

P라는 2차원 리스트를 채워나가면서, 필요한 경우 “앞에서 계산했던 다른 칸의 값을 이용해서” 다음 칸의 값을 계산한다. 그래서 이게 DP 문제인 것이다.

DP를 위한 2차원 리스트가 만들어지는 과정을 한번 보자 (위에서는 P였는데 여기서는 V로 썼다).

일단 i가 0인 경우는 넣을 보석이 없는 것이므로 다 0이고, w가 0인 경우는 배낭이 없는 것이므로 다 0이다. 그러니까 첫번째 행이랑 첫번째 열은 다 0으로 채워넣고 시작한다.

i=1인 경우부터 한칸씩 보자. (i, w)가 (1, 1) 인 경우에는 w=1짜리 배낭으로는 아무 보석도 넣을 수 없으므로 0이다. 그 다음 칸, (1, 2) 인 경우에는 이제 1번 보석을 넣을 수 있으니까 V[1, 2] = 3이 된다. 직관적으로는 이렇고, 위의 식을 통해서 보면 ‘1번 보석의 가치 + V[0, 0]’ 의 값과 V[0, 2] 의 값을 비교해서 더 큰 쪽을 가져가게 되는데, 1번 보석의 가치는 3이고 V[0, 0] 과 V[0, 2] 는 둘 다 0이므로 전자를 선택하게 된다.

현재 i=1이므로 1번 보석을 넣고 나면 더 이상 넣을 게 없으니 오른쪽의 남은 칸들도 다 3일 것이다.

i=2인 경우를 보면, w=2일때는 현재 보고있는 2번 보석 (3kg) 을 넣을 수 없으므로 바로 윗칸의 3을 가져온다 (1번 보석을 넣는다는 뜻). w=3이 되면 2번 보석을 넣을 수 있게 되는데, 1번 보석을 넣었을 때 (바로 윗칸) 랑 2번 보석을 넣을만큼의 공간을 확보하고 2번 보석을 넣었을 때 (즉, 2번 보석의 가치 + V[1, 0]) 를 비교해서 더 가치가 높은 쪽을 선택한다. 그래서 4가 들어간다.

(i, w) 가 (2, 5) 인 경우에는 1번 보석과 2번 보석을 둘 다 넣을 수 있다. 이미 3이 들어있는 (1, 2) 에서 최적값을 가져온다는 것이 1번 보석을 빼지 않고도 2번 보석을 넣을 수 있음을 의미한다. 즉 1번 보석을 넣었던 칸의 최적값 (3) + 2번 보석의 가격 해서 7이 들어간다.

이런 식으로 나머지 칸들도 계산해보면 마지막 칸에는 결국 7이 들어가고, 이 마지막 칸의 값이 최종적인 답 (최적의 총 가격) 이 된다.

아래는 이를 파이썬 함수로 구현한 것이다. DP를 위한 2차원 리스트를 만든 다음, 0번째 행/열을 0으로 세팅하고 나면 나머지는 위의 점화식을 그대로 프로그램으로 옮기면 된다. 위에선 P, V였던게 여기선 또 K인데 신경쓰지 말자

def knapsack(W, wt, val, n): # W: 배낭의 무게한도, wt: 각 보석의 무게, val: 각 보석의 가격, n: 보석의 수

K = [[0 for x in range(W+1)] for x in range(n+1)] # DP를 위한 2차원 리스트 초기화

for i in range(n+1):

for w in range(W+1): # 각 칸을 돌면서

if i==0 or w==0: # 0번째 행/열은 0으로 세팅

K[i][w] = 0

elif wt[i-1] <= w: # 점화식을 그대로 프로그램으로 K[i][w] = max(val[i-1]+K[i-1][w-wt[i-1]], K[i-1][w]) # max 함수 사용하여 큰 것 선택 else: K[i][w] = K[i-1][w] return K[n][W] 백준 온라인 저지의 12865번 문제가 정확히 이 0-1 배낭 채우기 문제인데, 이게 제대로 짠게 맞는지 확인차 오랜만에 들어가서 돌려봤더니 다행히 '맞았습니다!!' 가 떴다. 이 문제를 풀기 위한 나머지 코드도 아래에 써둔다. wt = [] val = [] N, K = map(int, sys.stdin.readline().strip().split()) for i in range(N): w, v = map(int, sys.stdin.readline().strip().split()) wt.append(w) val.append(v) print(knapsack(K, wt, val, N)) 메모: map 함수는 2번째 인자의 값에다가 일괄적으로 1번째 인자에 해당하는 함수를 적용시켜주는 함수다. 알고리즘 문제를 많이 풀어보지 않아서 잘 몰랐는데, 보통 이런 식으로 값을 많이 받는 모양이더라. 입력받을 땐 문자열인데 써먹을 땐 숫자로 써야 하니까 일괄적으로 int() 를 먹여서 타입 캐스팅을 해주는 것이다.

[알고리즘] 배낭 문제(Knapsack Problem)

배낭 문제(Knapsack Problem)

배낭 문제란 배낭에 담을 수 있는 무게의 최대값이 정해져 있고,

일정한 가치와 무게가 정해져있는 짐들을 배낭에 닮을 때,

가치의 합이 최대가 되도록 짐을 고르는 방법을 찾는 문제이다.

배낭 문제는 크게

1) 물건을 쪼갤 수 있는 배낭문제(Fraction Knapsack Problem)와

2) 물건을 쪼갤 수 없는 배낭문제(0/1 Knapsack Problem)으로 나뉜다.

1) 물건을 쪼갤 수 있는 배낭문제의 경우는 가치가 큰 물건부터 담고, 남은 무게 만큼 물건을 쪼개는 방식으로

그리디 알고리즘으로 해결할 수 있다.

2) 물건을 쪼갤 수 없는 배낭문제의 경우는 동적계획법(DP, Dynamic Programming)을 활용해 해결할 수 있다.

0/1 Kanpsack Problem 과정

0/1 Knapsack Problem 문제를 해결하기 위해서 동적 계획법을 이용한다.

가방에 담을 수 있는 물건의 무게와 가치가 아래 표와 같을 때,

물건 1 2 3 4 무게 6 4 3 5 가치 13 8 6 12

2차원 배열을 만들고 각 행과 열에 i번째 물건까지 넣을 수 있고, 배낭에 넣을 수 있는 최대무게가 j일 때, 최대 이윤을 저장해나간다.

이 때, 행 i 는 물건 i까지 넣을 수 있을 때를 의미하고, 열 j는 가방의 최대 무게를 의미한다.

0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 13 13 2 3 4

첫 번째 물건(무게 : 6, 가치 : 13)만 넣을 수 있을 때, 가방의 최대 무게에 따른 최대 이윤이다.

0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 13 13 2 0 0 0 0 8 8 13 13 3 4

두 번째 물건(무게 : 4, 가치 : 8)만 넣을 수 있을 때, 가방의 최대 무게에 따른 최대 이윤이다.

0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 13 13 2 0 0 0 0 8 8 13 13 3 0 0 0 6 8 8 13 14 4

세 번째 물건(무게 : 3, 가치 : 6)만 넣을 수 있을 때, 가방의 최대 무게에 따른 최대 이윤이다.

3행 7열을 보면 DP를 사용하는 이유를 알 수 있다. 가방의 최대 무게가 7일 때, 세번째 물건을 넣고 나서도 가방의 무게가 4가 남는다.

그렇다면 가방에는 최대무게가 4일 때와 같은 최대이윤을 더 남길 수 있다.

즉, DP[i][j]에는 v[i] + DP[i-1][j-w[i]]가 들어간다.

0 1 2 3 4 5 6 7 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 13 13 2 0 0 0 0 8 8 13 13 3 0 0 0 6 8 8 13 14 4 0 0 0 6 8 12 13 14

마지막 사이클까지 돌게되면 최대 이윤이 14인 것을 확인할 수 있다.

위의 과정을 점화식으로 나타내면 아래와 같이 나타낼 수 있다.

각 가방의 가치 : v[n]

각 가방의 무게 : w[n]

최대이윤 : dp[m][n]이라 할 때,

(w[i] <= j ) dp[i][j] = max(v[i] + dp[i-1][j - w[i]], dp[i-1][j] (w[i] > j) dp[i][j] = dp[i-1][j]

0/1 Knapsack Problem 구현

package baekjoon; import java.util.*; public class BOJ_12865 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] w = new int[n]; int[] v = new int[n]; int[][] dp = new int[n+1][k+1]; int max = 0; for(int i = 0; i < n; i++) { w[i] = sc.nextInt(); v[i] = sc.nextInt(); } for(int i = 1; i <= n; i++) { for(int j = 1; j <= k; j++) { if(w[i-1] <= j) dp[i][j] = Math.max(v[i-1] + dp[i-1][j - w[i-1]], dp[i-1][j]); else dp[i][j] = dp[i-1][j]; max = Math.max(dp[i][j], max); } } System.out.println(max); } }

[알고리즘 정리] 배낭 문제(Knapsack Problem)

글 작성자: 개발하는 훈이

Knapsack Problem

Knapsack Problem, 배낭문제는 다이나믹 프로그래밍에서 매우 유명한 문제이다.

어떤 배낭이 있고 그 배낭안에 넣을 수 있는 최대 무게가 K라고 하자. 배낭에 넣을 수 있는 N개의 물건이 각기 다른 가치 V를 가지고 있고 각 물건마다 다른 무게 W를 가지고 있을 때, 배낭이 최대한 가치가 높은 물건들을 담을 수 있는 조합을 찾는 문제이다. 냅색 문제는 Fractional Knapsack, 즉 물건을 쪼갤 수 있어 무게나 가치가 소수점 단위로 나뉘는 문제, 또는 0-1 Knapsack 물건을 쪼갤 수 없어 무게와 가치가 무조건 정수형태를 가지는 두 유형으로 나뉜다. 이번에는 0-1 Knapsack 문제를 해결하는 방법에 대해서 생각해보자.

Brute Force Approach

만약 n개의 물건이 있을 때, 가능한 모든 조합을 만들기 위해서는 2n 개의 경우의 수를 모두 시도해 보아야한다. 가지고 있는 물건이 몇개 없다면 별로 시간이 오래걸리지는 않겠지만, 2n 은 물건의 갯수가 하나만 늘어도 경우의 수가 크게 늘어나게 된다. 이 연산을 수행하려면 𝛩(2n ) 의 시간을 사용해야하고, 프로그래머 입장에서 그다지 좋은 접근은 아닐 것이다.

Dynamic Programming

따라서 이 문제는 당연스럽게도 다이나믹 프로그래밍으로 해결해야 한다. 그런데 항상 그렇듯 DP 의 가장 큰 어려움은 subproblem 을 정의하는 것이 쉽지 않다는 것이다. 나도 그랬고 많은 사람들이 이 문제의 subproblem 을 찾기 위해 다음과 같이 생각했을 것이다.

Finding Subproblem – 1

무게 7의 가방을 최대 가치로 가득 채우려면 무게 6일때 최대 가치로 가득 채웠을 때의 조합에 하나가 더 들어갈 수 있는지 확인해보면 되지 않을까?

이 수업을 듣기전에 나도 이렇게 생각했고 이 접근으로 문제를 풀어보려고 몇시간을 고민했던 적도 있다. 하지만 이 접근은 subproblem을 만들어내지 못한다. 기존에 있던 조합에서 하나의 물건을 빼고 다른 하나를 넣는 것으로 최대가치를 만들수 있기 때문이다. 따라서 무게 4일 때의 조합과 무게 5일때의 조합이 달라질 여지가 충분히 있는 것이다.

Finding Subproblem – 2

위 접근이 아닌 다른 방법으로 어떻게 접근해야 할까. 배낭에 물건을 넣을 때, 우리가 선택할 수 있는 경우는 두 가지가 있다.

물건을 넣는다. 물건을 넣지 않는다.

만약 현재 내가 넣으려고 하는 물건의 무게가 전체 제한무게를 초과한다면, 선택지는 물건을 넣지 않는 것 밖에 없다. 따라서 다음과 같은 식을 일단 하나 만들 수 있다.

B[k][W] = B[k-1][W], if w k > W

B는 DP를 위한 최대가치를 담는 배열이고, k는 현재 넣은 물건의 번호, W은 최대 무게를 의미한다. w k 는 k번째 물건에 대한 무게를 의미한다. 따라서 위 식은 k번째 물건이 총 제한 무게를 초과한다면 k번째 최대가치를 바로 k-1번째 물건을 넣을 경우의 가치로 정하는 것이다.

만약 물건을 넣을 수 있는 무게가 조금이라도 남았다면 어떻게 해야할까? 이때 우리의 선택지는 다시 두 가지로 나뉜다.

새로운 물건을 넣지 않는다 새로운 물건을 넣기 위해 현재 물건을 넣을 공간을 만들어서 물건을 넣는다.

우리는 최대 가치를 원하기 때문에, 두 경우 중 더 큰 값을 선택하게 될 것이다. 이것을 수식으로 만들면,

B[k][W] = max(B[k-1][W], B[k][W-w k ] + val(w k ))

현재 물건을 넣기 위해 넣었던 물건을 뺐을 때의 가치에 현재 물건의 가치를 더해주면 된다.

표를 채워가면서 더 자세하게 생각해보자. 우리에게 네 개의 물건이 있다고 하자 물건은 (무게, 가치) 로 나타내겠다. 그리고 물건을 넣을 가방의 최대 무게는 5라고 하자.

물건 : (2, 3), (3, 4), (4, 5), (5, 6)

가방의 최대 무게: 5

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 1 2 3 4 5

위와 같은 테이블을 만들고, 행은 최대 무게, 열은 물건의 번호를 가르키도록 하자.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 2 0 3 0 4 0 5 0

최대 무게가 0일 때, 그리고 물건이 없을 때는 가방에 넣을 수 있는 최대 가치는 당연히 0이다. 따라서 첫 행과 첫 열은 0으로 모두 채워줄 수 있다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 2 0 3 0 4 0 5 0

일단 첫 물건을 생각해보자. 무게 2, 가치 3짜리 물건이다. 이 물건을 가지고 해당 물건이 각 최대 무게당 가지는 최대 가치를 따져보면, 최대 무게가 1일 때는 현재 물건의 무게가 2이기 때문에 넣을 수 없다. 따라서 0을 넣어준다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 2 0 3 3 0 4 0 5 0

최대 무게가 2일 때는 현재 물건의 무게가 2이기 딱 맞게 물건을 넣을 수 있다. 물건을 넣게 되면 최대 가치는 3이 된다. 따라서 1열의 2행에는 1번째 물건의 가치인 3을 넣어준다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 2 0 3 3 0 3 4 0 3 5 0 3

첫번째 물건을 넣게 되면, 다른 모든 최대 무게에 대해서는 한번씩 모두 들어간다고 봐야한다. 무게가 2이니까 최대 무게가 3일 때도, 4일 때도, 5일 때도 하나씩 넣을 수 있기 때문이다. 따라서 1열의 남은 행은 모두 3으로 채워줄 수 있다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 0 2 0 3 3 3 0 3 4 0 3 5 0 3

다음 물건으로 넘어가보자. 다음은 (3, 4) 이다. 일단 무게가 3이기 때문에 가방의 최대무게가 3이 될 때 까지는 이 물건을 넣을 수 없다. 따라서 위와 같이 3미만의 무게에 대해서는 모두 1번째 물건을 넣은 상태로 두는 것이 가장 좋다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 0 2 0 3 3 3 0 3 4 4 0 3 5 0 3

자 이제 본격적으로 머리를 굴려볼 때가 왔다. 최대 무게가 3이 되었을 때는 우리에게 두 가지 선택지가 있다고 설명했었다. 넣거나, 넣지 않거나.

이 물건을 넣는다고 생각해보자. 그런데 물건을 넣게 되면 가방의 최대 무게를 초과하게 된다. 왜냐하면 이 시점에서는 가방에 첫번째 물건이 들어있기 때문이다. 따라서 물건을 넣으려면 이미 들어있는 첫번째 물건을 빼고 현재 물건을 넣어줘야한다. 가방에 있는 물건을 빼고 새 물건을 넣는다면, 가방의 최대 가치는 두 번째 물건의 가치인 4가 된다.

물건을 넣지 않는다고 생각해보자. 가방 안에는 첫 번째 물건이 들어있기 때문에 가방의 최대 가치는 3이 된다.

우리는 가방안에 들어있는 물건들의 가치를 최대로 하고 싶다. 따라서 우리가 선택할 선택지는 물건을 넣어서 가치가 4가 되게 하는 것이다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 0 2 0 3 3 3 0 3 4 4 0 3 4 5 0 3 7

가방의 최대 무게가 4일 때 역시 2번째 물건을 넣는 것이 이득이다.

가방의 최대 무게가 5일 때는 어떨까? 첫번째 물건을 넣은 상태에서 현재 물건을 넣어도 가방의 무게가 초과되지 않는다. 따라서 최대 무게가 5인 경우에는 두 물건을 모두 넣는것이 최대 가치를 만드는 선택일 것이다.

0 1 (2, 3) 2 (3, 4) 3 (4, 5) 4 (5, 6) 0 0 0 0 0 0 1 0 0 0 0 0 2 0 3 3 3 3 3 0 3 4 4 4 4 0 3 4 5 5 5 0 3 7 7 7

위 작업을 모든 물건에 대해서 진행해보자. 우리는 위와 같은 표를 얻을 수 있고, 최대 무게 5에 대한 최대 가치는 7이라는 것을 알 수 있다.

어떤 조합으로 최대 가치에 이르렀는지는 해당 가치값이 최초로 나온 지점을 보면된다. 이 경우에서는 1번째 물건과, 2번째 물건을 가방에 넣고 나머지 물건은 가방에 넣지 않는 경우가 최대 가치를 만드는 경우이다.

Pseudo code

위 로직을 pseudo code로 적어보자.

for w = 0 to W B[0][W] = 0 for i = 1 to n B[i][0] = 0 for w = 1 to W if w[i] <= w if b[i] + B[i-1][w-w[i]] > B[i-1][w] B[i][w] = b[i] + B[i-1][w-w[i]] else B[i][w] = B[i-1][w] else B[i][w] = B[i-1][w]

책에 나와있는 코드인데 변수가 무엇을 의미하는지 정확히 안나와 있어서 잘 와닿지 않는다. 백준에 동일한 알고리즘 문제가 있으니 [백준 알고리즘] 문제를 풀어보자. vector, pair, 같은 컨테이너나 algorithm에 들어있는 max 함수를 사용하면 더 수월하겠지만 최대한 pseudo code랑 비슷하게 만들었다. PS 포스트는 STL로 더 깔끔한 코드로 만들어서 올려보자.

implementation – BOJ 12865

문제

이 문제는 아주 평범한 배낭에 관한 문제이다.

한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다닐 배낭 또한 최대한 가치 있게 싸려고 한다.

준서가 여행에 필요하다고 생각하는 N개의 물건이 있다. 각 물건은 무게 W와 가치 V를 가지는데, 해당 물건을 배낭에 넣어서 가면 준서가 V만큼 즐길 수 있다. 아직 행군을 해본 적이 없는 준서는 최대 K무게까지의 배낭만 들고 다닐 수 있다. 준서가 최대한 즐거운 여행을 하기 위해 배낭에 넣을 수 있는 물건들의 가치의 최댓값을 알려주자.

입력

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)가 주어진다.

입력으로 주어지는 모든 수는 정수이다.

#include #define WEIGHT 0 #define VALUE 1 using namespace std; int main() { int dp[101][100001] = {0, }; int item[101][2]; int N, K; scanf(“%d %d”, &N, &K); for (int i = 1; i <= N; i++){ scanf("%d %d", &item[i][WEIGHT], &item[i][VALUE]); } for (int i = 1 ; i <= N ; i++){ for (int w = 1 ; w <= K ; w++){ if (item[i][WEIGHT] <= w){ // 최대 무게를 하나씩 올려가면서 계산 if ((item[i][VALUE] + dp[i-1][w-item[i][WEIGHT]]) > dp[i-1][w]) // 이전 최대가치를 사용하는 것보다 이전걸 빼고 현재물건을 넣는게 더 좋다면 넣어주자 dp[i][w] = item[i][VALUE] + dp[i-1][w-item[i][WEIGHT]]; else dp[i][w] = dp[i-1][w]; // 아니라면 이전가치를 그대로 사용 } else{ dp[i][w] = dp[i-1][w]; } } } printf(“%d”, dp[N][K]); return 0; }

Algorithm Analysis

DP 로 접근한 Knapsack Problem의 time complexity는 단순하게 2차원 배열을 모두 채워주면 끝나기 때문에, 무게 W, 물건의 갯수 N에 대해 Օ(NW) 의 시간복잡도를 가진다.

So you have finished reading the knapsack 알고리즘 topic article, if you find this article useful, please share it. Thank you very much. See more: 0-1 knapsack 알고리즘, Knapsack 알고리즘 파이썬, Knapsack Problem, 동적 계획 알고리즘 배낭, 배낭문제 백트래킹, 배낭문제 시간복잡도, Knapsack 뜻, Knapsack problem Dynamic Programming

Leave a Comment