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

分支限界法基本思想:
分支限界法以广度优先或以最小消耗优先的方式搜索解空间树。
基本策略为:
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 i
int step[10001];
// for visit current node
queue<int> q1;

//there is a function which is from m to n
int FmTn(int n);
//there is a function which is the rule of number change
int 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值