算法動態規划的詳解(經典的背包問題)


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

作用:不用說了提高效率和性能

應用:目前也是買了算法導論這本書,看得頭暈,各種數學知識需要返回去重新認識,哎,終於知道了以前學的東西總有用的。。。,自己買的哭着也要讀完,不扯了,直接說下現在已經應用的兩個地方

1 trie樹結構,對於后端扁平化數據轉樹形結構適用於前端的應用,終於把遞歸改成動規了

2 動態規划在前端瀑布流中的應用

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

http://www.cnblogs.com/ypinchina/p/7306581.html

第二點的動態規划參考以下博客,其中說的非常清晰,我主要是列舉下對於此篇介紹中已實現的js,做 空間復雜度優化的代碼,不足之處請指出

https://segmentfault.com/a/1190000006082676

首先我是按照數據的倒退圖里面以物品數組作為外層數組,背包容量作為內層數組的形式寫的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));

這種方式需要構建龐大的二維緩存數組(用來把每次的最優解存下),這一步完全可以優化成只構建上一步的最優解供給下一次使用

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快了一倍之多

這里只是想把自己看書后應用的東西分享下,大家有更好的方法也可以指正-。-

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM