All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.skjolberg.packing.PermutationRotationIterator Maven / Gradle / Ivy

There is a newer version: 1.2.5
Show newest version
package com.github.skjolberg.packing;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * Rotation and permutations built into the same class. Minimizes the number of
 * rotations. 
*
* The maximum number of combinations is n! * 6^n, however after accounting for * bounds and sides with equal lengths the number can be a lot lower (and this * number can be obtained before starting the calculation).
*
* Assumes a do-while approach: * *
{@code 
 * do {
 * 	do {
 * 		for (int i = 0; i < n; i++) {
 * 			Box box = instance.get(i);
 * 			// .. your code here
 * 		}
 * 	} while (instance.nextRotation());
 * } while (instance.nextPermutation());
 * 
 * }
* * @see next-lexicographical-permutation-algorithm */ public class PermutationRotationIterator { public static Box[][] toRotationMatrix(List list, boolean rotate3D) { Box[][] boxes = new Box[list.size()][]; for(int i = 0; i < list.size(); i++) { boxes[i] = new Box[rotate3D ? 6 : 2]; Box box = list.get(i); List result = new ArrayList<>(); if(rotate3D) { Box box0 = box.clone(); boolean square0 = box.isSquare2D(); result.add(box0); if(!box.isSquare3D()) { box.rotate3D(); boolean square1 = box.isSquare2D(); result.add(box.clone()); box.rotate3D(); boolean square2 = box.isSquare2D(); result.add(box.clone()); if(!square0 && !square1 && !square2) { box.rotate2D3D(); result.add(box.clone()); box.rotate3D(); result.add(box.clone()); box.rotate3D(); result.add(box.clone()); } } } else { result.add(box.clone()); // do not rotate 2d if square if(!box.isSquare2D()) { result.add(box.clone().rotate2D()); } } boxes[i] = result.toArray(new Box[result.size()]); } return boxes; } private Box[][] matrix; private int[] reset; private int[] rotations; // 2^n or 6^n private int[] permutations; // n! public PermutationRotationIterator(List list, Dimension bound, boolean rotate3D) { this(bound, toRotationMatrix(list, rotate3D)); } public PermutationRotationIterator(Dimension bound, Box[][] unconstrained) { Box[][] matrix = new Box[unconstrained.length][]; for(int i = 0; i < unconstrained.length; i++) { List result = new ArrayList<>(); for(int k = 0; k < unconstrained[i].length; k++) { if(unconstrained[i][k] != null && unconstrained[i][k].fitsInside3D(bound)) { result.add(unconstrained[i][k]); } } matrix[i] = result.toArray(new Box[result.size()]); } this.matrix = matrix; // permutations is a 'pointer' list permutations = new int[matrix.length]; for(int i = 0; i < matrix.length; i++) { permutations[i] = i; } reset = new int[matrix.length]; rotations = new int[reset.length]; System.arraycopy(reset, 0, rotations, 0, rotations.length); } public boolean nextRotation() { // next rotation for(int i = 0; i < rotations.length; i++) { while(rotations[i] < matrix[i].length - 1) { rotations[i]++; // reset all previous counters System.arraycopy(reset, 0, rotations, 0, i); return true; } } return false; } public boolean isWithinHeight(int fromIndex, int height) { for(int i = fromIndex; i < matrix.length; i++) { if(matrix[permutations[i]][rotations[permutations[i]]].getHeight() > height) { return false; } } return true; } protected void resetRotations() { System.arraycopy(reset, 0, rotations, 0, rotations.length); } public long countRotations() { long n = 1; for(int i = 0; i < rotations.length; i++) { n = n * matrix[i].length; } return n; } public long countPermutations() { long n = 1; for(int i = 0; i < matrix.length; i++) { n = n * (i + 1); } return n; } public Box get(int index) { return matrix[permutations[index]][rotations[permutations[index]]]; } public boolean nextPermutation() { resetRotations(); // Find longest non-increasing suffix int i = permutations.length - 1; while (i > 0 && permutations[i - 1] >= permutations[i]) i--; // Now i is the head index of the suffix // Are we at the last permutation already? if (i <= 0) { return false; } // Let array[i - 1] be the pivot // Find rightmost element that exceeds the pivot int j = permutations.length - 1; while (permutations[j] <= permutations[i - 1]) j--; // Now the value array[j] will become the new pivot // Assertion: j >= i // Swap the pivot with j int temp = permutations[i - 1]; permutations[i - 1] = permutations[j]; permutations[j] = temp; // Reverse the suffix j = permutations.length - 1; while (i < j) { temp = permutations[i]; permutations[i] = permutations[j]; permutations[j] = temp; i++; j--; } // Successfully computed the next permutation return true; } public int length() { return rotations.length; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy