iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > VUE >什么是分支算法
  • 519
分享到

什么是分支算法

2024-04-02 19:04:59 519人浏览 独家记忆
摘要

这篇文章主要介绍“什么是分支算法”,在日常操作中,相信很多人在什么是分支算法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是分支算法”的疑惑有所帮助!接下来,请跟着小编一

这篇文章主要介绍“什么是分支算法”,在日常操作中,相信很多人在什么是分支算法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是分支算法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

前言

分治算法(divide and  conquer)是五大常用算法(分治算法、动态规划算法、贪心算法、回溯法、分治界限法)之一,很多人在平时学习中可能只是知道分治算法,但是可能并没有系统的学习分治算法,本篇就带你较为全面的去认识和了解分治算法。

在学习分治算法之前,问你一个问题,相信大家小时候都有存钱罐的经历,父母亲人如果给钱都会往自己的宝藏中存钱,我们每隔一段时间都会清点清点钱。但是一堆钱让你处理起来你可能觉得很复杂,因为数据相对于大脑有点庞大了,并且很容易算错,你可能会将它先分成几个小份算,然后再叠加起来计算总和就获得这堆钱的总数了

 什么是分支算法

当然如果你觉得各个部分钱数量还是太大,你依然可以进行划分然后合并,我们之所以这么多是因为:

计算每个小堆钱的方式和计算最大堆钱的方式是相同的(区别在于体量上)

然后大堆钱总和其实就是小堆钱结果之和。这样其实就有一种分治的思想。

当然这些钱都是想出来的……

分治算法介绍

分治算法是用了分治思想的一种算法,什么是分治?

分治,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在计算机科学中,分治法就是运用分治思想的一种很重要的算法。分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)等等。

将父问题分解为子问题同等方式求解,这和递归的概念很吻合,所以在分治算法通常以递归的方式实现(当然也有非递归的实现方式)。分治算法的描述从字面上也很容易理解,分、治其实还有个合并的过程:

  • 分(Divide):递归解决较小的问题(到终止层或者可以解决的时候停下)

  • 治(Conquer):递归求解,如果问题够小直接求解。

  • 合并(Combine):将子问题的解构建父类问题

一般分治算法在正文中分解为两个及以上的递归调用,并且子类问题一般是不相交的(互不影响)。当求解一个问题规模很大很难直接求解,但是规模较小的时候问题很容易求解并且这个问题并且问题满足分治算法的适用条件,那么就可以使用分治算法。

什么是分支算法

那么采用分治算法解决的问题需要 满足那些条件(特征) 呢?

1 . 原问题规模通常比较大,不易直接解决,但问题缩小到一定程度就能较容易的解决。

2 . 问题可以分解为若干规模较小、求解方式相同(似)的子问题。且子问题之间求解是独立的互不影响。

3 . 合并问题分解的子问题可以得到问题的解。

你可能会疑惑分治算法和递归有什么关系?其实分治重要的是一种思想,注重的是问题分、治、合并的过程。而递归是一种方式(工具),这种方式通过方法自己调用自己形成一个来回的过程,而分治可能就是利用了多次这样的来回过程。

分治算法经典问题

对于分治算法的经典问题,重要的是其思想,因为我们大部分借助递归去实现,所以在代码实现上大部分都是很简单,而本篇也重在讲述思想。

分治算法的经典问题,个人将它分成两大类:子问题完全独立和子问题不完全独立。

1 . 子问题完全独立就是原问题的答案可完全由子问题的结果推出。

2 . 子问题不完全独立,有些区间类的问题或者跨区间问题使用分治可能结果跨区间,在考虑问题的时候需要仔细借鉴下。

二分搜索

二分搜索是分治的一个实例,只不过二分搜索有着自己的特殊性

  • 序列有序

  • 结果为一个值

正常二分将一个完整的区间分成两个区间,两个区间本应单独找值然后确认结果,但是通过有序的区间可以直接确定结果在哪个区间,所以分的两个区间只需要计算其中一个区间,然后继续进行一直到结束。实现方式有递归和非递归,但是非递归用的更多一些:

