關於算法動態規劃的實現優化

首先說下算法對於前端的做用和應用

做用:不用說了提升效率和性能html

應用:目前也是買了算法導論這本書,看得頭暈,各類數學知識須要返回去從新認識,哎,終於知道了之前學的東西總有用的。。。,本身買的哭着也要讀完,不扯了,直接說下如今已經應用的兩個地方前端

  1. trie樹結構,對於後端扁平化數據轉樹形結構適用於前端的應用,終於把遞歸改爲動規了
  2. 動態規劃在前端瀑布流中的應用

第一點我也是看了這篇博客才下定決心邁向算法大坑的,具體很少說直接附上地址算法

鏈接描述segmentfault

第二點的動態規劃參考如下博客,其中說的很是清晰,我主要是列舉下對於此篇介紹中已實現的js,作 空間複雜度優化的代碼,不足之處請指出後端

連接描述數組

首先我是按照數據的倒退圖裏面以物品數組做爲外層數組,揹包容量做爲內層數組的形式寫的js(按照圖的推導順序)緩存

1 用來生成隨機大小的物品重量和價值數組

function getNum() {
    return parseInt(Math.random()*100+1);
}
function getArr(size) {
    var arr = [];
    for (var i = 0;i<size;i++) {
        arr.push(getNum());
    }
    return arr;
}
var weight = getArr(10000);
var value = getArr(10000);
var V = 10000;

2 實現

function aaa(wight,value,all) {
    var startTime = new Date().getTime();
    var returnList = [];
    for (var i = 0;i<wight.length;i++) {
        returnList[i] = [];
        for (var j = 0;j<all;j++) {
            var nowW = j+1;//此時揹包重量
            var nowW_ = wight[i];//此時物品重量
            var nowV = value[i];//此時的價值
            var lastW = nowW - nowW_;//此時揹包重量減去此時要添加的物品後的重量
            
            var fV = lastW>=0?nowV:0;
            fV = fV+(i>0&&returnList[i-1][lastW-1]?returnList[i-1][lastW-1]:0);
            var nV = i>0&&returnList[i-1][j]?returnList[i-1][j]:0;
            returnList[i][j] = Math.max(fV,nV);
        }
    }
    var endTime = new Date().getTime();
    return returnList[wight.length-1][all-1]+"耗時:"+(endTime-startTime)+"ms";
}
console.log(aaa(weight,value,V));

這種方式須要構建龐大的二維緩存數組(用來把每次的最優解存下,相似於斐波那契函數動規的緩存),這一步徹底能夠優化成只構建上一步的最優解供給下一次使用dom

function bbb(wight,value,all) {
    var startTime = new Date().getTime();
    var returnList = [];
    var returnList_prev = [];
    var flag = true;
    for (var i = 0;i<wight.length;i++) {
        for (var j = 0;j<all;j++) {
            var nowW = j+1;//此時揹包重量
            var nowW_ = wight[i];//此時物品重量
            var nowV = value[i];//此時的價值
            var lastW = nowW - nowW_;//此時揹包重量減去此時要添加的物品後的重量
            //考慮過兩個數組相互賦值,可是數組是引用類型,兩個會干擾,若是深拷貝那就更影響速度,因此想到這種兩個數組相互使用相互覆蓋的方式來避免構建龐大的二維數組
            if(flag) {
                var fV = lastW>=0?nowV:0;
                fV = fV+(i>0&&returnList_prev[lastW-1]?returnList_prev[lastW-1]:0);
                var nV = i>0&&returnList_prev[j]?returnList_prev[j]:0;
                returnList[j] = Math.max(fV,nV);
            } else {
                var fV = lastW>=0?nowV:0;
                fV = fV+(i>0&&returnList[lastW-1]?returnList[lastW-1]:0);
                var nV = i>0&&returnList[j]?returnList[j]:0;
                returnList_prev[j] = Math.max(fV,nV);
            }
            
        }
        flag = !flag;
    }
    var endTime = new Date().getTime();
    return returnList[all-1]+"耗時:"+(endTime-startTime)+"ms";
}
console.log(bbb(weight,value,V));

對比了兩次的結果時間分別是:
圖片描述
能夠看到bbb方法明顯比aaa快了一倍之多
這裏只是想把本身看書後應用的東西分享下,你們有更好的方法也能夠指正-。-函數

相關文章
相關標籤/搜索