回溯法-01背包問題

一、問題描述

給定 n 件物品,物品的重量為 w[i],物品的價(jià)值為 c[i]?,F(xiàn)挑選物品放入背包中,假定背包能承受的最大重量為 V,問應(yīng)該如何選擇裝入背包中的物品,使得裝入背包中物品的總價(jià)值最大

二、解決思路

物品是不能拆分的,首先想到的是動(dòng)態(tài)規(guī)劃,將背包問題分為兩個(gè)子問題,求解子問題的最優(yōu)解。回溯法可以解決這個(gè)問題,將所有的解羅列出來,叫做解空間,然后在每個(gè)解空間上,判斷每個(gè)物品是否加入背包,每個(gè)物品相當(dāng)于一個(gè)節(jié)點(diǎn),加入和不加入相當(dāng)于兩條路,具體是看走哪條路。


01背包.png

在向下遞歸查找最優(yōu)解的過程中,主要看兩個(gè)函數(shù),一個(gè)是當(dāng)前路能夠走,另一個(gè)就是當(dāng)前路走下去是不是最優(yōu)解。分別叫做限界條件、減枝函數(shù),這兩個(gè)函數(shù)的好壞影響算法的效率。

三、代碼

public class MapColoring {

    public static void main(String[] args) {
        //鄰接矩陣存儲(chǔ)圖 0代表相連否則不相連
        int[][] adjacencyMatrix = new int[][]{
                {0, 1, 1, 1, 0, 0, 0},
                {1, 0, 1, 0, 1, 0, 0},
                {1, 1, 0, 1, 1, 0, 0},
                {1, 0, 1, 0, 1, 0, 1},
                {0, 1, 1, 1, 0, 1, 1},
                {0, 0, 0, 0, 1, 0, 1},
                {0, 0, 0, 1, 1, 1, 0},
        };
        //記錄所有的結(jié)果
        int[][] allResult = new int[adjacencyMatrix.length][adjacencyMatrix.length];
        int[] currentValue = new int[adjacencyMatrix.length];
        coloring(adjacencyMatrix, allResult, 0, currentValue, 3, 0);
        for (int i = 0; i < allResult.length; i++) {
            System.out.println(Arrays.toString(allResult[i]));
        }


    }

    /**
     * 地圖著色
     *
     * @param adjacencyMatrix 鄰接矩陣
     * @param allResult       所有的結(jié)果集
     * @param i               當(dāng)前點(diǎn)
     */
    public static int coloring(int[][] adjacencyMatrix, int[][] allResult, int i, int[] currentValue, int color, int resultIndex) {

        /**
         * 判斷當(dāng)前節(jié)點(diǎn)的著色
         * 循環(huán)已經(jīng)著色的點(diǎn) ,如果相連則判斷能否著色當(dāng)前顏色
         * 循環(huán)顏色
         */

        if (i > adjacencyMatrix.length - 1) {
            //將當(dāng)前結(jié)果保存到全部結(jié)果中
            for (int j = 0; j < currentValue.length; j++) {
                allResult[resultIndex][j] = currentValue[j];
            }
            resultIndex += 1;
            return resultIndex;
        }

        for (int j = 1; j <= color; j++) {
            // 記錄當(dāng)前節(jié)點(diǎn)的顏色嘗試
            if (isOk(adjacencyMatrix, j, currentValue, i)) {
                // 當(dāng)前節(jié)點(diǎn)染色j
                currentValue[i] = j;
                //向下遞歸 如果這條路最終能走到葉子節(jié)點(diǎn),則會(huì)加入到allResult
                resultIndex = coloring(adjacencyMatrix, allResult, i + 1, currentValue, color, resultIndex);
                //由于這里是for循環(huán)嘗試其他的道路,所以不用手動(dòng)回溯,下次currentValue[i] = j;  會(huì)將本次循環(huán)值覆蓋,直到達(dá)到葉子節(jié)點(diǎn)保存結(jié)果
            }
        }
        return resultIndex;
    }


    /**
     * 判斷當(dāng)前節(jié)點(diǎn)是否可以進(jìn)行找色
     * 循環(huán)已經(jīng)作色的點(diǎn) 當(dāng)相鄰再判斷顏色是否相等
     *
     * @param adjacencyMatrix 鄰接矩陣
     * @param colorIndex      判斷的顏色
     * @param currentValue    當(dāng)前值列表
     * @param i               當(dāng)前節(jié)點(diǎn)
     * @return
     */
    public static boolean isOk(int[][] adjacencyMatrix, int colorIndex, int[] currentValue, int i) {
        for (int j = 0; j < i; j++) {
            if (adjacencyMatrix[j][i] == 1) {
                if (currentValue[j] == colorIndex) {
                    return false;
                }
            }
        }
        return true;
    }

四、優(yōu)化空間

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄 1.問題描述1.1 問題描述1.2 問題的數(shù)學(xué)表示(規(guī)劃類問題,此種表示可以轉(zhuǎn)換為回溯法)1.3 三種方法的...
    王偵閱讀 20,085評(píng)論 0 2
  • 深度優(yōu)先搜索 + 剪枝?;厮莘ǖ那蠼饽繕?biāo)一般是找出解空間樹中滿足約束條件的所有解。 # 在學(xué)習(xí)回溯和分支限界法之前...
    Tenloy閱讀 3,199評(píng)論 0 3
  • 文章結(jié)構(gòu) 如何理解回溯算法 回溯算法的經(jīng)典應(yīng)用 完整源碼 圖片來源 1. 如何理解回溯算法 1.1 什么是回溯算法...
    huyongming閱讀 945評(píng)論 1 4
  • 引言:這道題目老師強(qiáng)調(diào)了肯定要考,所以只有硬著頭皮將其復(fù)習(xí)了;下面是自己學(xué)習(xí)回溯算法的學(xué)習(xí),僅供參考;一:基本概念...
    cp_insist閱讀 8,721評(píng)論 4 3
  • 回溯法學(xué)習(xí)總結(jié) 回溯算法也是算法導(dǎo)論中常用的算法,回溯算法類似于暴力求解算法,經(jīng)常用在求可能解的問題。下面我將從三...
    魚魚魚三條魚ii閱讀 3,851評(píng)論 0 5

友情鏈接更多精彩內(nèi)容