【问题标题】:0 1 matrix balancing0 1 矩阵平衡
【发布时间】:2011-12-24 20:09:17
【问题描述】:

在 wikipedia http://en.wikipedia.org/wiki/Dynamic_programming#A_type_of_balanced_0.E2.80.931_matrix 上,计算 0 1 平衡矩阵的数量作为动态规划的示例给出。但我发现很难实现那里给出的算法。有没有更好的算法?

如果不是,那么任何人都可以以一种更容易实现的方式解释那里提出的算法。就像这个算法中的递归关系是什么?因为一旦我找到它,做记忆就很容易了。

也有人能说出为什么这个特定的问题似乎比该页面上给出的所有其他问题要困难得多。

【问题讨论】:

    标签: algorithm matrix dynamic-programming


    【解决方案1】:

    动态编程会更快,但这里有一种简单的枚举方式。 平衡矩阵:双色 0-1 矩阵。这里s是0-1平衡方阵的维数,L[p][q]是矩阵的一个入口。最初调用 enumerate(s,1,1)。

    int enumerate(int s, int p,int q){ 
    
        if(p>s) {
                 printmatrix(L);
                 return 0;
        }
    
        if(p>=3 && q>=3){
                int min = p;if(p>q){min=q;}
                if L[1...min][1...min] is not a balanced matrix, then return 0;            
        }
        if(q<=s) {
                L[p][q] = 1;
                enumerate(s,p,q+1);
                if(p!=q){
                         L[p][q] = 0;
                         enumerate(s,p,q+1);            
                }
        }
        if(q>s) {
                enumerate(s,p+1,1); 
        }
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      动态编程解决方案

      import java.util.HashMap;
      import java.util.Map;
      
      public class Balanced01Matrix {
      
          //Variable to hold all possible row permutation 
          private int[][] rowPerms;
      
          //Mapping function f((n/2,n/2),(n/2,n/2)......(n/2,n/2))
          Map<String, Integer> arrangeFunction;
      
          int rowCounter = 0;
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              Balanced01Matrix bm = new Balanced01Matrix();
              int n = 4;
              int rows = bm.combination(n, n/2);
              bm.rowPerms = new int[rows][n];
              //Getting all the row permuation with n/2 '0' and n/2 '1'
              bm.getAllCombination(n/2, n/2, n, new int[n]);
              //bm.printAllCombination();
              bm.arrangeFunction = new HashMap<String, Integer>();
              //Variable to hold vector ((n/2,n/2),(n/2,n/2),......(n/2,n/2))
              int[][] digitsRemaining = new int[n][2];
              for(int i=0;i<n;i++){
                  digitsRemaining[i][0]=n/2;
                  digitsRemaining[i][1]=n/2;
              }
              //Printing total number of combination possible for nxn balanced matrix
              System.out.println(bm.possibleCombinations(digitsRemaining, n));
          }
      
          /**
           * Method to get all permutation of a row with n/2 zero and n/2 one
           * @param oneCount
           * @param zeroCount
           * @param totalCount
           * @param tmpArr
           */
          private void getAllCombination(int oneCount, int zeroCount, int totalCount, int[] tmpArr){
              if(totalCount>0){
                  if(oneCount > 0){
                      tmpArr[totalCount-1] = 1;
                      getAllCombination(oneCount-1, zeroCount, totalCount-1, tmpArr);
                  }
                  if(zeroCount > 0){
                      tmpArr[totalCount-1] = 0;
                      getAllCombination(oneCount, zeroCount-1, totalCount-1, tmpArr);
                  }
              }else{
                  rowPerms[rowCounter++] = tmpArr.clone();
              }
      
          }
      
          /**
           * Recursive function to calculate all combination possible for a given vector and level
           * @param digitsRemaining
           * @param level
           * @return
           */
          private int possibleCombinations(int[][] digitsRemaining, int level){
              //Using memoization
              if(arrangeFunction.containsKey(getStringForDigitsRemaining(digitsRemaining))){
                  return arrangeFunction.get(getStringForDigitsRemaining(digitsRemaining)); 
              }
              int totalCombination = 0;
              for(int[] row: rowPerms){
                  int i=0;
                  int[][] tmpArr = createCopy(digitsRemaining);
                  for(;i<row.length;i++){
                      if(row[i]==0){
                          if(tmpArr[i][0] - 1 >= 0){
                              tmpArr[i][0] -= 1;
                          }else
                              break;
                      }else{
                          if(tmpArr[i][1] - 1 >= 0){
                              tmpArr[i][1] -= 1;
                          }else
                              break;
                      }
                  }
                  //If row permutation is successfully used for this level
                  //else try next permuation
                  if(i==row.length){
                      //If last row of matrix return 1
                      if(level == 1){
                          return 1;
                      }else{
                          int combinations = possibleCombinations(tmpArr, level-1);
                          arrangeFunction.put(getStringForDigitsRemaining(tmpArr), combinations);
                          totalCombination += combinations;
                      }
                  }
              }
              return totalCombination;
          }
      
          /**
           * Creating deep copy of 2 dimensional array
           * @param arr
           * @return
           */
          private int[][] createCopy(int[][] arr){
              int[][] newArr = new int[arr.length][arr[0].length];
              for(int i=0;i<arr.length;i++){
                  for(int j=0;j<arr[0].length;j++){
                      newArr[i][j] = arr[i][j];
                  }
              }
              return newArr;
          }
      
          private void printRow(int[] row){
              for(int i: row)
                  System.out.print(i);
          }
      
          private String getStringForDigitsRemaining(int[][] digitsRemaining){
              StringBuilder sb = new StringBuilder();
              for(int i=0;i<digitsRemaining.length;i++){
                  sb.append(digitsRemaining[i][0]);
                  sb.append(digitsRemaining[i][1]);
              }
              return sb.toString();
          }
      
          /**
           * Calculates x choose y
           * @param x
           * @param y
           */
          private int combination(int x, int y){
              if(x>0 && y>0 && x>y)
                  return factorial(x)/(factorial(y)*factorial(x-y));
              else
                  return 0;
          }
      
          private int factorial(int x){
              if(x==0)
                  return 1;
              return x*factorial(x-1);
      
          }
      
          private void printAllCombination(){
              for(int[] arr: rowPerms){
                  for(int i: arr)
                      System.out.print(i);
                  System.out.println();
              }
      
      
          }
      
      
      
      }
      

      【讨论】:

      • 为您修复了代码格式。此外,最好在代码之外概述它是如何工作的;没有多少人会通过代码 cmets 来寻找解释。
      猜你喜欢
      • 2016-09-12
      • 2016-12-03
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多