分支限界法-从1到36,最少要几步?

来源:互联网 发布:成女脸型数据 编辑:程序博客网 时间:2024/05/24 07:26

分支限界法基本思想:
分支限界法以广度优先或以最小消耗优先的方式搜索解空间树。
基本策略为:
1.先分支:在扩展结点处,生成其所有的子结点。
2.再限界:根据题目要求设置限界函数,根据函数值,选择所有子结点中最有利的结点作为下一个扩展结点。
经过两步使搜索朝着解空间树上最优的分支推进,以便尽快找出最优解。

问题描述:
输入m,n。假设当前有三种操作:加1,乘2,平方;问从m变换至n最少需要几次运算;

问题分析:
1.根据分支限界法步骤,先分支:每个当前结点将有三个子结点;
2.再限界:若分支后的子结点已经出现,本题中若出现则代表走过则剪枝;若当前的子结点数值超过目标,剪枝;
3.所需数据结构:需要一个队列时刻访问当前结点;需要一个一维数组,记录从起始结点至当前结点的步数,若为-1则表示未经过;

备注:小学生最近开始学英语,大神不要吐槽,指点一二也是好,(^__^) 嘻嘻……

代码展示:

#include <iostream>#include <queue>using namespace std;// note the steps from began to iint step[10001];// for visit current nodequeue<int> q1;//there is a function which is from m to nint FmTn(int n);//there is a function which is the rule of number changeint moveto(int u, int num);int main(){    //readData    int m, n;    cin >> m >> n;    //initData    // -1 means not path from m to i    for (int i(m); i <= n; ++i)        step[i] = -1;    q1.push(m);    step[m] = 0;    //run    cout << FmTn(n) << endl;    return 0;}int FmTn(int n){    int u, v;    while(!q1.empty())    {        // get current node        u = q1.front();        q1.pop();        for (int i(0); i < 3; ++i)        {            *//first : expand*            //the node after three change ways            v = moveto(u, i);            *//last : impose*            //find            if (v == n)                return (step[u] + 1);            //have not found the answer, stroy this path and select next answer            if (v < n && step[v] == -1)            {                q1.push(v);                step[v] = step[u] + 1;            }        }    }}int moveto(int u, int num){    switch(num)    {        case 0: u += 1;break;        case 1: u *= 2;break;        case 2: u *= u;break;        default:break;    }    return u;}
0 0
原创粉丝点击