public int searchInsert(int[] nums, int target) {   if(nums[0]>=target)return 0;//剪枝   if(nums[nums.length-1]==target)return nums.length-1;//剪枝   if(nums[nums.length-1]<target)return nums.length;   int left=0,right=nums.length-1;   while (left<right) {     int mid=(left+right)/2;     if(nums[mid]==target)       return mid;     else if (nums[mid]>target) {       right=mid;     }     else {       left=mid+1;     }   }   return left; }

快速排序

快排也是分治的一个实例,快排每一趟会选定一个数,将比这个数小的放左面,比这个数大的放右面,然后递归分治求解两个子区间,当然快排因为在分的时候就做了很多工作,当全部分到最底层的时候这个序列的值就是排序完的值。这是一种分而治之的体现。

什么是分支算法
public void quicksort(int [] a,int left,int right) {   int low=left;   int high=right;   //下面两句的顺序一定不能混,否则会产生数组越界!!!very important!!!   if(low>high)//作为判断是否截止条件     return;   int k=a[low];//额外空间k,取最左侧的一个作为衡量,最后要求左侧都比它小,右侧都比它大。   while(low<high)//这一轮要求把左侧小于a[low],右侧大于a[low]。   {     while(low<high&&a[high]>=k)//右侧找到第一个小于k的停止     {       high--;     }     //这样就找到第一个比它小的了     a[low]=a[high];//放到low位置     while(low<high&&a[low]<=k)//在low往右找到第一个大于k的,放到右侧a[high]位置     {       low++;     }     a[high]=a[low];      }   a[low]=k;//赋值然后左右递归分治求之   quicksort(a, left, low-1);   quicksort(a, low+1, right);   }

归并排序(逆序数)

快排在分的时候做了很多工作,而归并就是相反,归并在分的时候按照数量均匀分,而合并时候已经是两两有序的进行合并的,因为两个有序序列O(n)级别的复杂度即可得到需要的结果。而逆序数在归并排序基础上变形同样也是分治思想求解。

什么是分支算法 
private static void mergesort(int[] array, int left, int right) {   int mid=(left+right)/2;   if(left<right)   {     mergesort(array, left, mid);     mergesort(array, mid+1, right);     merge(array, left,mid, right);   } }  private static void merge(int[] array, int l, int mid, int r) {   int lindex=l;int rindex=mid+1;   int team[]=new int[r-l+1];   int teamindex=0;   while (lindex<=mid&&rindex<=r) {//先左右比较合并     if(array[lindex]<=array[rindex])     {       team[teamindex++]=array[lindex++];     }     else {           team[teamindex++]=array[rindex++];     }   }   while(lindex<=mid)//当一个越界后剩余按序列添加即可   {     team[teamindex++]=array[lindex++];    }   while(rindex<=r)   {     team[teamindex++]=array[rindex++];   }    for(int i=0;i<teamindex;i++)   {     array[l+i]=team[i];   } }

最大子序列和

最大子序列和的问题我们可以使用动态规划的解法,但是也可以使用分治算法来解决问题,但是最大子序列和在合并的时候并不是简单的合并,因为子序列和涉及到一个长度的问题,所以正确结果不一定全在最左侧或者最右侧,而可能出现结果的区域为:

  • 完全在中间的左侧

  • 完全在中间的右侧

  • 包含中间左右两个节点的一个序列

用一张图可以表示为:

什么是分支算法

所以在具体考虑的时候需要将无法递归得到结果的中间那个最大值串的结果也算出来参与左侧、右侧值得比较。

力扣53. 最大子序和在实现的代码为:

ublic int maxSubArray(int[] nums) {     int max=maxsub(nums,0,nums.length-1);     return max; } int maxsub(int nums[],int left,int right) {     if(left==right)         return  nums[left];     int mid=(left+right)/2;     int leftmax=maxsub(nums,left,mid);//左侧最大     int rightmax=maxsub(nums,mid+1,right);//右侧最大      int midleft=nums[mid];//中间往左     int midright=nums[mid+1];//中间往右     int team=0;     for(int i=mid;i>=left;i--)     {         team+=nums[i];         if(team>midleft)             midleft=team;     }     team=0;     for(int i=mid+1;i<=right;i++)     {         team+=nums[i];         if(team>midright)             midright=team;     }     int max=midleft+midright;//中间的最大值     if(max<leftmax)         max=leftmax;     if(max<rightmax)         max=rightmax;     return  max; }

最近点对

最近点对是一个分治非常成功的运用之一。在二维坐标轴上有若干个点坐标,让你求出最近的两个点的距离,如果让你直接求那么枚举暴力是个非常非常大的计算量,我们通常采用分治的方法来优化这种问题。

什么是分支算法

如果直接分成两部分分治计算你肯定会发现如果最短的如果一个在左一个在右会出现问题。我们可以优化一下。

在具体的优化方案上,按照x或者y的维度进行考虑,将数据分成两个区域,先分别计算(按照同方法)左右区域内最短的点对。然后根据这个两个中较短的距离向左和向右覆盖,计算被覆盖的左右点之间的距离,找到最小那个距离与当前最短距离比较即可。

什么是分支算法

这样你就可以发现就这个一次的操作(不考虑的情况),左侧红点就避免和右侧大部分红点进行距离计算(O(n2)的时间复杂度)。事实上,在进行左右区间内部计算的时候,它其实也这样递归的进行很多次分治计算。如图所示:

什么是分支算法 

这样下去就可以节省很多次的计算量。

但是这种分治会存在一种问题就是二维坐标可能点都聚集某个方法某条轴那么可能效果并不明显(点都在x=2附近对x分割作用就不大),需要注意一下。

杭电1007推荐给大家,ac的代码为:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Main {     static int n;     public static void main(String[] args) throws IOException {         StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));         PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));         //List<node>list=new ArrayList();          while(in.nextToken()!=StreamTokenizer.TT_EOF)          {              n=(int)in.nval;if(n==0) {break;}             node no[]=new node[n];                           for(int i=0;i<n;i++)              {                  in.nextToken();double x=in.nval;                  in.nextToken();double y=in.nval;                 // list.add(new node(x,y));                  no[i]=new node(x,y);              }              Arrays.sort(no, com);             double min= search(no,0,n-1);             out.println(String.fORMat("%.2f", Math.sqrt(min)/2));out.flush();          }              }     private static double search(node[] no, int left,int right) {         int mid=(right+left)/2;         double minleng=0;         if(left==right) {return Double.MAX_VALUE;}         else if(left+1==right) {minleng= (no[left].x-no[right].x)*(no[left].x-no[right].x)+(no[left].y-no[right].y)*(no[left].y-no[right].y);}         else minleng= min(search(no,left,mid),search(no,mid,right));         int ll=mid;int rr=mid+1;         while(no[mid].y-no[ll].y<=Math.sqrt(minleng)/2&&ll-1>=left) {ll--;}         while(no[rr].y-no[mid].y<=Math.sqrt(minleng)/2&&rr+1<=right) {rr++;}         for(int i=ll;i<rr;i++)         {             for(int j=i+1;j<rr+1;j++)             {                 double team=0;                 if(Math.abs((no[i].x-no[j].x)*(no[i].x-no[j].x))>minleng) {continue;}                 else                 {                      team=(no[i].x-no[j].x)*(no[i].x-no[j].x)+(no[i].y-no[j].y)*(no[i].y-no[j].y);                     if(team<minleng)minleng=team;                 }             }         }         return minleng;          }     private static double min(double a, double b) {         // TODO 自动生成的方法存根         return a<b?a:b;     }     static Comparator<node>com=new Comparator<node>() {          @Override         public int compare(node a1, node a2) {             // TODO 自动生成的方法存根             return a1.y-a2.y>0?1:-1;         }};     static class node     {         double x;         double y;         public node(double x,double y)         {             this.x=x;             this.y=y;         }     } }

到此,关于“什么是分支算法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: 什么是分支算法

本文链接: https://www.lsjlt.com/news/84253.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 什么是分支算法
    这篇文章主要介绍“什么是分支算法”,在日常操作中,相信很多人在什么是分支算法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是分支算法”的疑惑有所帮助!接下来,请跟着小编一...
    99+
    2022-10-19
  • Git分支操作方法是什么
    这篇文章主要介绍“Git分支操作方法是什么”,在日常操作中,相信很多人在Git分支操作方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Git分支操作方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-27
  • git更改分支名的方法是什么
    这篇文章主要介绍“git更改分支名的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“git更改分支名的方法是什么”文章能帮助大家解决问题。查看已有分支在命令行中进入Git所在项目的目录,通过...
    99+
    2023-07-05
  • Python分支结构的使用方法是什么
    这篇文章主要讲解了“Python分支结构的使用方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python分支结构的使用方法是什么”吧!if语句的使用在Python中,要构造分支结构...
    99+
    2023-06-01
  • git分支是干什么用
    Git是一种分布式版本控制系统,通过管理项目代码的变化来跟踪和协调开发人员之间的工作。分支是Git的一个重要概念,用于管理代码的不同版本。本文将探讨Git分支的基本概念及其用途。Git分支是什么?在Git 中,分支就像是一个指向某一特定提交...
    99+
    2023-10-22
  • matlab积分计算的方法是什么
    在MATLAB中,可以使用多种方法计算积分,其中包括:1. 符号积分:MATLAB可以进行符号计算,使用符号计算工具箱可以进行符号积...
    99+
    2023-09-14
    matlab
  • Java分位点计算方法是什么
    本篇内容介绍了“Java分位点计算方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java 分位点(分位值)计算有一个需求给出一段时...
    99+
    2023-06-22
  • Java分支结构程序设计方法是什么
    这篇“Java分支结构程序设计方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java分支结构程序设计方法是什么”文...
    99+
    2023-06-29
  • php 多分支是什么意思
    本文操作环境:Windows7系统、PHP7.1、Dell G3。php 多分支是什么意思?PHP分支控制语句,PHP流程控制结构之分支结构流程控制对于任何一门编程语言来说都是具有通用与普遍性的,是程序的重要组成部分。可以这么说,在任何一门...
    99+
    2021-09-28
    php 多分支
  • JVM的四种GC算法分别是什么
    本篇文章给大家分享的是有关JVM的四种GC算法分别是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内...
    99+
    2023-06-02
  • python的单分支结构是什么
    本篇内容主要讲解“python的单分支结构是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python的单分支结构是什么”吧!说明根据判断条件结果而选择不同向前路径的运行方式。条件表达式可以...
    99+
    2023-06-20
  • 什么是python的多分支结构
    这篇文章主要介绍“什么是python的多分支结构”,在日常操作中,相信很多人在什么是python的多分支结构问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是python的多分支结构”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • python的二分支结构是什么
    本篇内容介绍了“python的二分支结构是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明根据判断条件结果而选择不同向前路径的运行方式...
    99+
    2023-06-20
  • Python Day04的分支结构是什么
    Python Day04的分支结构是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Day03 - 分支结构分支结构的应用场景迄今为止,我们写的Python代码都是一条一...
    99+
    2023-06-02
  • Git分支合并命令是什么
    本篇内容介绍了“Git分支合并命令是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Git 是一个开源的分布式版本控制系统,用于敏捷高效地...
    99+
    2023-06-04
  • php的多分支指的是什么
    这篇文章主要介绍“php的多分支指的是什么”,在日常操作中,相信很多人在php的多分支指的是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php的多分支指的是什么”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-21
  • 什么是java算法
    什么是java算法 算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,java算法就是采用Java语言来实现解决某一问题的清晰指令。算法的特征:输入性:有零个或多个外部量作为算法的输入输出性:算法产生至少一个量作为输出确定性:...
    99+
    2016-09-25
    java入门 java 算法
  • RSA算法是什么
    今天就跟大家聊聊有关RSA算法是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。2. 加密算法的一点历史我们知道常见的加密算法有:对称加密和非对称...
    99+
    2022-10-19
  • C++算法学习之分支限界法的应用
    目录分支限界1实验题目: 填格子4实验题目: 不如走楼梯分支限界 堂练实验题目: 再填格子实验题目: 最短路径分支限界1 实验题目: 填格子4 题目描述: 有一个由数字 0、1 组成...
    99+
    2022-11-13
  • 算法时常用的分析思路是什么
    这篇“算法时常用的分析思路是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“算法时常用的分析思路是什么”文章吧。分析框架以...
    99+
    2023-06-27
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作