常见的解空间结构
1.子集树
概述:子集树是使用回溯法解题时经常遇到的一种典型的解空间树。当所给的问题是从n个元素组成的集合S中找出满足某种性质的一个子集时,相应的解空间树称为子集树。此类问题解的形式为n元组(x1,x2…xn),分量xi(1,2,…n)表示第i个元素是否在要找的子集中。xi的取值为0或者1,xi=0 表示第i个元素不在要找的子集中;xi=1 表示第i个元素在要找的子集中。
在这里插入图片描述
树的根结点:初始状态
中间结点:某种情况下的中间状态
叶子结点:结束状态
分支:从一个状态过渡到另一个状态的行为
从根节点到叶子结点的路径:一个可能的解(一个子集)
子集树的深度:等于问题的规模
解空间为子集树的常见问题:
(1)0-1背包问题;
(2)子集和问题;
(3)装载问题;
(4)最大团问题。
算法描述模式:


int backtrack(int k)     //k表示扩展结点在解空间树中所处的层次
{
    
    if(k>n)             //n标识问题的规模
        output(x);      //x是存放当前解的一维数组
    
    if(constraint(k))   //约束函数
    {  
         //做相关标识
        backtrack(k+1)
        //做相关标识的反操作 
    }    
    if(bound(k))       //限定函数
    {
        //做相关标识
        backtrack(k+1)
        //做相关标识的反操作 

    }
    
}

2.排列数
概述:排列树是用回溯法解题时遇到的第二种典型的解空间树。当所给的问题是从n个元素的排列中找出某种性质的一个排列时,相应的解空间树称为排列树。此类问题解的形式为n元组(x1,x2,…,xn),分量xi(i=1,2,…,n)表示第i个位置的元素是xi。n个元素组成的集合为S={1,2,…,n},xi->(S-(x1,x2,…,x(i-1))),i=1,2,…,n.
在这里插入图片描述
树的根结点:初始状态(所有位置全部没有放置元素)
中间结点:某种情况下的中间状态(中间节点之前的位置已经确定了元素,中间结点之后的节点还没有确定元素)
叶子结点:结束状态(所有位置上的元素全部确定)
分支:从一个状态过渡到另一个状态的行为(在特定位置上放置元素)
从根节点到叶子结点的路径:一个可能的解(所有元素的一个全排列)
子集树的深度:等于问题的规模
解空间为排列树的常见问题:
(1)n皇后问题;
(2)旅行商问题;
(3)园排列问题;
(4)电路板排列问题。
算法描述模式:

int backtrack(int t)      //t表示扩展结点在解空间树中所处的层次
{
    
    if(t>n)              //n标识问题的规模
        output(x);       //x是存放当前解的一维数组
    else
    {
        for(int i=t;i<=n;i++)
        {
            swap(x[t],x[i]);              //实现两个位置的交换
            if(constraint(t)&&bound(t))   //约束函数与限定函数
            backtrack(t+1)                //递归
            swap(x[t],x[i]);              //恢复原状
            
        }
        
    }
    
}
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