回溯算法:从电影蝴蝶效应中学习回溯算法的核心思想
回溯算法:从电影<蝴蝶效应>中学习回溯算法的核心思想
数独、八皇后、0-1背包、图的着色、旅行商问题、全排列问题都能用到
理解“回溯算法”
回溯的思想,类似枚举搜索,枚举所有的解,找到满足期望的解,为了有规律枚举所有可能的解,把问题求解的过程分为多个阶段,每个阶段,都会面对一个岔路口,先随意选一条路,当发现这条路不通的时候(不满足期望)就回退到上一个岔路口,另选一种。
八皇后问题:
有一个8x8棋盘,往里面放8个棋子(皇后),每个棋子所在行、列、对角线都不能有另外一个棋子
把这个问题划分为8个阶段,依次将8个棋子放到第一行、第二行、……、第八行,在放置的过程中,不停的检查是否满足规则,如果满足就跳到下一行继续放置棋子,不满足就换一种放法尝试
int[] result = new int[8];//全局或成员变量,下标表示行,值表示queen存储在哪一列
public void cal8queens(int row){ //调用方式:cal8queen(0);if(row == 8){ //8个棋子都放置好了打印结果printQueens(result);return; //8个棋子都放好了,已经没法再往下递归了,所以就return}for(int column = 0 ; column < 8 ; ++column){ //每一行都有8种放法if(isOk(row,column)){ //有些放法不满足要求result[row] = column; //第row行的棋子放到了column列cal8queens(row+1); //考察下一行}}
}private boolean isOk(int row , int column){ //判断row行column列放置是否合适int leftup = column - 1 , rightup = column + 1;for(int i = row - 1; i >= 0 ; --i){ //逐行往上考察每一行if(result[i] == column) return false; //第i行的column列有棋子吗?if(leftup >= 0){ //考察左上对角线:第i行leftup列有棋子吗?if(result[i] == leftup) return false;}if(rightup < 8 ){ //考察右上对角线:第i行rightup列有棋子吗?if(result[i] == rightup) return false;}--leftup ; ++rightup;}return true;
}private void printQueens(int[] result){ //打印出一个二维矩阵for(int row = 0 ; row < 8 ; ++row){for(int column = 0 ;; column < 8 ; ++column){if(result[row] == column) System.out.print("Q ");else System.out.print("* ");}System.out.println():}System.out.println();
}
两个回溯算法的经典应用
1. 0-1背包
有一个背包,背包总的承载重量是Wkg,我们有n个物品,每个物品的重量不等,且不可分割,期望选择几件物品装载到背包中,在不超过背包所能装载重量的前提下,如何让背包物品的总重量最大?
对于n个物品来说,总的装法有2^n
种,去掉总重量最接近Wkg,从剩下的装法中选择总重量最接近Wkg的,如何才能不重复穷举这2^n
种装法呢?
把物品依次排列,整个问题就分解成了n个阶段,每个阶段对应一个物品怎么选择,先对第一个物品进行处理,选择装进去还是不装,再递归处理剩下的物品
如果发现已经选择的物品重量超过了Wkg,停止继续探测剩下的物品
public int maxW = Integer.MIN_VALUE;//存储背包中物品总重量的最大值
//cw表示当前已经装进去的物品的重量和; i表示考察到哪个物品了;
//w背包重量 ; items表示每个物品的重量;n表示物品个数
//假设背包可承受重量100,物品个数10,物品重量存储在数组a中,那可以这样调用函数:
//f(0,0,a,10,100)
public void f(int i , int cw, int[] items , int n , int w){if(cw == w || i == n ){ // cw == w表示装满了;i== n表示已经考察完所有的物品if(cw > maxW) maxW = cw;return;}f(i+1 , cw , items , n ,w);if(cw + items[i] <= w){ //已经超过可以背包承受的重量的时候,就不要再装了f(i+1 , cw + items[i] , items ,n , w);}
}
2. 正则表达式
正则表达式中,最重要的是通配符,假设正则表达式中只包含 *
和?
两个通配符,其中,*
匹配任意多个(大于等于0个)任意字符,?
匹配零个或者一个任意字符,如何通过回溯算法,判断一个给定的文本,能否跟给定的正则表达式匹配?
依次考察正则表达式中的每个字符,当时非通配符时,直接跟文本的字符进行匹配,如果相同,继续往下处理,如果不同,则回溯
如果遇到特殊字符的时候,比如*
有多种匹配方案,可以匹配任意个文本串中的字符,先随意选择一种匹配方案,继续考察剩下的字符
public class Pattern{private boolean matched = false;private char[] pattern; //正则表达式private int plen; //正则表达式长度public Pattern(char[] pattern , int plen){this.pattern = pattern;this.plen = plen;}public boolean match(char[] text , int tlen){ //文本串及长度matched = false;rmatch(0,0,text,tlen);return matched;}private void rmatch(int ti,int pj, char[] text, int tlen){if(matched) return;//如何已经匹配了,就不需要继续递归了if(pj == plen){ //正则表达式到结尾了if(ti ==tlen) matched = true;// 文本串也到结尾了return;}if(pattern[pj] == "*"){ //*匹配任意个字符for(int k = 0 ; k <= tlen-ti;++k){rmatch(ti+k,pj+1,text,tlen);}}else if (pattern[pj] == "?"){ //?匹配0个或者1个字符rmatch(ti,pj+1,text,tlen);rmatch(ti+1,pj+1,text,tlen);}else if(ti < tlen && pattern[pj] == text[ti]){ //纯字符匹配才行rmatch(ti+1,pj+1,text,tlen);}}
}
回溯算法:从电影蝴蝶效应中学习回溯算法的核心思想相关推荐
- 计算机图形学 学习笔记(一):概述,直线扫描转换算法:DDA,中点画线算法,Bresenham算法
前言 本笔记基于 http://www.icourse163.org/learn/CAU-45006?tid=1001746004#/learn/announce 感谢中国农大 赵明老师的分享~ 现在 ...
- 在线电影推荐网 Python+Django+Mysql 协同过滤推荐算法在电影网站中的运用 基于用户、物品的协同过滤推荐算法 开发在线电影推荐系统 电影网站推荐系统 人工智能、大数据、机器学习开发
在线电影推荐网 Python+Django+Mysql 协同过滤推荐算法在电影网站中的运用 基于用户.物品的协同过滤推荐算法 开发在线电影推荐系统 电影网站推荐系统 人工智能.大数据.机器学习开发 M ...
- python实现KNN算法在电影分类中的应用
使用python实现KNN算法在电影分类中的应用 代码如下: import numpy as np import operator""" 使用KNN算法对电影进行分类 K ...
- 主要推荐系统算法总结及Youtube深度学习推荐算法实例概括
主要推荐系统算法总结及Youtube深度学习推荐算法实例概括 By ZhuZhiboSmith2017年7月09日 17:00 现如今,许多公司使用大数据来做超级相关推荐,并以此来增加收益.在海量推荐 ...
- 从电影《蝴蝶效应》中学习回溯算法的核心思想
点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 关注我们丨文末赠书 深度优先搜索算法利用的是回溯算法思想.这个算法思 ...
- 回溯算法:从电影《蝴蝶效应》中学习回溯算法的核心思想
------ 本文是学习算法的笔记,<数据结构与算法之美>,极客时间的课程 ------ 我们在深度和广度优先算法提到,深度优先搜索算法利用的是回溯算法思想.这个算法思想非常简单,但是应用 ...
- 极客时间——数据结构与算法(39) 回溯算法:从电影《蝴蝶效应》中学习回溯算法的核心思想
转载地址:https://time.geekbang.org/column/article/74287 我们在第 31 节提到,深度优先搜索算法利用的是回溯算法思想.这个算法思想非常简单,但是应用却非 ...
- 从一个实例中学习DTW算法
基于动态时间规整算法(DTW)的相似度计算 Killer 发表于(2015-10-063) 本文标签:大数据 机器学习 算法 浏览量:193次 喜欢收藏 在孤立词语音识别中,最为简单有效的方法是 ...
- HMM学习笔记_1(从一个实例中学习DTW算法)
DTW为(Dynamic Time Warping,动态时间归准)的简称.应用很广,主要是在模板匹配中,比如说用在孤立词语音识别,计算机视觉中的行为识别,信息检索等中.可能大家学过这些类似的课程都看到 ...
最新文章
- Java多线程并发常用类实例之:exchanger
- Java里的接口的interface 简单介绍.
- NYOJ 士兵杀敌(四) 树状数组
- p4: php5ts.dll p5: 5.6.14.0,服务器httpd.exe 应用程序错误
- [前端漫谈_4] 从 薛定谔的猫 聊到 Event loop
- 在logback、log4j等日志输出工具中输出java异常调用堆栈
- arcgis运行慢_ArcGIS Pro运行较慢的诊断方法
- [改善Java代码]使用CyclicBarrier让多线程齐步走
- 关于Terra和Aqua的轨道问题整理
- [转] iOS 开发者应该知道的 ARM 结构(转自apple4us)
- java id pid 递归,父子结构数据(id,pid)递归查询所有子id合集和父id合集
- 创建列表、删除列表、查看列表长度、列表增加一个元素的几种方法
- Ardupilot固定翼无人机L1制导律原理及代码解读
- 学习笔记-Depth Map Prediction from a Single Image using a Multi-Scale Deep Network
- 求一个数的最小素因子外加快速分解质因子
- acs2go android,Aquarius2Go Astrology
- 这是个什么软件Android,想提高语文水平,不妨试试这几个APP(Android)
- 重叠社区检测基础算法
- 汇编 跳转指令: JMP、JCXZ、JECXZ、JA、JE、JNA、JNE、JZ、JB、JS、JC、JNC、JG、JNBE、JO、JP、JL、JPO、JGE、JLE 汇编语言
- Java+集合系列3、骨骼惊奇之LinkedList