バックトラッキングアルゴリズム1-組み合わせの問題

[質問]
1からnまでのr個の数字のすべての組み合わせを見つけます。たとえば、n = 5とr = 3のすべての組み合わせは次のとおりです。

(1)1、2、3
(2)1、2、4
(3)1、2、5
(4)1、3、4
(5)1、3、5
(6)1、4、5
(7 )2,3,4
(8)2,3,5
(9)2,4,5
(10)3,4,5
バックトラッキング方法によれば、見つかった組み合わせは昇順で配列aに格納されます[0 ]、a [1] 、. a [r-1]の場合、組み合わせの要素は次の特性を満たします。
(1)a [i + 1]> a [i]、つまり、次の数が前の番号;
(2)a [i] -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]からトレースバックするまで、上記の順方向試行と逆方向トレースを繰り返します。

コード:

#include<stdio.h>
#include <iostream>
#define MAX 100 
int a[MAX];
void comb(int n, int r)
{
	int i, j;
	i = 0;
	a[i] = 1;
	do
	{
		if (a[i] - i <= n - r + 1) 			/*还可以向前试探*/
		{
			if (i == r - 1)				/*找到一个组合*/
			{
				for (j = 0; j < r; j++)		/*输出一个组合*/
					printf("%4d", a[j]);
				printf("\n");
				a[i]++;
				continue;
			}
			i++;					/*向前试探*/
			a[i] = a[i - 1] + 1;
		}
		else						/*回溯*/
		{
			if (i == 0)				/*找完全部解*/
				return;
			a[--i]++;
		}
	} while (1);
}
void main()
{
	printf("正整数1~5中的3个数的任意组合:\n");
	comb(5, 3);
	system("pause");
}

結果:

 

おすすめ

転載: blog.csdn.net/baidu_36669549/article/details/104156704