Advertisement
Guest User

Untitled

a guest
Nov 29th, 2016
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.47 KB | None | 0 0
  1. import java.util.Arrays;
  2. import java.util.HashMap;
  3. import java.util.HashSet;
  4. import java.util.Map;
  5. import java.util.Set;
  6.  
  7. public class SubsetSumExtreme {
  8.     public double getExpectation(int[] block, int[] face) {
  9.        
  10.         int B = block.length;
  11.         int F = face.length;
  12.        
  13.         int[] sums = new int[1 << B]; //sum for each subset of blocks
  14.         Map<Integer,Set<Integer>> masks = new HashMap<>(); //possible block subsets for each face
  15.        
  16.         for (int f : face)
  17.             masks.put(f, new HashSet<>());
  18.        
  19.         for (int i = 1; i < sums.length; i++) {
  20.             /*
  21.              * dynamic programming:
  22.              * 1. remove a single block from the current subset of blocks
  23.              * 2. the corresponding block sum was already calculated
  24.              * 3. add the number on the removed block to it
  25.              *
  26.              * here: always choose the block corresponding
  27.              * to the least significant bit of i
  28.              */
  29.             int t = Integer.numberOfTrailingZeros(i & -i);
  30.             sums[i] = sums[i & ~(1 << t)] + block[t];
  31.            
  32.             //only add block subsets that add up to a face
  33.             if (masks.containsKey(sums[i]))
  34.                 masks.get(sums[i]).add(i);
  35.         }
  36.        
  37.         //expected value for each subset of (remaining) blocks
  38.         double[] E = new double[1 << B];
  39.        
  40.         for (int i = 0; i < E.length; i++) {
  41.            
  42.             int def = sums[i];
  43.             double[] choices = new double[F];
  44.            
  45.             /*
  46.              * default value for every face of the dice will be the current block sum
  47.              * (given the face f, if there is no subset of the blocks that sum up to f
  48.              *  no further blocks will be removed and the game ends)
  49.              */
  50.             Arrays.fill(choices, def);
  51.            
  52.             for (int s = i; s > 0; s = (s - 1) & i) { //for each subset of i
  53.                 for (int j = 0; j < F; j++) { //for each face
  54.                     if (masks.get(face[j]).contains(s))
  55.                         /*
  56.                          * dynamic programming:
  57.                          * 1. remove from i the current subset of remaining blocks that add up to a face
  58.                          * 2. the expected value of the remaining subset of blocks was already calculated
  59.                          * 3. store the value for later calculation of expected value of i
  60.                          *
  61.                          * here: want to minimize total expected value, so just find the minimum
  62.                          * (this also means that we always have a constant number of choices (the number of faces))
  63.                          */
  64.                         choices[j] = Math.min(choices[j], E[i & ~s]);
  65.                 }
  66.             }
  67.            
  68.             //calculate expected value for subset of (remaining) blocks i
  69.             for (double e : choices)
  70.                 E[i] += e;
  71.             E[i] /= F;
  72.         }
  73.        
  74.         //return expected value of the set of blocks (no blocks removed)
  75.         return E[(1 << B) - 1];
  76.     }
  77. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement