參考 關鍵點:找到狀態和狀態轉移方程;把大問題拆分紅小問題再回歸比較html
function minimum(total, moneys) {
const cache = {};
const getMinimum = (totals) => {
const list = moneys.map(i => {
if (totals > i) {
const nextIndex = totals - i;
if (!cache[nextIndex]) {
cache[nextIndex] = getMinimum(nextIndex);
}
if (cache[nextIndex]) {
return [i].concat(cache[nextIndex])
} else {
return false
}
} else if (totals == i) {
return [i]
} else {
return false
}
}).filter(i => !!i)
if (list.length > 0) {
return list.sort(function(a,b){return a.length-b.length})[0];
} else {
return []
}
}
const back = getMinimum(total);
return back;
}
minimum(13, [1, 2, 3, 7, 10])
複製代碼
i | 1 | 2 | 3 | 4 |
---|---|---|---|---|
w(體積) | 2 | 3 | 4 | 5 |
v(價值) | 3 | 4 | 5 | 6 |
function test(total, arr) {
const unshift = arr.pop();
console.log(arr, _.cloneDeep(arr));
let next = [];
if (arr.length > 0) {
const bin1 = [unshift].concat(test(total - unshift[0], _.cloneDeep(arr)));
const bin2 = test(total, _.cloneDeep(arr));
const bin1W = bin1.map(item => item[0]).concat([0]).reduce(function(prev, curr){return prev + curr});
const bin2W = bin2.map(item => item[0]).concat([0]).reduce(function(prev, curr){return prev + curr});
if (bin1W > total && bin2W > total) {
return []
} else if (bin1W > total && bin2W <= total) {
return bin2
} else if (bin1W <= total && bin2W > total) {
return bin1
} else{
const bin1V = bin1.map(item => item[1]).concat([0]).reduce(function(prev, curr){return prev + curr});
const bin2V = bin2.map(item => item[1]).concat([0]).reduce(function(prev, curr){return prev + curr});
return bin1V > bin2V ? bin1 : bin2
}
} else {
if (unshift[0] > total) {
return []
} else {
return [unshift]
}
}
}
const res = test(10, [[2, 3], [3, 4], [4, 5], [5, 6]]);
if (res.length <= 0) {
console.log('無結果');
} else {
console.log(`能夠裝:${JSON.stringify(res)},價值是:${res.map(item => item[1]).reduce(function(prev, curr){return prev + curr})}`)
}
複製代碼
function test(arr) {
const cache = {};
const max = function(i, j) {
console.log(i, j);
if (i == arr.length - 1 && j == arr[0].length -1 ) {
return [[i, j, arr[i][j]]]
} else if (i == arr.length -1 ) {
return [[i, j, arr[i][j]]].concat(max(i, j + 1));
} else if (j == arr[0].length -1 ) {
return [[i, j, arr[i][j]]].concat(max(i + 1, j));
}
const key = `${i}-${j}`;
if (!cache[key]) {
const rightList = max(i, j + 1);
const leftList = max(i + 1, j);
const rightListValue = rightList.map(item => item[2]).reduce(function(prev, curr){
return prev + curr;
});
const leftListValue = leftList.map(item => item[2]).reduce(function(prev, curr){
return prev + curr;
});;
cache[key] = [[i, j, arr[i][j]]].concat(rightListValue > leftListValue ? rightList: leftList);
}
return cache[key]
}
const list = [[0, 0, arr[0][0]]].concat(max(0, 0));
console.log(cache, list, list.map(item => item[2]).reduce(function(prev, curr){
return prev + curr;
}))
}
test([
[56, 85, 16, 1, 55, 79],
[11, 87, 86, 94, 84, 54],
[15, 94, 17, 11, 13, 97],
[76, 60, 94, 21, 78, 49],
[3, 16, 90, 86, 73, 45],
]);
複製代碼
遺傳算法(Genetic Algorithm)是模擬達爾文生物進化論的天然選擇和遺傳學機理的生物進化過程的計算模型,是一種經過模擬天然進化過程搜索最優解的方法。 具體而言,它有兩個核心要點:第一是編碼,即須要找到一種合適的方法,將待解決的問題映射爲「基因」編碼,生成多個個體;第二是評估,即須要一種定量的方法給每一個個體打分,評估哪一個個體所對應的方案更接近最佳答案,從而能夠根據這個分數優勝劣汰。算法
介紹能夠看下百度百科,裏面仍是講的比較清楚。bash
將蟻羣算法應用於解決優化問題的基本思路爲:用螞蟻的行走路徑表示待優化問題的可行解,整個螞蟻羣體的全部路徑構成待優化問題的解空間。路徑較短的螞蟻釋放的信息素量較多,隨着時間的推動,較短的路徑上累積的信息素濃度逐漸增高,選擇該路徑的螞蟻個數也越來越多。最終,整個螞蟻會在正反饋的做用下集中到最佳的路徑上,此時對應的即是待優化問題的最優解網絡
螞蟻找到最短路徑要歸功於信息素和環境,假設有兩條路可從蟻窩通向食物,開始時兩條路上的螞蟻數量差很少:當螞蟻到達終點以後會當即返回,距離短的路上的螞蟻往返一次時間短,重複頻率快,在單位時間裏往返螞蟻的數目就多,留下的信息素也多,會吸引更多螞蟻過來,會留下更多信息素。而距離長的路正相反,所以愈來愈多的螞蟻彙集到最短路徑上來。post
可應用的問題:旅行商問題、指派問題、Job—shop調度問題、車輛路由問題、圖着色問題和網絡路由問題等 本例實現「車輛路由問題」:優化
複製代碼