Try the following:
import java.util.Arrays; public class Test { public static void main(String [] args){ int [] arr = {7, 11, 1, 9, 10, 3, 5, 13, 9, 12}; int [][] res = combinations(5, arr); int N = Arrays.stream(arr).reduce(1, (a, b) -> a * b); int min = Integer.MAX_VALUE; int [] opt = new int [5]; for (int [] i : res){ int k = (int) Math.abs( Math.pow(Arrays.stream(i).sum(), 2) - N/(Arrays.stream(i).reduce(1, (a, b) -> a * b))); if(k < min){ min = k; opt = i; } } Arrays.sort(opt); System.out.println("minimum difference is "+ min + " with the subset containing this elements " + Arrays.toString(opt)); } // returns all k-sized subsets of a n-sized set public static int[][] combinations(int k, int[] set) { int c = (int) binomial(set.length, k); int[][] res = new int[c][Math.max(0, k)]; int[] ind = k < 0 ? null : new int[k]; for (int i = 0; i < k; ++i) { ind[i] = i; } for (int i = 0; i < c; ++i) { for (int j = 0; j < k; ++j) { res[i][j] = set[ind[j]]; } int x = ind.length - 1; boolean loop; do { loop = false; ind[x] = ind[x] + 1; if (ind[x] > set.length - (k - x)) { --x; loop = x >= 0; } else { for (int x1 = x + 1; x1 < ind.length; ++x1) { ind[x1] = ind[x1 - 1] + 1; } } } while (loop); } return res; } // returns n choose k; // there are n choose k combinations without repetition and without observance of the sequence // private static long binomial(int n, int k) { if (k < 0 || k > n) return 0; if (k > n - k) { k = n - k; } long c = 1; for (int i = 1; i < k+1; ++i) { c = c * (n - (k - i)); c = c / i; } return c; } }
Code taken from https://stackoverflow.com/a/312947/ ... also see this wikipedia article on combinations.
Erythrean
source share