Итак, вот ситуация: я написал программу, которая использует рекурсию и выполняет то, что вы ищете. Единственное, что он улавливает самую длинную комбинацию (и) / подмножество (ы) чисел, которые в точности равны целевой сумме (6 в вашем примере); Я не мог понять, как найти самое длинное подмножество, которое было меньше или равно целевой сумме. Кроме того, в вашем примере у вас есть два 1 по цене. Если вы запустите экземпляр моей программы, вы заметите, что он будет обрабатывать два подмножества (более одного поднабора равным 6) как имеющие одинаковый идентификатор для 1, поэтому они являются дублирующими подмножествами. Это еще одна проблема, которую вы могли бы решить. Эта программа заняла у меня более одного дня, поэтому, несмотря на то, что она неисправна и использует рекурсию, я решила опубликовать ее.
import java.util.*;
public class SubSet_sum_problem
{
private static ArrayList<int[]> listOfArrays = new ArrayList<int[]>();
public static void getSubsets(double[] elements, double sum) {
getAllSubsets(elements, 0, sum, new Stack<Double>());
}
private static void getAllSubsets(double[] elements, int i, double sum, Stack<Double> currentSol) {
//stop clauses:
if (sum == 0 && i == elements.length)
{
Object[] prices = currentSol.toArray();
double[] prices2 = new double[currentSol.size()];
for (int index = 0; index < prices.length; index++)
prices2[index] = (Double)prices[index];
int[] indexes = new int[currentSol.size()];
for(int index2 = 0; index2 < prices2.length; index2++) { // Find common/duplicate elements in both arrays
for(int count = 0; count < elements.length; count++) {
if(prices2[index2] == elements[count])
indexes[index2] = count;
}
}
for (int a = 0; a < indexes.length; a++) // Scanning for duplicates again, this time for common indexes
{
for (int b = a + 1; b < indexes.length; b++)
{
if (indexes[a] == indexes[b]) // Now we know we have duplicate indexes for the elements[] array, which isn't possible
{
indexes[a] = a;
indexes[b] = b;
}
}
}
listOfArrays.add(indexes);
}
//if elements must be positive, you can trim search here if sum became negative
if (i == elements.length)
return;
//"guess" the current element in the list:
currentSol.add(elements[i]);
getAllSubsets(elements, i+1, sum-elements[i], currentSol);
//"guess" the current element is not in the list:
currentSol.pop();
getAllSubsets(elements, i+1, sum, currentSol);
}
public static void main(String args[])
{
String name[] = {"pr1", "pr2", "pr3", "pr4", "pr5", "pr6"};
double price[] = {1, 1, 1.5, 3, 2, 4};
double sum = 6.0;
getSubsets(price, sum);
int size = listOfArrays.size();
int max = listOfArrays.get(0).length;
for(int str[] : listOfArrays)
{
int theSize = str.length;
if(max < theSize)
max = theSize;
}
for(int arr[] : listOfArrays)
{
if (arr.length == max)
{
for (int index = 0; index < arr.length; index++)
{
int index2 = arr[index] + 1;
System.out.print("{id: " + index2 + ", name: " + name[arr[index]] + ", price: " + price[arr[index]] + "}\n");
if (index == arr.length - 1)
System.out.print("\n");
}
}
}
}
}