#java #knapsack-problem #subset-sum
#java #проблема с рюкзаком #подмножество-сумма
Вопрос:
Кто-нибудь знает, как реализовать проблему суммы подмножеств в Java с помощью этого псевдокода?
w = an array of positive integers sorted in non-decreasing order.
W = the target sum value
include = an array or arraylist of the solutions who's weight adds up to W. After the print statement, this array can be deleted so that it can store the next solution.
weight = weight of elements in the include array.
total = weight of the remaining elements not in the include array.
public static void sum_of_subsets(index i, int weight, int total)
{
if(promising(i))
{
if(weight == W)
{
System.out.print(include[1] through include[i]);
}
else
{
include[i 1] = "yes"; //Include w[i 1]
sum_of)subsets(i 1, weight w[i 1], total - w[i 1]);
include[i 1] = "no"; //Do not include w[i 1]
sum_of_subsets(i 1, weight, total - w[i 1]);
}
}
}
public static boolean promising(index i);
{
return (weight total >= W) amp;amp; (weight == W || weight w[i 1] <= W);
}
это действительно ставит меня в тупик, поэтому, если бы вы могли добавить комментарии, это было бы здорово!!!
Комментарии:
1. Это домашнее задание? Пожалуйста, пометьте ее как таковую.
Ответ №1:
Эта программа находит точные пары из набора чисел для формирования желаемой суммы, программа также возвращает уникальные пары в конце. Программа также возвращает ближайшее подмножество для формирования желаемой суммы, если точное подмножество не найдено. Вы можете запустить программу как есть, чтобы посмотреть демонстрацию, а затем внести изменения, если это необходимо. Логика, которую я применил здесь, основана на всех комбинациях чисел в данном наборе, чтобы получить желаемую сумму, вы можете обратиться к встроенным комментариям для получения дополнительной информации
package com.test;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
*
* @author ziya sayed
* @email : sayedziya@gmail.com
*/
public class SumOfSubsets{
// private static int[] numbers= {1,1,2,2,3,4};//set of numbers
private static int[] numbers= {18,17,1};//set of numbers
// private static final int SUM = 4;//desired sum
private static final int SUM = 20;//desired sum
public static void main(String[] args) {
String binaryCount="";
int[] nos=new int[numbers.length];
//input set, and setting binary counter
System.out.print("Input set numbers are : ");
for (int no : numbers) {
if (no<=SUM) {
System.out.print(no " ");
nos[binaryCount.length()]=no;
binaryCount =1; //can we use sring builder or string.format
}
}
System.out.println();
Arrays.sort(nos);//sort asc
int totalNos = binaryCount.length();
String subset=""; //chosen subset
int subsetSum=0;//to temp hold sum of chosen subset every iteration
String nearestSubset="";//chosen closest subset if no exact subset
int nearestSubsetSum=0;//to hold sum of chosen closest subset
Set<String> rs = new HashSet<String>();//to hold result, it will also avoide duplicate pairs
for (int i = Integer.parseInt(binaryCount, 2) ; i >0;i-- ) {//for all sum combinations
// System.out.println(i);
binaryCount=String.format("%1$#" totalNos "s", Integer.toBinaryString(i)).replace(" ","0");//pad 0 to left if number is less than 6 digit binary for proper combinations
subset="";
subsetSum=0;
for (int j=0 ;j<totalNos; j ) {//for active combinations sum
if (binaryCount.charAt(j)=='1') {
subset =nos[j] " ";
subsetSum =nos[j];
}
}
if (subsetSum == SUM) {
// System.out.println(subset);//we can exit here if we need only one set
rs.add(subset);
}
else{//use this for subset of numbers with nearest to desired sum
if (subsetSum < SUM amp;amp; subsetSum > nearestSubsetSum amp;amp; rs.isEmpty()) {
nearestSubsetSum = subsetSum;
nearestSubset = subset;
}
}
}
if (rs.isEmpty()) {
System.out.println("Nearest Subset of " SUM);
System.out.println(nearestSubset);
}
else{
System.out.println("Exact Subset of " SUM);
System.out.println(rs);//unique sub sets to remove duplicate pairs
}
}
}
Комментарии:
1. Почему пары? В задаче говорится о подмножестве.
2. java.util. Исключение FormatFlagsConversionMismatchException: Преобразование = s, флаги = # в binaryCount=String.format(«% 1 $ #» totalNos «s», целое число. toBinaryString(i)).replace(» «,»0»);
Ответ №2:
Алгоритмы, закодированные на Java
Сначала алгоритм удаляет все числа, которые для начала больше суммы.
Затем для наибольшего числа, меньшего суммы, он проверяет, есть ли в списке какие-либо числа, которые он может добавить к себе, чтобы получить сумму. Как только мы либо найдем пару, либо сумма превысит желаемую сумму, мы можем прерваться, поскольку список отсортирован. Затем мы рассмотрим второе по величине число и посмотрим, сможем ли мы составить с ним пару, и так далее.
/**
* This will find how many pairs of numbers in the given array sum
* up to the given number.
*
* @param array - array of integers
* @param sum - The sum
* @return int - number of pairs.
*/
public static int sumOfSubset(int[] array, int sum)
{
// This has a complexity of O ( n lg n )
Arrays.sort(array);
int pairCount = 0;
int leftIndex = 0;
int rightIndex = array.length - 1;
// The portion below has a complextiy of
// O ( n ) in the worst case.
while (array[rightIndex] > sum array[0])
{
rightIndex--;
}
while (leftIndex < rightIndex)
{
if (array[leftIndex] array[rightIndex] == sum)
{
pairCount ;
leftIndex ;
rightIndex--;
}
else if(array[leftIndex] array[rightIndex] < sum)
{
leftIndex ;
}
else
{
rightIndex--;
}
}
return pairCount;
}
Приведенный выше алгоритм не возвращает пары, но это тривиально добавить.
Комментарии:
1. Приведенный выше ответ неверен,,, возьмем пример 1,1,2,2,3,4,,,,, он не обнаружит 1,1,2 для суммы 4