it_worker365

   ::  ::  ::  ::  :: 管理
/**
 * Created by itworker365 on 5/10/2017.
 */
public class DynamicPlan {
    public static void main (String[] args) {
        int[] data = {1,-1,3,-5,2,1,9,-1};
//        System.out.println(calcMaxSum(data));
        int[] a = {1,-1,3,-5,2,1,9,-1};
        int[] b = {1,-1,3,-5,2};
        Lcs(a, b);
//        packLoad();
    }

    //最大子段和,如果加上比最大的大,那么就加上,如果加起来是负数,那么就舍弃重置为0
    private static int calcMaxSum (int[] data) {
        int max = data[0];
        for (int i = 1; i < data.length ; i++) {
            int sum = max + data[i];
            if (sum > max) {
                max = sum;
            } else if (sum < 0){
                max = 0;
            }
        }
        return max;
    }

    /**0-1(只只能选择放入或者不放入,没有其他可能),指定容量的背包,一堆一定数量和价值的物品,如何能在背包可容纳的情况下找到价值最高的负载方式
     * V[i][j]表示前i个物品可以装入容量为j的背包的最大价值
     * 可出现以下三种可能:
     * 1. v[i][0]=v[0][j]=0;    初始状态,背包容量为0或者不装任何物品的时候价值为0
     * 2. v[i][j]=v[i-1][j]   当w[i]>j    当放入物品i后背包超重,则无法放入
     * 3. v[i][j]=max{v[i-1][j],v[i-1][j-w[i]]+v[i]}  当j>=w[i]    当第i个物品可以放入时,比较不放入 和 放入(减少容量,增加价值) 的价值,选择大的。
     * */
    private static void packLoad() {
        int[] weight = {9, 3, 6};
        int[] val = {4, 2, 3};
        int packMax = 10;
        int goodsCnt = val.length;
        Method1(weight, val, packMax, goodsCnt);
        Method2(weight, val, packMax, goodsCnt);
    }

    private static void Method2(int[] weight, int[] val, int packMax, int goodsCnt) {
        int[] f = new int[packMax + 1];
        for(int i = 1; i < f.length; i++){
            //初始化为Integer.MIN_VALUE表示必须装满,初始化为0可以不满
            f[i] = 0;
        }
        for(int i = 0; i < goodsCnt; i++){
            for(int j = f.length - 1; j >= weight[i]; j--){
                f[j] = Math.max(f[j], f[j - weight[i]] + val[i]);
            }
        }
        for(int i = 0; i < f.length; i++){
            System.out.print(f[i] + " ");
        }
        System.out.println("Max value: "+f[f.length - 1]);
    }

    private static void Method1(int[] weight, int[] val, int packMax, int goodsCnt) {
        int[][] v = new int[goodsCnt + 1][packMax + 1];
        //没带包,装不了
        for(int i = 0; i < v.length; i++){
            v[i][0] = 0;
        }
        //没物品,没得装
        for(int i = 0; i < v[0].length; i++){
            v[0][i] = 0;
        }

        //遍历所有物品
        for(int i = 1; i < v.length; i++){
            //遍历每个容量单元
            for(int j = 1; j < v[0].length; j++){
                //当前物品的重量大于背包容量,不放入
                if(weight[i - 1] > j)
                    v[i][j] = v[i - 1][j];
                else{
                    //如果放入价值更高,则放入,较少容积增加对应的价值,否则不放入
                    if(v[i - 1][j] < v[i - 1][j - weight[i - 1]] + val[i - 1]){
                        v[i][j] = v[i - 1][j - weight[i - 1]] + val[i - 1];
                        System.out.println("放入X:" + i + " " + j + " " + v[i][j]);
                    }else{
                        v[i][j] = v[i - 1][j];
                    }
                }
            }
        }
        PrintTwo(v);
    }

    private static void PrintTwo(int[][] v) {
        for(int i = 0; i < v.length; i++){
            for(int j = 0; j < v[0].length; j++){
                System.out.print(v[i][j] + " ");
            }
            System.out.println();
        }
    }

    /**
     * 最长公共子序列
     * c[i][j]表示两个长度分别为i,j的序列的最长公共子序列的长度
     * c[0][j] 和 c[i][0]就是一个序列和一个空序列的公共子序列,所以就是空
     * 寻找c[i][j]递推关系:
     *     当序列1的第i个元素和第2个序列的第j个元素相同时,当前最大子序列增加一 c[i - 1][j - 1] + 1
     *     当序列1的第i个元素和第2个序列的第j个元素不相同时,当前最大子序列为max(c[i - 1][j], c[i][j - 1])
     * */
    private static void Lcs(int[] a, int[] b) {
        int alen = a.length;
        int blen = b.length;
        int[][] c = new int[alen][blen];
        for (int i = 0; i < c.length; i++) {
            c[i][0] = 0;
        }
        for (int i = 0; i < c[0].length; i++) {
            c[0][i] = 0;
        }
        for (int i = 1; i < c.length; i++) {
            for (int j = 1; j < c[0].length; j++) {
                if (a[i - 1] != b[j - 1]) {
                    if (c[i - 1][j] > c[i][j - 1]) {
                        c[i][j] = c[i - 1][j];
                    } else {
                        c[i][j] = c[i][j - 1];
                    }
                } else {
                    c[i][j] = c[i -1][j - 1] + 1;
                }
            }
        }
        PrintTwo(c);
    }
}

 

posted on 2017-05-10 16:31  it_worker365  阅读(242)  评论(0编辑  收藏  举报