【问题标题】:How to revert change of ArrayList after using List.set() JAVA使用 List.set() JAVA 后如何恢复 ArrayList 的更改
【发布时间】:2016-06-28 12:54:59
【问题描述】:

我有一个物品的 ArrayList(每个物品都有重量和利润):

ArrayList 项目列表: [{权重:3,收益:10},{权重:15,收益:50},{权重:7,收益:25},{权重:6,收益:15},{权重:4,收益:10} ]

然后我有一个随机的 bitStrings 表示在给定最大重量为 20(容量 = 20)的情况下要携带哪些物品。

假设获得的初始随机位是 [1,1,0,0,0],这意味着第 1 项和第 2 项得到:

总重量 = 3 + 15 = 18 [

然后我有一个随机位要翻转(如果该位是 1 -> 0,并且如果选择翻转的位是 0 -> 1)。假设翻转位的顺序是[3,2,1,4,0​​]。

首先,索引 3 处的位将被翻转并计算总重量,如下所示:

[1,1,0,0,0] --> [1,1,0,1,0]

因此,bit[3] 翻转后的新位串:[1,1,0,1,0]。

然后再次计算总重量:

新位串的总权重 = 3 + 15 + 6 = 24 [>容量]

所以总数超过了容量,我希望新的位串在翻转之前分配回前一个位串:

[1,1,0,1,0] --> 返回之前的状态:[1,1,0,0,0]。

返回状态后:[1,1,0,0,0]下一位会从刚才的顺序翻转[3,2,1,4,0​​]但是现在我必须按照从左到右的顺序翻转索引 2 处的位。这变成:

从 [1,1,0,0,0] --> 翻转位[2]:

[1,1,0,0,0] --> [1,1,1,0,0]

然后做同样的计算重量等。

如果总数仍然超过,它将返回到以前的状态,但如果它没有超过,它将新的解决方案添加到新的 ArrayList。

我已经对其进行了一些编码,但我的问题是要回到以前的状态,并将接受的位字符串添加到 ArrayList 改进。它仅存储最新更新的解决方案,并且正在替换其他已接受的解决方案,如我获得的输出所示。

这是我的代码: '

  public class KnapsackHC {
    public static void main (String[] args){
    int n = 5, capacity = 20, pointer, toFlip;
    //Item items = new Item();
    ArrayList<Item> itemList = new ArrayList<Item>();
    ArrayList<Integer> solution = new ArrayList<Integer>();
    ArrayList<Integer> currentSolution = new ArrayList<Integer>();
    ArrayList<Integer> flipOrder = new ArrayList<Integer>();
    ArrayList<ArrayList<Integer>> improve = new ArrayList<ArrayList<Integer>>();
    //ArrayList<Integer> temp = new ArrayList<Integer>();

    itemList = getProblem();
    solution = initialSolution(n);
    currentSolution = solution;
    flipOrder = randomFlipOrder(n);

    System.out.println("List of Items: " + itemList);
    System.out.println("Initial solution: " + solution);
    System.out.println("Current solution: " + currentSolution);
    System.out.println("Random order: " + flipOrder);

    for (int i = 0; i < flipOrder.size(); i++){
        int totalWeight = 0, totalProfit = 0;

        pointer = flipOrder.get(i);
        toFlip = solution.get(pointer);

        for (int j = 0; j < solution.size(); j++){
            if (solution.get(j) == 1){
                totalWeight += itemList.get(j).getWeight();
                totalProfit += itemList.get(j).getProfit();
            }
        }
        System.out.println();
        System.out.println("Updated Solution: " + currentSolution);
        System.out.println("Total Weight Solution " + (i+1) + " : " + totalWeight + " | Total Profit Solution " + (i+1) + " : " + totalProfit);

        if (totalWeight <= capacity){
            System.out.println("----------NOT EXCEED-----------");
            currentSolution = solution;
            System.out.println("currentSolution BEFORE FLIP: " + currentSolution);
            improve.add(currentSolution);
            System.out.println("Improve: " + improve);

            if (toFlip == 1){
                solution.set(pointer, 0);
            }
            else if (toFlip == 0){
                solution.set(pointer, 1);
            }
            System.out.println("solution AFTER FLIP from Random Order [" + flipOrder.get(i) + "] : " + solution);

            currentSolution = solution;
            //solution = new ArrayList<Integer>();
            System.out.println("--------------------------------");
        }
        else{
            System.out.println("----------EXCEED!!!!------------");
            //currentSolution = solution;
            System.out.println("currentSolution BEFORE FLIP {return back to previous state}: " + currentSolution);

            if (toFlip == 1){
                solution.set(pointer, 0);
            }
            else if (toFlip == 0){
                solution.set(pointer, 1);
            }
            System.out.println("solution AFTER FLIP from Random Order [" + flipOrder.get(i) + "] : " + solution);

            System.out.println("--------------------------------");
        }

    }

}
/*
public static ArrayList<Integer> calcFitness(ArrayList<Integer> currentSolution, ArrayList<Integer> solution, ArrayList<Item> itemList, int capacity){
    System.out.println("\nAfter Flip: " + solution);
    System.out.println("Current Solution: " + currentSolution);

    int totalWeight = 0; 
    int totalProfit = 0;

    for (int i = 0; i < solution.size(); i++){
        if (solution.get(i) == 1){
            totalWeight += itemList.get(i).getWeight();
            totalProfit += itemList.get(i).getProfit();
        }
    }
    System.out.println("Total Weight: " + totalWeight + " || Total Profit: " + totalProfit);


    if (totalWeight <= capacity){
        currentSolution = solution;
        System.out.println("Solution change: " + currentSolution);
        System.out.println();
        return solution;
    }
    else{

        System.out.println("Solution NO change: " + currentSolution);
        System.out.println();
        return currentSolution;
    }

}*/

public static ArrayList<Item> getProblem(){
    ArrayList<Item> itemsArr = new ArrayList<Item>();

    try {
        BufferedReader in = new BufferedReader( new FileReader("knapsack_problem_5.txt" ) );

        int i = 0;
        String str;
        while ( (str = in.readLine() )!= null ) {
            String[] item = str.split( "," );
            //System.out.print("Weight #" + i + " : " + Integer.parseInt(item[0]));
            //System.out.print("Profit #" + i + " : " + Integer.parseInt(item[1]));
            int weight = Integer.parseInt(item[0]);
            int profit = Integer.parseInt(item[1]);

            itemsArr.add(i,new Item(weight,profit));

            i++;
        }
        in.close();
    } catch ( IOException ex ) {
        System.err.println( "Error: Can't open the file for reading." );
    }

    return itemsArr;
}

//generate initial solution(bits) randomly
public static ArrayList<Integer> initialSolution(int length){
    Random r = new Random();
    ArrayList<Integer> solution = new ArrayList<Integer>(length);

    // generate some random boolean values
    boolean[] booleans = new boolean[length];
    for (int i = 0; i < booleans.length; i++) {
      booleans[i] = r.nextBoolean();
    }

    for (boolean b : booleans) {
      if (b == true){
          solution.add(1);
      }
      else{
          solution.add(0);
      }
    }

    return solution;

}

public static ArrayList<Integer> randomFlipOrder(int length){
    ArrayList<Integer> order = new ArrayList<Integer>();
    Random r = new Random();

    for (int i = 0; i < length; i++){
        order.add(i);
    }

    Collections.shuffle(order);

    return order;
   }
  }

'

我的文本文件包含以下内容(重量、利润):

3,10

15,50

7,25

6,15

4,10

我得到的输出(将随机生成初始位串和翻转位的随机顺序):

项目列表:[{重量:3,利润:10},{重量:15,利润:50},{重量:7,利润:25},{重量:6,利润:15},{重量: 4, 利润: 10}]

初始解决方案:[1, 0, 0, 1, 0]

当前解决方案:[1, 0, 0, 1, 0]

随机顺序:[2, 4, 0, 1, 3]

更新的解决方案:[1, 0, 0, 1, 0]

总重量解决方案 1 : 9 |总利润解决方案 1 : 25

---------不超过------------

翻转前的当前解决方案:[1, 0, 0, 1, 0]

改进:[[1, 0, 0, 1, 0]]

随机顺序翻转后的解决方案 [2] : [1, 0, 1, 1, 0]


更新的解决方案:[1, 0, 1, 1, 0]

总重量解决方案 2 : 16 |总利润解决方案 2:50

---------不超过------------

翻转前的当前解决方案:[1, 0, 1, 1, 0]

改进:[[1, 0, 1, 1, 0], [1, 0, 1, 1, 0]] 它不存储以前接受的解决方案,而是用新的解决方案替换它强>

随机顺序翻转后的解决方案 [4] : [1, 0, 1, 1, 1]


更新的解决方案:[1, 0, 1, 1, 1]

总重量解决方案 3 : 20 |总利润解决方案 3 : 60

---------不超过------------

翻转前的当前解决方案:[1, 0, 1, 1, 1]

改进:[[1, 0, 1, 1, 1], [1, 0, 1, 1, 1], [1, 0, 1, 1, 1]]

从随机顺序 [0] 翻转后的解决方案:[0, 0, 1, 1, 1]


更新的解决方案:[0, 0, 1, 1, 1]

总重量解 4 : 17 |总利润解决方案 4:50

---------不超过------------

翻转前的当前解决方案:[0, 0, 1, 1, 1]

改进:[[0, 0, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 1, 1, 1], [0, 0, 1, 1 , 1]]

从随机顺序 [1] 翻转后的解决方案:[0, 1, 1, 1, 1]


更新的解决方案:[0, 1, 1, 1, 1]

总重量解 5 : 32 |总利润解决方案 5:100

---------超过!!!!------------

currentSolution BEFORE FLIP {return back to previous state}: [0, 1, 1, 1, 1] ==> 这应该返回到 [0,0,1,1,1] 其中容量不超过

解决方案 AFTER FLIP from Random Order [3] : [0, 1, 1, 0, 1] ==> 这应该从 [0,0,1,1,1] 和 bcomes 中翻转 -> [0,0,1,0,1]


最后,一旦它变成 [0,0,1,0,1] 它应该再次显示总重量并显示但它不显示。

我不确定错误在哪里。请帮忙。谢谢。

【问题讨论】:

  • 提示:这确实是很多的输入。为了你(也是为了我们),我建议减少整个问题的核心。换句话说:尝试找到一段示例代码来显示您的问题(换句话说:使用列表执行某些操作的代码),它没有权重、文件等的“开销”......以及旁注:这样的代码非常适合 TDD 和单元测试。做TDD;你会从小的、有效的代码开始;逐步增加。与将 100 行代码组合在一起相比,它的效果要好得多 ...然后发现:那里的某个错误

标签: java algorithm arraylist random bit


【解决方案1】:

我已编辑我的代码以使其更短。如果权重超过,我仍然无法获得以前的位串。

这是我更新的代码: '

  public class BitString {
    public static void main (String[] args){
    int n = 3, capacity = 11, pointer, toFlip;

    ArrayList<Item> itemList = new ArrayList<Item>();
    ArrayList<Integer> solution = new ArrayList<Integer>();
    ArrayList<Integer> currentSolution = new ArrayList<Integer>();
    ArrayList<Integer> flipOrder = new ArrayList<Integer>();
    ArrayList<ArrayList<Integer>> improve = new ArrayList<ArrayList<Integer>>();

    itemList.add(new Item(4,5));
    itemList.add(new Item(10,12));
    itemList.add(new Item(5,8));

    solution = initialSolution(n);
    currentSolution = solution;
    flipOrder = randomFlipOrder(n);

    System.out.println("List of Items: " + itemList);
    System.out.println("Initial solution: " + solution);
    System.out.println("Current solution: " + currentSolution);
    System.out.println("Random order: " + flipOrder);

    for (int i = 0; i < flipOrder.size(); i++){
        int totalWeight = 0, totalProfit = 0;

        pointer = flipOrder.get(i);
        toFlip = solution.get(pointer);

        System.out.println();

        for (int j = 0; j < solution.size(); j++){
            if (solution.get(j) == 1){
                totalWeight += itemList.get(j).getWeight();
                totalProfit += itemList.get(j).getProfit();
            }
        }

        System.out.println("Total Weight For Solution " + solution + " : " + totalWeight + " | Total Profit For Solution " + solution + " : " + totalProfit);

        if (totalWeight <= capacity){
            System.out.println(totalWeight + " NOT EXCEED CAPACITY FOR SOLUTION: " + solution);
            currentSolution = solution;
            improve.add(currentSolution);
            System.out.println("Updated Current Solution: " + currentSolution);
            System.out.println("Updated Improved: " + improve);

            //do the flipping bits
            if (toFlip == 1)
                solution.set(pointer, 0);
            else
                solution.set(pointer, 1);

            System.out.println("New Solution After flip: " + solution);
        }
        else{
            System.out.println(totalWeight + " EXCEEDS CAPACITY FOR SOLUTION: " + solution);
            solution = currentSolution;
            System.out.println("SOLUTION REVERTED: " + solution);

            //do the flipping bits
            if (toFlip == 1)
                solution.set(pointer, 0);
            else
                solution.set(pointer, 1);

            System.out.println("New Solution After flip: " + solution);
        }

    }

}

//generate initial solution(bits) randomly
public static ArrayList<Integer> initialSolution(int length){
    Random r = new Random();
    ArrayList<Integer> solution = new ArrayList<Integer>(length);

    // generate some random boolean values
    boolean[] booleans = new boolean[length];
    for (int i = 0; i < booleans.length; i++) {
      booleans[i] = r.nextBoolean();
    }

    for (boolean b : booleans) {
      if (b == true){
          solution.add(1);
      }
      else{
          solution.add(0);
      }
    }

    return solution;

}

   public static ArrayList<Integer> randomFlipOrder(int length){
    ArrayList<Integer> order = new ArrayList<Integer>();
    Random r = new Random();

    for (int i = 0; i < length; i++){
        order.add(i);
    }

    Collections.shuffle(order);

    return order;
   }
  }

'

我的输出是:

项目列表:[{Weight: 4, Profit: 5}, {Weight: 10, Profit: 12}, {Weight: 5, Profit: 8}]

初始解决方案:[0, 1, 0]

当前解决方案:[0, 1, 0]

随机顺序:[2, 0, 1]

解决方案 [0, 1, 0] 的总重量:10 |解决方案的总利润 [0, 1, 0] : 12

10 未超过解决方案的容量:[0, 1, 0]

更新的当前解决方案:[0, 1, 0]

更新改进:[[0, 1, 0]]

翻转后的新解决方案:[0, 1, 1]

解决方案 [0, 1, 1] 的总重量:15 |解决方案 [0, 1, 1] 的总利润:20

15 超出解决方案的容量:[0, 1, 1]

解决方案已恢复:[0, 1, 1]

翻转后的新解决方案:[1, 1, 1]

解决方案 [1, 1, 1] 的总重量:19 |解决方案的总利润 [1, 1, 1] : 25

19 超出解决方案的容量:[1, 1, 1]

解决方案已恢复:[1, 1, 1]

翻转后的新解决方案:[1, 0, 1]

【讨论】:

    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 2020-06-17
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 2019-03-28
    • 2016-05-25
    相关资源
    最近更新 更多