TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
接上一篇[学习常用算法之(3)回溯法]
【问题】 组合问题
问题描述:找出从自然数1,2,…,n中任取r个数的所有组合。
采用回溯法找问题的解,将找到的组合以从小到大顺序存于a[0],a[1],…,a[r-1]中,组合的元素满足以下性质:
(1) a[i+1]>a,后一个数字比前一个大;
(2) a-i<=n-r+1。 按回溯法的思想,找解过程可以叙述如下:
首先放弃组合数个数为r的条件,候选组合从只有一个数字1开始。因该候选解满足除问题规模之外的全部条件,扩大其规模,并使其满足上述条件(1),候选组合改为1,2。继续这一过程,得到候选组合1,2,3。该候选解满足包括问题规模在内的全部条件,因而是一个解。在该解的基础上,选下一个候选解,因a[2]上的3调整为4,以及以后调整为5都满足问题的全部要求,得到解1,2,4和1,2,5。由于对5不能再作调整,就要从a[2]回溯到a[1],这时,a[1]=2,可以调整为3,并向前试探,得到解1,3,4。重复上述向前试探和向后回溯,直至要从a[0]再回溯时,说明已经找完问题的全部解。按上述思想写成程序如下:
- public class TestComb{
- public static void main(String args[]){
- comb(6,3);
- }
- public static void comb(int m,int r){
- int i=0,j;
- int a[]=new int[100];
- a[i]=1;
- do {
- if (a[i]-i<=m-r+1)/*还能向前试探*/
- { if(i==r-1)/*已经找到一个可行的组合解*/
- { for (j=0;j< r;j++)
- System.out.printf("%4d",a[j]);
- System.out.println();
-
- a[i]++;/*调整*/
- continue;
- }
- i++;/*扩展,向前试探*/
- a[i]=a[i-1]+1;
- }
-
- else/*不能试探,理应回溯*/
- { if (i==0) /找到所有可行的解,结束*/
- return;
- a[--i]++; /*调整,向后回溯*/
- }
- }while(true);
- }
- }
复制代码 运行:
C:java>java TestComb
1 2 3
1 2 4
1 2 5
1 2 6
1 3 4
1 3 5
1 3 6
1 4 5
1 4 6
1 5 6
2 3 4
2 3 5
2 3 6
2 4 5
2 4 6
2 5 6
3 4 5
3 4 6
3 5 6
4 5 6 C:java>
源码下载:http://file.javaxxz.com/2014/11/27/000516812.zip |
|