导航:首页 > 源码编译 > 子集递归算法

子集递归算法

发布时间:2022-08-04 03:56:11

算法的子集和数问题

回溯算法设计2008-05-29 10:15 P.M.[实验目的]

1. 掌握回溯法解题的基本思想;

2. 掌握回溯算法的设计方法;

3. 针对子集和数问题,熟练掌握回溯递归算法、迭代算法的设计与实现。

[预习要求]

1. 认真阅读教材或参考书, 掌握回溯法解题的基本思想, 算法的抽象控制策略;

2. 了解子集和数问题及解向量的定长和变长状态空间表示;

3. 针对解向量的定长表示, 设计状态空间树节点扩展的规范(限界)函数及实现方法;

4. 分析深度优先扩展状态空间树节点或回溯的条件;

5. 分析和设计生成解向量各分量可选值的实现方法;

6. 设计和编制回溯算法的递归和迭代程序。

[参考数据类型或变量]

float s; // 表示有可能抵达答案节点的子路径上的元素之和;

float r; // 尚未测试的剩余集合元素之和;

float w[n]; // 存储原始集合的n个元素, 根据问题实例初始化;

int x[n]; // 定长表示的解向量, 各元素初始值为0;

[参考子程序接口与功能描述]

void RecursiveSubset(float s, float r, int k)

功能: 针对问题实例的递归回溯算法。

void IterativeSubset(int m)

功能: 针对问题实例的迭代回溯算法。

void InitializeInstanse(void)

功能: 问题实例的初始化函数, 初始化子集和数M , w, x向量, s, r。

[实验步骤]

1. 录入、修改并测试你的程序,直至正确为止;

2. 针对问题实例,实录运行时的输入、输出界面;

3. 将你的程序和实录的界面存盘备用。

[实验报告要求]

1. 阐述实验目的和实验内容;

2. 提交模块化的实验程序源代码;

3. 简述程序的测试过程,提交实录的输入、输出界面;

4. 鼓励对实验内容展开讨论,鼓励提交思考与练习题的代码和测试结果。

[思考与练习]

1. 试针对解向量的变长表示设计回溯算法,上机测试正确性。

2. 试针对0/1背包问题设计回溯算法,比较与子集和数问题的算法差异。

#include<stdio.h>
#define n 3
float s; /*表示有可能抵达答案节点的子路径上的元素之和;*/
float r; /*尚未测试的剩余集合元素之和;*/
float w[n]={2,3,4}; /*存储原始集合的n个元素, 根据问题实例初始化;*/
int x[n]; /*定长表示的解向量, 各元素初始值为0;*/
int M;
int k;

