@tucuxi @David Eisenstadt, , , n k, .
, , go ( ) , , . , , , . n k .
, , , , , , . tucuxi
. , n, k , -, .
.
.
public class CombinationGenerator {
private final int N;
private final int K;
private final int[] mCurrentCombination;
public CombinationGenerator(int n, int k) {
N = n;
K = k;
mCurrentCombination = new int[k];
setElementSequence(0, 0);
mCurrentCombination[K - 1]--;
}
private void setElementSequence(int startPos, int startValue) {
for (int i = startPos; i < K; i++) {
mCurrentCombination[i] = i + startValue - startPos;
}
}
public int[] getNextCombination() {
for (int i = K - 1; i >= 0; i--) {
if (mCurrentCombination[i] < i + N - K) {
setElementSequence(i, mCurrentCombination[i] + 1);
return mCurrentCombination.clone();
}
}
return null;
}
}
public class CombinationSorter {
private final int N;
private final int K;
public CombinationSorter(int n, int k) {
N = n;
K = k;
}
public List<int[]> getSortedCombinations(List<int[]> combinations) {
List<int[]> sortedCombinations = new LinkedList<int[]>();
int[] combination = null;
int[] hitCounts = new int[N];
while (!combinations.isEmpty()) {
int index = findNextCombination(combinations, hitCounts, combination);
combination = combinations.remove(index);
sortedCombinations.add(combination);
addHitCounts(combination, hitCounts);
}
return sortedCombinations;
}
private int findNextCombination(List<int[]> combinations, int[] hitCounts,
int[] previousCombination) {
int lowestHitCount = Integer.MAX_VALUE;
int foundIndex = 0;
for (int i = 0; i < combinations.size(); i++) {
int[] comb = combinations.get(i);
int hitCount = getHitCount(comb, hitCounts);
if (hitCount < lowestHitCount) {
lowestHitCount = hitCount;
foundIndex = i;
} else if (hitCount == lowestHitCount
&& previousCombination != null
&& getNrCommonElements(comb, previousCombination) < getNrCommonElements(
combinations.get(foundIndex), previousCombination)) {
foundIndex = i;
}
}
return foundIndex;
}
private int getHitCount(int[] combination, int[] hitCounts) {
int hitCount = 0;
for (int i = 0; i < K; i++) {
hitCount += hitCounts[combination[i]];
}
return hitCount;
}
private void addHitCounts(int[] combination, int[] hitCounts) {
for (int i = 0; i < K; i++) {
hitCounts[combination[i]]++;
}
}
private int getNrCommonElements(int[] c1, int[] c2) {
int count = 0;
for (int i = 0; i < K; i++) {
for (int j = 0; j < K; j++) {
if (c1[i] == c2[j]) {
count++;
}
}
}
return count;
}
}
public class Test {
public static void main(String[] args) {
final int n = 7;
final int k = 3;
CombinationGenerator cg = new CombinationGenerator(n, k);
List<int[]> combinations = new LinkedList<int[]>();
int[] nc;
while ((nc = cg.getNextCombination()) != null) {
combinations.add(nc);
}
for (int[] c : combinations) {
System.out.println(Arrays.toString(c));
}
System.out.println("Sorting...");
CombinationSorter cs = new CombinationSorter(n, k);
List<int[]> sortedCombinations = cs.getSortedCombinations(combinations);
for (int[] sc : sortedCombinations) {
System.out.println(Arrays.toString(sc));
}
}
}
:
[0, 1, 2, 3]
[0, 4, 5, 6]
[1, 2, 3, 4]
[0, 1, 5, 6]
[2, 3, 4, 5]
[0, 1, 2, 6]
[3, 4, 5, 6]
[0, 1, 2, 4]
[0, 3, 5, 6]
[1, 2, 4, 5]
[0, 1, 3, 6]
[2, 4, 5, 6]
[0, 1, 3, 4]
[2, 3, 5, 6]
[0, 1, 4, 5]
[0, 2, 3, 6]
[1, 3, 4, 5]
[0, 2, 4, 6]
[1, 2, 3, 5]
[0, 1, 4, 6]
[0, 2, 3, 5]
[1, 2, 4, 6]
[1, 3, 5, 6]
[0, 2, 3, 4]
[1, 2, 5, 6]
[0, 3, 4, 5]
[1, 2, 3, 6]
[0, 2, 4, 5]
[1, 3, 4, 6]
[0, 2, 5, 6]
[0, 1, 3, 5]
[2, 3, 4, 6]
[1, 4, 5, 6]
[0, 1, 2, 5]
[0, 3, 4, 6]
:
[0, 1]
[2, 3]
[0, 4]
[1, 2]
[3, 4]
[0, 2]
[1, 3]
[2, 4]
[0, 3]
[1, 4]