js 알고리즘 초기 탐색 05 (알고리즘 모델 02 - 동적 계획 과 욕심 알고리즘)
그러면 저 는 또 하나의 의문 이 있 습 니 다. 앞에서 재 귀 를 말 했 습 니 다. 그러면 재 귀 는 요? 분 치 법 과 동적 계획 은 일종 의 수단 이나 방법 같 고 재 귀 는 구체 적 으로 조작 하 는 도구 나 집행 자 입 니 다. 분 치 법 이 든 동적 계획 이 든 다른 어떤 재 미 있 는 방법 이 든 재 귀 도 구 를 사용 하여 '실행' 코드 를 사용 할 수 있 습 니 다.
동적 계획 으로 문 제 를 해결 하 는 것 은 주로 세 가지 절차 로 나 뉜 다. 1. 서브 문 제 를 정의 하고 2. 반복 적 으로 실행 하여 서브 문 제 를 해결 해 야 하 는 부분 (예 를 들 어 재 귀 로 '반복') 을 실현 한다. 3. 경계 조건 을 식별 하고 해결 해 야 한다. 이렇게 말 하면 좀 어리둥절 하 다. 그러면 우 리 는 동적 계획 으로 전형 적 인 문 제 를 해결 해 보 자.
1. 최소 동전 거스름돈 문제
최소 동전 거스름돈 문 제 는 동전 거스름돈 문제 의 변종 이다. 동전 거스름돈 문 제 는 거스름돈 의 액수 와 사용 가능 한 동전 의 액수, 그리고 그 에 대응 하 는 수량 을 제시 하 는 것 이다. 동전 거스름돈 을 얼마나 찾 느 냐 하 는 것 이다. 최소 동전 거스름돈 문 제 는 그 중 가장 적은 양의 동전 을 찾 는 것 이다. 예 를 들 어 우 리 는 1, 5, 10, 25 액면가 의 동전 이 있 는데 36 액면가 의 동전 을 찾 으 려 면돈 을 어떻게 거스름돈 으로 드릴 까요? 답 은 25 개, 10 개, 1 개 입 니 다. 이것 이 답 입 니 다. 그러면 어떻게 위의 문 제 를 알고리즘 으로 바 꾸 어 해결 할 수 있 습 니까? 컴퓨터 가 있 으 면 빠 르 고 간단 한 결 과 를 얻 을 수 있 습 니 다. 우리 가 더 이상 머리 를 써 서 문 제 를 해결 하지 않 아 도 됩 니 다. 다음은 코드 를 살 펴 보 겠 습 니 다.
//
function MinCoinChange(coins) {
// coins 。
// 。
var coins = coins;
//
var cache = {};
// ,
this.makeChange = function (amount) {
// this this.makeChange , ( )
var me = this;
// amount , , , 。
if(!amount) {
return [];
};
// cache[amount]
//
if(cache[amount]) {
return cache[amount];
};
// min ,newMin newAmount , 。
var min = [],newMin,newAmount;
// coins 。 , conis 。( coin )
for(var i = 0; i < coins.length; i++) {
// coins 。
var coin = coins[i];
// 。 newAmount 。
newAmount = amount - coin;
// , newAmount 0 , , 。
// , 。
if(newAmount >= 0) {
newMin = me.makeChange(newAmount);
};
// newAmount ,
// if , , 。
console.log(!min.length,min.length)
if(newAmount >= 0 && (newMin.length < min.length - 1 || !min.length) && (newMin.length || !newAmount)) {
min = [coin].concat(newMin);
//console.log('new Min' + min + 'for' + amount);
}
};
//cache 1 amount
//console.log(cache)
return (cache[amount] = min);
};
};
var minCoinChange = new MinCoinChange([1,5,10,25]);
console.log(minCoinChange.makeChange(36))
이것 은 동적 계획 의 방법 으로 최소 동전 찾기 문 제 를 해결 하 는 것 입 니 다. 그러면 욕심 산법 으로 최소 동전 찾기 문 제 를 어떻게 해결 하 는 지 살 펴 보 겠 습 니 다. 그렇다면 욕심 산법 은 무엇 입 니까? 욕심 산법 은 가장 좋 은 서브 구 조 를 가 진 문제 에서 특히 효과 적 입 니 다. 가장 좋 은 서브 구 조 는 부분 적 인 최 적 화 를 통 해 전체 국면 을 결정 할 수 있다 는 뜻 입 니 다. 쉽게 말 하면 문 제 는 분해 할 수 있 습 니 다.하위 문 제 를 해결 하기 위해 서 는 하위 문제 의 최 적 화 를 최종 문제 의 최 적 화 된 문제 로 미 룰 수 있 습 니 다. 욕심 산법 은 동적 계획 과 달리 모든 하위 문제 의 해결 방안 을 선택 하여 되 돌 릴 수 없습니다. 동적 계획 은 이전의 연산 결 과 를 저장 하고 앞의 결과 에 따라 현 재 를 선택 하여 되 돌 리 는 기능 이 있 습 니 다.
코드 를 보 겠 습 니 다.
function MinCoinChange(coins) {
var coins = coins;
this.makeChange = function (amount) {
var change = [],total = 0;
for(var i = coins.length; i >= 0; i--) {
var coin = coins[i];
while(total + coin <= amount) {
change.push(coin);
total += coin;
}
}
return change;
};
}
var minCoinChange = new MinCoinChange([1,5,10,25]);
console.log(minCoinChange.makeChange(36))
우 리 는 위의 코드 를 보 았 습 니 다. 주요 논 리 는 동적 계획 과 매우 비슷 합 니 다. 다만 코드 자체 가 아주 간단 해 야 합 니 다. 욕심 산법 은 우리 의 동전 중에서 가장 큰 것 부터 가 져 갈 수 없 을 때 까지 다음 것 을 가 져 가 최종 결과 로 돌아 갈 때 까지 두 가지 해결 방법 이 통과 하지 못 하 는 지 살 펴 보 겠 습 니 다. 동적 계획 은 cache 를 통 해 이전의 계산 결 과 를 캐 시 할 것 입 니 다.현재 의 계산 결과 에서 이전 과 비교 하여 둘 사이 의 최 적 화 를 선택 하 십시오. 욕심 산법 은 현재 의 최 적 화 를 선택 할 뿐 되 돌아 가지 않 고 기록 전의 해결 방안 을 저장 하지 않 습 니 다.
2. 가방 문제
가방 문 제 는 조합 최적화 문제 입 니 다. 문 제 는 이 렇 습 니 다. 고정 크기 를 정 하고 무게 가 W 인 가방 과 가치 와 무게 가 있 는 물건 을 휴대 할 수 있 습 니 다. 가장 좋 은 해결 방안 을 찾 아 가방 에 넣 은 물품 의 총 중량 이 W 를 초과 하지 않 고 총 가치 가 가장 큽 니 다. 이 문 제 는 두 가지 버 전이 있 습 니 다. 하 나 는 0 - 1 가방 문제 입 니 다. 이 버 전 은가방 에 온전한 물건 만 넣 을 수 있 으 며 분리 할 수 없습니다. 또 하 나 는 점수 아 이 템 을 넣 을 수 있 습 니 다. 우 리 는 나중에 욕심 산법 으로 점수 가방 문 제 를 해결 할 것 입 니 다.
코드 를 보 겠 습 니 다.
//
function knapSack(capacity,weights,values,n) {
var i,w,a,b,kS = [];
for (var i = 0; i <= n; i++) {
kS[i] = [];
}
for(i = 0; i <= n; i++) {
for(w = 0; w <= capacity; w++) {
if(i == 0 || w == 0) {
kS[i][w] = 0;
} else if(weights[i - 1] <= w) {
a = values[i - 1] + kS[i - 1][w - weights[i - 1]];
b = kS[i - 1][w];
kS[i][w] = (a > b) ? a : b;
} else {
kS[i][w] = kS[i - 1][w];
}
}
}
findValues(n,capacity,kS,weights,values);
return kS[n][capacity];
};
function findValues(n,capacity,kS,weights,values) {
var i = n,k = capacity;
console.log(' :');
while(i > 0 && k > 0) {
if(kS[i][k] !== kS[i - 1][k]) {
console.log(' ' + i + ', :' + weights[i- 1] + ', :' + values[i - 1]);
i--;
k = k - kS[i][k];
} else {
i--;
}
}
}
var values = [3,4,5],weights = [2,3,4],capacity = 5,n = values.length;
console.log(knapSack(capacity,weights,values,n))
위의 코드 에서, 우 리 는 처음에 하나의 행렬 을 초기 화하 여 각종 해결 방안 을 저장 하 였 으 며, 가방 에 넣 는 물품 i 는 capacity 보다 작 아야 합 니 다. 즉, 가방 에 넣 을 수 있 는 무게 보다 작 아야 가방 에 넣 을 수 있 는 일부분 이 될 수 있 습 니 다. 그렇지 않 으 면 가방 에 넣 을 수 있 는 무 게 를 초과 할 수 있 습 니 다. 이것 은 허용 되 지 않 습 니 다. 또한 두 개의 물품 이 있 을 때.무게 가 같 을 때 우 리 는 가치 가 비교적 큰 어느 것 을 선택한다.
사실 위의 알고리즘 은 계속 최적화 할 수 있 습 니 다. 여 기 는 많이 말 하지 않 고 여러분 들 이 관심 이 있 으 면 깊이 공부 할 수 있 습 니 다.
욕심 산법 의 점수 가방 문제:
점수 가방 문 제 는 0 - 1 가방 문제 와 유사 합 니 다. 다만 점수 가방 에 일부 아 이 템 을 넣 을 수 있 습 니 다. 코드 는 어렵 지 않 습 니 다. 여러분 이 직접 쓰 시 면 알 수 있 습 니 다.
function knapSack(capacity,values,weights) {
var n = values.length,load = 0,i = 0,val = 0;
for(i = 0; i < n && load < capacity; i++) {
if(weights[i] <= (capacity - load)) {
val += values[i];
load += weights[i];
} else {
var r = (capacity - load) / weights[i];
val += r * values[i];
load += weights[i];
}
}
return val;
}
var values = [3,4,5],weights = [2,3,4],capacity = 6;
console.log(knapSack(capacity,values,weights))
3. 최 장 공공 서브 시퀀스 문제
이 문 제 는 이 렇 습 니 다. 두 문자열 서열 중 가장 긴 하위 서열 의 길 이 를 찾 아 보 세 요. 가장 긴 하위 서열 은 두 문자열 서열 에서 같은 순서 로 나타 나 지만 반드시 연속 적 인 문자열 서열 이 라 고 요구 하 지 는 않 습 니 다.
// LCS
function lcs(wordX,wordY) {
var m = wordX.length,n = wordY.length,l = [],i,j,a,b;
var solution = [];
for (i = 0; i <= m; ++i) {
l[i] = [];
solution[i] = [];
for(j = 0; j <= n; ++j) {
l[i][j] = 0;
solution[i][j] = '0';
}
}
for(i = 0; i <= m; i++) {
for(j = 0; j <= n; j++) {
if(i == 0 || j == 0) {
l[i][j] = 0;
} else if(wordX[i - 1] == wordY[j - 1]) {
l[i][j] = l[i - 1][j - 1] + 1;
solution[i][j] = 'diagonal';
} else {
a = l[i - 1][j];
b = l[i][j - 1];
l[i][j] = (a > b) ? a : b;
solution[i][j] = (l[i][j] == l[i - 1][j]) ? 'top' : 'left';
}
}
}
printSolution(solution,l,wordX,wordY,m,n);
return l[m][n];
}
function printSolution(solution,l,wordX,wordY,m,n) {
var a = m,b = n,i,j,
x = solution[a][b],
answer = '';
while(x !== '0') {
if(solution[a][b] === 'diagonal') {
answer = wordX[a - 1] + answer;
a--;
b--;
} else if(solution[a][b] === 'left') {
b--;
} else if(solution[a][b] === 'top') {
a--;
}
x = solution[a][b];
}
console.log('lcs:' + answer);
}
lcs("acbaed","abcadf");
4. 행렬 체인 상승
이 문 제 는 행렬 을 곱 하 는 가장 좋 은 방법 (순서) 을 찾 는 것 이다.시작 하기 전에 행렬 의 상승 을 간단히 설명 할 필요 가 있 습 니 다. 쉽게 말 하면 n 행 m 열 을 넣 은 행렬 A 와 m 행 p 열 을 넣 은 행렬 B 를 곱 하면 n 행 p 열의 행렬 C 를 얻 을 수 있 습 니 다. 한 행렬 의 행 이 다른 행렬 의 열 과 같은 두 행렬 만 이 곱 할 수 있 음 을 주의해 야 합 니 다.
그러면 만약 에 제 가 A, B, C, D 네 개의 행렬 을 곱 하고 싶다 면 곱셈 이 결합 율 (초등학교 수학 지식 점) 을 만족 시 키 기 때문에 우 리 는 이렇게 (A (B (CD)) 하거나 이렇게 (AB) (CD)) 할 수 있 습 니 다.등 다섯 가지 상승 방법, 그러나 주의해 야 할 것 은 각 상승 순서 가 다 르 고 우리 의 계 산 량 도 다르다 는 것 이다. 그래서 우 리 는 함 수 를 구축 하여 계 산 량 이 가장 적은 상승 방법 을 찾 아야 한다. 이것 이 바로 행렬 체인 상승 문제 이다.
//
function matrixChainOrder(p,n) {
var i,j,k,l,q,m = [];
// s
var s = [];
for(i = 0; i <= n; i++) {
s[i] = [];
for(j = 0; j <= n; j++) {
s[i][j] = 0;
}
}
for(i = 0; i <= n; i++) {
m[i] = [];
m[i][i] = 0;
};
for(l = 2; l < n; l++) {
for(i = 1; i <= n - l + 1; i++) {
j = i + l - 1;
m[i][j] = Number.MAX_SAFE_INTEGER;
for(k = i; k <= j - 1; k++) {
q = m[i][k] + m[k + 1][j] + p[i - 1]*p[k]*p[j];
if(q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;//
}
}
}
}
printOptimalParenthesis(s,1,n - 1);
return m[1][n - 1];
}
function printOptimalParenthesis(s,i,j) {
if(i == j) {
console.log("A[" + i + "]");
} else {
console.log("(");
printOptimalParenthesis(s,i,s[i][j]);
printOptimalParenthesis(s,s[i][j] + 1,j);
console.log(")");
}
}
var p = [10,100,5,50,1,100];
n = p.length;
console.log(matrixChainOrder(p,n));
마지막 으로, 본인 의 수준 이 제한 되 어 있 기 때문에, 능력 과 큰 신 은 여전히 거리 가 멀 습 니 다. 잘못 이 있 거나 불분명 한 점 이 있 으 면, 여러분 의 가르침 을 아 끼 지 않 기 를 바 랍 니 다. 감사합니다. 더 높이 날 고 싶 은 채소 새 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.