子集和问题



子集和问题

在**子集和问题**中,给定一个包含一些非负整数元素的集合。同时还提供一个和值,我们的任务是找到给定集合的所有可能的子集,其元素之和与给定的和值相同。

**集合:**在数学术语中,**集合**被定义为相似类型对象的集合。集合的实体或对象必须通过相同的规则相互关联。

**子集:**假设有两个集合,即集合P和集合Q。当且仅当集合P的所有元素也属于集合Q时,集合P被称为集合Q的子集,反之则不一定成立。

输入输出场景

假设给定的集合和和值如下:

 Set = {1, 9, 7, 5, 18, 12, 20, 15}
 sum value = 35

给定集合的所有可能的子集,其中每个子集的每个元素的和与给定的和值相同,如下所示:

 {1  9  7  18}  
 {1  9  5  20}  
 {5  18  12}

回溯法解决子集和问题

在解决子集和问题的朴素方法中,算法生成所有可能的排列,然后逐个检查有效解。每当一个解满足约束条件时,将其标记为解的一部分。

在解决子集和问题时,回溯法用于选择有效的子集。当一个项目无效时,我们将回溯以获取先前的子集,并添加另一个元素以获得解。

在最坏情况下,回溯法可能会生成所有组合,但是,通常情况下,它的性能优于朴素方法。

请按照以下步骤使用回溯法解决子集和问题:

  • 首先,取一个空子集。

  • 将下一个元素(索引为0)包含到空集中。

  • 如果子集等于和值,则将其标记为解的一部分。

  • 如果子集不是解并且小于和值,则向子集中添加下一个元素,直到找到有效的解。

  • 现在,转到集合中的下一个元素并检查另一个解,直到所有组合都已尝试过。

示例

在本示例中,我们将说明如何在各种编程语言中解决子集和问题。

#include <stdio.h>
#define SIZE 7
void displaySubset(int subSet[], int size) {
   for(int i = 0; i < size; i++) {
      printf("%d  ", subSet[i]);
   }
   printf("\n");
}
void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount ,int sum) {
   if( total == sum) {
      //print the subset 
      displaySubset(subSet, subSize);  
      //for other subsets
      if (subSize != 0)
         subsetSum(set,subSet,n,subSize-2,total-set[nodeCount],nodeCount+1,sum);     
      return;
   }else {
      //find node along breadth 
      for( int i = nodeCount; i < n; i++ ) {     
         subSet[subSize] = set[i];
          //do for next node in depth
         subsetSum(set,subSet,n,subSize+1,total+set[i],i+1,sum);    
      }
   }
}
void findSubset(int set[], int size, int sum) {
   //create subset array to pass parameter of subsetSum
   int subSet[size];     
   subsetSum(set, subSet, size, 0, 0, 0, sum);
}
int main() {
   int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
   int size = SIZE;
   findSubset(weights, size, 35);
   return 0;
}
#include <iostream>
using namespace std;
void displaySubset(int subSet[], int size) {
   for(int i = 0; i < size; i++) {
      cout << subSet[i] << "  ";
   }
   cout << endl;
}
void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount, int sum) {
   if( total == sum) {
      //print the subset 
      displaySubset(subSet, subSize);  
      //for other subsets
      subsetSum(set, subSet, n, subSize-1, total-set[nodeCount], nodeCount+1,sum);     
      return;
   }else {
      //find node along breadth 
      for( int i = nodeCount; i < n; i++ ) {     
         subSet[subSize] = set[i];
          //do for next node in depth
         subsetSum(set, subSet, n, subSize+1, total+set[i], i+1, sum);    
      }
   }
}
void findSubset(int set[], int size, int sum) {
   //create subset array to pass parameter of subsetSum
   int *subSet = new int[size];     
   subsetSum(set, subSet, size, 0, 0, 0, sum);
   delete[] subSet;
}
int main() {
   int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
   int size = 7;
   findSubset(weights, size, 35);
}
public class Main {
   static void displaySubset(int subSet[], int size) {
      for(int i = 0; i < size; i++) {
         System.out.print(subSet[i] + "  ");
      }
      System.out.println();
   }
   static void subsetSum(int set[], int subSet[], int n, int subSize, int total, int nodeCount ,int sum) {
      if( total == sum) {
         //print the subset 
         displaySubset(subSet, subSize);  
         //for other subsets
         if (subSize != 0)
            subsetSum(set,subSet,n,subSize-1,total-set[nodeCount],nodeCount+1,sum);     
         return;
      } else {
         //find node along breadth 
         for( int i = nodeCount; i < n; i++ ) {     
            subSet[subSize] = set[i];
            //do for next node in depth
            subsetSum(set,subSet,n,subSize+1,total+set[i],i+1,sum);    
         }
      }
   }
   static void findSubset(int set[], int size, int sum) {
      //create subset array to pass parameter of subsetSum
      int subSet[] = new int[size];     
      subsetSum(set, subSet, size, 0, 0, 0, sum);
   }
   public static void main(String[] args) {
      int weights[] = {1, 9, 7, 5, 18, 12, 20, 15};
      int size = 7;
      findSubset(weights, size, 35);
   }
}
def displaySubset(subSet, size):
    for i in range(size):
        print(subSet[i], end="  ")
    print()

def subsetSum(set, subSet, n, subSize, total, nodeCount, sum):
    if total == sum:
        #print the subset 
        displaySubset(subSet, subSize)
        #for other subsets
        if subSize != 0:
            subsetSum(set, subSet, n, subSize-1, total-set[nodeCount], nodeCount+1, sum)
        return
    else:
        #find node along breadth 
        for i in range(nodeCount, n):
            subSet[subSize] = set[i]
            #do for next node in depth
            subsetSum(set, subSet, n, subSize+1, total+set[i], i+1, sum)

def findSubset(set, size, sum):
    #create subset array to pass parameter of subsetSum
    subSet = [0]*size
    subsetSum(set, subSet, size, 0, 0, 0, sum)

if __name__ == "__main__":
    weights = [1, 9, 7, 5, 18, 12, 20, 15]
    size = 7
    findSubset(weights, size, 35)

输出

1  9  7  18  
1  9  5  20  
5  18  12  
广告