void RecursiveSubset(float s, float r, int k)/*针对问题实例的递归回溯算法*/
{int i;
x[k-1]=1;
if(s+w[k-1]==M)
{for(i=0;i<n;i++)
printf("%2d",x[i]);
printf("\n");}

else if(((s+r)>=M)&&((s+w[k-1]+w[k]<=M)))
RecursiveSubset(s+w[k-1],r-w[k-1],k+1);
if((s+r-w[k-1]>=M)&&((s+w[k])<=M))
{x[k-1]=0;
RecursiveSubset(s,r-w[k-1],k+1);
}
}
void IterativeSubset(int m)/*针对问题实例的迭代回溯算法*/
{int i;
for(i=0;i<m;i++) x[i]=2;
for(i=k-1;i<n;i++) r+=w[i];
k=1;
while(k>0)
{--x[k-1];
if(x[k-1]==0)
{if((s+r-w[k-1]>=M)&&(s+w[k]<=M))
{s+=x[k-1]*w[k-1];
r-=w[k-1];
k++;
continue;
}
else{
--k;
s-=x[k-1]*w[k-1];
r+=w[k-1];
for(i=k;i<m-1;i++)
x[i]=2;
continue;
}
}
if(s+w[k-1]==M)
for(i=0;i<n;i++)
{printf("%2d",x[i]);}
else if((s+r>=M)&&(s+w[k-1]+w[k]<=M))
{s+=w[k-1];r-=w[k-1];k++;}
}
printf("\n");
}
void InitializeInstanse(void) /*问题实例的初始化函数, 初始化子集和数M , w, x向量, s, r*/
{int i;
printf("Enter M:");
scanf("%d",&M);
for(i=0;i<n;i++)x[i]=0;
for(i=k-1;i<n;i++) r+=w[i];
for(i=0;i<k-2;i++) s+=x[i]*w[i];
}
main()
{InitializeInstanse();
RecursiveSubset(s,r,k);
IterativeSubset(n);
system("pause");

㈡ 求高手解答一个算法!!!!!!

#include<stdio.h>
int n,a[100],r; /*数组a为记录集合的元素*/
int ans[100]; /*记录子集的元素*/
void solve(int k,int p) /*在子集数组ans里已有k个元素,p为ans最后的元素下标*/
{
int i;
if(k>r) /*已经找到一个子集*/
{
for(i=1;i<=r;i++) /*显示子集*/
printf("%d ",ans[i]);
printf("\n");
return;
}
if(p>n) /*找不到子集*/
return;
for(i=p+1;i<=n;i++) /*递归查找子集*/
{
ans[k]=a[i]; /*当前元素放进子集数组*/
solve(k+1,i); /*下一个元素*/
}
}
void main()
{
int i;
scanf("%d%d",&n,&r);
for(i=1;i<=n;i++) /*初始集合数组元素*/
a[i]=i;
solve(1,0); /*查找开始*/
}

上面的程序还可以优化,可以让速度更快些,更省空间!你自己看看吧!还有最好是看懂程序,不要照抄!你还可以用其他方法,这是用了递归回溯算法!

java树级对象递归查找子集问题

packagecom.demo.dept;

/**
*@authordongbin.yu
*@from2016-05-06
*@sinceV1.0
*/
publicclassDept{

privateintid;

privateStringname;

privateintparentId;

publicintgetId(){
returnid;
}

publicvoidsetId(intid){
this.id=id;
}

publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

publicintgetParentId(){
returnparentId;
}

publicvoidsetParentId(intparentId){
this.parentId=parentId;
}

publicDept(intid,Stringname,intparentId){
this.id=id;
this.name=name;
this.parentId=parentId;
}
}
packagecom.demo.dept;

importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;

/**
*@authordongbin.yu
*@from2016-05-06
*@sinceV1.0
*/
publicclassDeptTest{

privatestaticList<Dept>depts=newArrayList<>();

static{
depts.add(newDept(1,"部门1",0));
depts.add(newDept(2,"部门2",1));
depts.add(newDept(3,"部门3",1));
depts.add(newDept(4,"部门4",1));
depts.add(newDept(5,"部门5",2));
depts.add(newDept(6,"部门6",3));
depts.add(newDept(7,"部门7",2));
depts.add(newDept(8,"部门8",2));
depts.add(newDept(9,"部门9",1));
depts.add(newDept(10,"部门10",5));
}

publicstaticvoidmain(String[]args){
Map<Integer,List<Integer>>deptMap=newHashMap<>();

for(Deptdept:depts){
deptMap.put(dept.getId(),getChildDept(dept.getId()));
}

System.out.println(deptMap);

}

privatestaticList<Integer>getChildDept(intid){
List<Integer>ids=newArrayList<>();

for(Deptdept:depts){
if(dept.getParentId()==id){
//添加第一次父id符合的
ids.add(dept.getId());
//添加嵌套父id符合的
ids.addAll(getChildDept(dept.getId()));
}
}
Collections.sort(ids);
returnids;
}

}

㈣ 用c++求2-10个正整数的子集,递归算法求解。

如果你说的是打印出所有可能的集合的话..
#include<iostream>

void printSet(int*, int);
int* Set(int*, int, int);

void getSubSet(int* set, int len) {
if(len > 0) {
printSet(set, len);
for(int i = 0; i < len; i++) {
getSubSet(Set(set, len, i), len - 1);
}
}
}

int* Set(int* set, int len, int index) { //return a set with less 1 count. specfic the index.
int j = 0;
int *set2 = new int[len - 1];
for(int i = 0; i < len; i++) {
if(index != i) {
set2[j++] = set[i];
}
}
return set2;
}

void printSet(int* set, int len) {
using namespace std;
cout << "{ ";
for(int i = 0; i < len; i++) {
cout << set[i] << ", ";
}
cout << "}" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
int i = 0;
while(1) {
cout << "Getting all subsets..." << endl;
cout << "How many numbers do you wanna input ? " ;
cin >> i;
if(cin.good() && i >= 2 && i <= 10) break;
cin.clear();
}
int* set = new int[i];
for(int j = 0; j < i; j++) {
cout << endl << "Input number " << j + 1 << ": ";
cin >> set[j];
if(!cin.good()) {
cout << "Bad input, quitting...";
system("pause");
return 0;
}
}
printSet(set, i);
system("pause");
cout << endl << "Now printing Set... " << endl;
getSubSet(set, i);
delete[] set;
cout << endl << "Finished, press any key to quit. " << endl;
system("pause");
return 0;
}

㈤ 写一个递归算法

用C++实现的,希望对你有所帮助:(还有种的经典的算法:000,001,010...111每一位表示是否包含这个元素,自己可以再想想)
#include<iostream>
using namespace std;
template<class T>
void powerset(T *a,T* b,int n1,int n2,int n)
{
if(n1==-1)
{
int j=n-1;
if(j<n2+1){cout<<"空集";}
for(;j>=n2+1;j--)
{
if(j==n-1){cout<<"{";}
if(j==n2+1){cout<<b[j]<<"}";}
else {cout<<b[j]<<",";}
}
cout<<endl;
}
else
{
for(int i=n1-1;i>=-1;i--)
{
if(i!=-1){b[n2-1]=a[i];}
powerset(a,b,i,n2-1,n);
}

}
}
template<class T>
void ChildUnion(T* a,int n)
{
T* b=new T[n];
powerset(a,b,n,n,n);

delete []b;

}
void main()
{
int a[4]={0,1,2,3};
ChildUnion(a,4);
}

㈥ 求用递归法求一个集合的子集的C++代码!!

参考下面的

找出从自然数1、2、……、n中任取r个数的所有组合。例如n=5,r=3

的所有组合为:

(1)5、4、3 (2)5、4、2 (3)5、4、1
(4)5、3、2 (5)5、3、1 (6)5、2、1
(7)4、3、2 (8)4、3、1 (9)4、2、1
(10)3、2、1
分析所列的10个组合,可以采用这样的递归思想来考虑求组合函数的算法。设函数为void comb(int m,int k)为找出从自然数1、2、……、m中任取k个数的所有组合。当组合的第一个数字选定时,其后的数字是从余下的m-1个数中取k-1数的组合。这就将求m个数中取k个数的组合问题转化成求m-1个数中取k-1个数的组合问题。设函数引入工作数组a[ ]存放求出的组合的数字,约定函数将确定的k个数字组合的第一个数字放在a[k]中,当一个组合求出后,才将a[ ]中的一个组合输出。第一个数可以是m、m-1、……、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未去顶组合的其余元素,继续递归去确定;或因已确定了组合的全部元素,输出这个组合。细节见以下程序中的函数comb。
【程序】
# include
# define MAXN 100
int a[MAXN];
void comb(int m,int k)
{ int i,j;
for (i=m;i>=k;i--)
{ a[k]=i;
if (k>1)
comb(i-1,k-1);
else
{ for (j=a[0];j>0;j--)
printf(“%4d”,a[j]);
printf(“\n”);
}
}
}

void main()
{ a[0]=3;
comb(5,3);
}

python 子集的算法优化; 找寻一个list的所有满足特定条件的子集

使用 itertools呀

importitertools

#有序
printlist(itertools.permutations([1,2,3,4],2))
[(1,2),(1,3),(1,4),(2,1),(2,3),(2,4),(3,1),(3,2),(3,4),(4,1),(4,2),(4,3)]

#无序
printlist(itertools.combinations([1,2,3,4],2))
[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]

㈧ 请问递归算法的时间复杂度如何计算呢

递归算法的时间复杂度在算法中,当一个算法中包含递归调用时,其时间复杂度的分析会转化为一个递归方程求解,常用以下四种方法:

1.代入法(Substitution Method)

代入法的基本步骤是先推测递归方程的显式解,然后用数学归纳法来验证该解是否合理。

2.递归程序设计是程序设计中常用的一种方法,它可以解决所有有递归属性的问题,并且是行之有效的.

3.但对于递归程序运行的效率比较低,无论是时间还是空间都比非递归程序更费,若在程序中消除递归调用,则其运行时间可大为节省.

㈨ 递归输出集合子集

思路: 对于某个集合元素 e 和某个子集subset, e要不就在这个集合中,要不就不在。 故,只需枚举所有元素的在或不在某子集, 即可枚举所有子集。

不标准伪代码: 不妨设集合元素为 e[0] 到 e[n-1] 共n个, 用数组 flag[0] 到 flag[n-1] 代表i元素是否在当前集合

void Output( i )
{
if ( i == 集合元素个数n)
{
根据flag数组输出当前集合(在或不在);
return;
}
flag[i] = 在当前集合;
Output(i + 1);
flag[i] = 不在当前集合;
Output(i + 1);
}

初始化时 flag[0] 到flag[n-1]都为 ‘不在当前集合’;
初始调用 Output(0);

阅读全文

与子集递归算法相关的资料

热点内容
收支预算法怎么做 浏览:875
模板如何上传到服务器 浏览:372
如何同步安卓信息到新ipad 浏览:364
腾讯云轻量服务器流量警告 浏览:503
u盘备份linux 浏览:120
高压缩比活塞 浏览:92
压缩弹簧标准件 浏览:25
linux统计个数命令 浏览:292
cad转pdf居中 浏览:8
编译型语言处理过程 浏览:325
手机创文件夹复制到电脑 浏览:984
有什么直播APP可以看那种 浏览:41
程序员叫什么人 浏览:378
python画地图等高线 浏览:751
epic永劫无间是什么服务器 浏览:444
网游服务器下载地址 浏览:107
macphpfreetype安装 浏览:644
设计道pdf 浏览:615
单片机kill4软件下载收费吗 浏览:846
苹果手机怎么连接RMS服务器 浏览:603