常见的两种解空间 全排列与幂集

1.全排列

全排列解空间是常见的一种解空间.

下面介绍一下它的基本遍历方法

定义Full(a) 为 a 数组的全排列

插入法

a = {1}
//插入 元素2 有两种方式
a = {2,1} , a = {1,2}
//同理再插入 3
a = {3,2,1}, a = {2,3,1} ,a= {2,1,3}
a = {3,1,2}, a = {1,3,2} ,a= {1,2,3}
...
//依此类推即可

队首法

a = {1,2,...,n}

//轮流将元素放在队首
for(i){
	将 i 放在队首
	a = {i, Full(p)}
	//p为剩下元素
	//p只有一个元素即为出口
}

java代码

public static void full(int a[], int n) {
		if (n == a.length) {
			{
				//do something
			}
			return;
		}
		for (int i = n; i < a.length; i++) {//这是队首法
		
		//for (int i = 0; i <= n; i++) {//这是插入法
			
			swap(a, i, n);
			full(a, n + 1);
			swap(a, i, n);
		}
	}

总结

实际上两种方法只是一个对称的关系

插入法是 自底向上 的方法
队首法是 自顶向下 的方法

(ps:方法命名为博主命名,并不权威)

2.幂集

幂集解空间是常见的一种解空间(例如01背包).

下面介绍一下它的基本遍历方法

java代码

这个分析起来并不复杂,每个元素有typeNum中状态 
递归+回溯 即可
public static void mi(int a[], int n) {
		if (n == a.length) {
			{
				// do something
			}
			return;
		}
		for (int i = 0; i < typeNum; i++) {
			//遍历所有装态数
			a[n] = i;
			mi(a, n + 1);
			a[n] = 0;
		}
	}

总结

幂集的暴力遍历是简单的,但是时间复杂度是极高的 O(power(m,n))
所以有很多时候并不选它解决问题,而是使用其他的方法
如 贪心法, 动态规划等



参考文章

(算法)全排列的递归算法Java实现过程

你可能感兴趣的:(常见的两种解空间 全排列与幂集)