专题二:搜索总结报告

来源:互联网 发布:mac 加速器 编辑:程序博客网 时间:2024/05/01 10:15

搜索专题

1.什么是搜素?

搜索算法是利用计算机的高性能来有目的地穷举一个问题的部分或所有的可能情况,从而求出问题的解的一种方法。

相比于单纯的枚举算法有了一定的方向性和目标性。算法是在解的空间里,从一个状态转移(按照要求拓展)到其他状态,这样进行下去,将解的空间中的状态遍历,找到答案(目标的状态)。

2.搜索算法

广度优先搜索(BFS)

深度优先搜索(DFS)


BFS

基本思想:从初始状态S 开始,利用规则,生成所有可能的状态。构成的下一层节点,检查是否出现目标状态G,若未出现,就对该层所有状态节点,分别顺序利用规则。
生成再下一层的所有状态节点,对这一层的所有状态节点检查是否出现G,若未出现,继续按上面思想生成再下一层的所有状态节点,这样一层一层往下展开。直到出现目标状态为止。

具体过程:
1 每次取出队列首元素(初始状态),进行拓展
2 然后把拓展所得到的可行状态都放到队列里面
3 将初始状态删除
4 一直进行以上三步直到队列为空。

框架:

While Not Queue.Empty ()
 Begin
   可加结束条件
   Tmp = Queue.Top ()
     从Tmp循环拓展下一个状态Next
   If 状态Next合法 Then
      Begin
              生成新状态Next
            Next.Step = Tmp.Step + 1 
           Queue.Pushback (Next)
      End
     Queue.Pop ()
 End



DFS

基本思想:从初始状态,利用规则生成搜索树下一层任一个结点,检查是否出现目标状态,若未出现,以此状态利用规则生成再下一层任一个结点,再检查,重复过程一直到叶节点(即不能再生成新状态节点),当它仍不是目标状态时,回溯到上一层结果,取另一可能扩展搜索的分支。采用相同办法一直进行下去,直到找到目标状态为止。

具体实现过程
1 每次取出栈顶元素,对其进行拓展。
2 若栈顶元素无法继续拓展,则将其从栈中弹出。继续1过程。
3 不断重复直到获得目标状态(取得可行解)
    或栈为空(无解)。

框架:

(1)递归实现:
Function Dfs (Int Step, 当前状态)
Begin
  可加结束条件
   从当前状态循环拓展下一个状态Next
   If 状态Next合法 Then
   Dfs (Step + 1, Next ))
End

 (2)非递归实现

非递归实现:
While Not Stack.Empty ()
 Begin
   Tmp = Stack.top()
   从Tmp拓展下一个未拓展的状态Next
   If 没有未拓展状态(到达叶节点) Then
      Stack.pop() 
      Else If 状态Next合法 Then
     Stack.push(Next)
End


二分搜索算法

简单定义:在一个单调有序的集合中查找元素,每次将集合分为左右两部分,判断解在哪个部分中并调整集合上下界,重复直到找到目标元素。
时间复杂度:O (logn),优于直接顺序查找O(n)

查找连续 函数的写法:

//x:待查找的值,Caculate():所要查找的函数,在这里单调递增
     //需保证查找的值在区间范围内
double low=“区间下界”,high=“区间上界”,mid;
while(high - low > 1.0e-6)
{
mid = (high + low)/2;
    if(Caculate(mid)<x)
        low=mid;
    else
        high=mid;
}

PS对于某些问题,如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。则可以在范围内对答案进行二分验证,从而快速确定答案。


三分算法

当需要求某凸性或凹形函数的极值,通过函数本身表达式并不容易求解时,就可以用三分法不断逼近求解。

程序模板:

double Calc(Type a)
{
    /* 根据题目的意思计算 */
}

void Solve(void)
{
    double Left, Right;
    double mid, midmid;
    double mid_value, midmid_value;
    Left = MIN; Right = MAX;
    while (Left + EPS < Right)
    {
        mid = (Left + Right) / 2;
        midmid = (mid + Right) / 2;
        mid_area = Calc(mid);
        midmid_area = Calc(midmid);
        // 假设求解最大极值.
        if (mid_area >= midmid_area) Right = midmid;
        else Left = mid;
    }
}

专题感悟:

(1)算法真是无穷无尽的

(2)做题的过程中感觉到“理论和实践之间还有很远的距离”

(3)思考问题要灵活一点

(4)在做这个专题的题目时,感觉很多题到了最后其实考验的是数学功底。虽然大一自己学的是数学分析,但是还是觉得数学水平不够

(5)写出代码之后要考虑如何优化,尽可能的减少算法的时间复杂度

(6)自己太弱了,被题目虐的很惨!!!


0 0