回溯算法(BackTracking)

news2024/11/17 13:57:00

在许多情况下,回溯算法相当于穷举搜索的巧妙实现。回溯算法的一个具体例子是在新房子里摆放家具,开始什么也不摆放,然后每件家具被摆放在房间的某个位置,如果所有的家具都被摆放得令户主满意,那么算法终止;如果摆到某一步,该步之后的所有摆放方法都不能满意,那么就需要撤销这一步,并尝试其他的摆放方法,如果发现撤销了所有可能的第一步,就不存在令人满意的摆放方法。虽然回溯算法基本上是蛮力的,但它并不直接尝试所有的可能。例如,将沙发摆放进厨房的可能是不考虑的。在一步之内删除一大组可能性的做法叫作裁剪。

设给定N个点p_{1}, p_{2}, ..., p_{N},它们位于x轴上。x_{i}p_{i}点的x坐标。进一步假设x_{1}=0以及这些点从左到右给出。这N个点确定在每一对点间的\frac{N(N-1)}{2}个(不必是唯一的)形如\left | x_{i}-x_{j} \right | (i\neq j)的距离。显然,如果给定点集,那么容易以O(N^{2})时间构造距离的集合。这个集合将不是排序的,但是,如果我们愿意花O(N^{2}logN)时间界整理,那么这些距离也可以被排序。收费公路重建问题是从这些距离中重新构造一个点集。当然,若给定该问题的一个解,则可以通过对所有的点加上一个偏移量而构建无穷多其他的解。这就是为什么我们一定要将第一个点置于0处以及构建解的点集以非降顺序输出的原因。

D是距离的集合,并设\left | D\right |=M=\frac{N(N-1)}{2},设

D=\left \{ 1,2,2,2,3,3,3,4,5,5,5,6,7,8,10 \right \}

 首先,置x_{1}=0,找到D中的最大元素(最大的距离对应的点的位置只有两处,且点的位置只需要参考两个端点),显然x_{6}=10,并从D中删除距离10,

接下来找到D中最大的元素8,由于x_{2}x_{5}是对称的,所以x_{2}=2x_{5}=8都是合理的,置x_{5}=8,从D中删除x_{5}-x_{1}=8, x_{6}-x_{5}=2,得到

接下来选择距离7,此时有两个选择x_{2}=3, x_{4}=7,发现这两个点与其余三个点的距离都属于D,那么此时就任选一个点使算法先进行下去,如果后面会出现矛盾,则退回来尝试另一个选择。选择x_{4}=7并删除对应距离,得到

接下来选x_{2}=4x_{3}=6,但由于x_{5}-x_{4}=1不属于Dx_{2}-x_{1}=4x_{5}-x_{2}=4,而D中只有一个4,所以这两个选择都是不符合要求的,那么就需要退回上一步尝试x_{2}=3

接下来选择x_{3}=4x_{4}=6,易得只有x_{4}=6符合条件,所以

 最后一步只能有x_{3}=5,且发现能删除D中的所有距离并不会产生D中没有的距离,所以此算法成功地重建了公路。

如图是一棵决策树,代表为得到解而采取的行动。这里没有对分支做标记,而是将标记放在了节点中。带有一个星号的节点表示这些所选的点与给定的距离不一致;带有两个星号的节点只有将不可能的节点作为儿子节点,因此表示一条不正确的路径。

收费公路重建代码: 

#include<stdio.h>
#include<stdbool.h>
#include<math.h>

int deletemax(int dis[], int discopy[]) {//删除距离集合中的最大值
	int index, max = -1;
	for (int i = 0; i < 15; i++) {
		if (dis[i] > max) {
			max = dis[i];
			index = i;
		}
	}
	dis[index] = -1;
	discopy[index] = -1;
	return max;
}

int findmax(int dis[]) {//找到距离集合中的最大值
	int max = -1;
	for (int i = 0; i < 15; i++) {
		if (dis[i] > max)
			max = dis[i];
	}
	return max;
}

void copy(int dis1[], int dis2[]) {//将一个集合复制到另一个集合
	for (int i = 0; i < 15; i++) {
		dis1[i] = dis2[i];
	}
}

bool find(int x[], int dis[], int discopy[], int npot, int N) {//判断新增加的点与其余点的距离都在集合中,npot表示新增点的坐标
	for (int i = 1; i <= N; i++) {
		int d = 0;
		if ( x[i] != -1 && (d = abs(npot - x[i]))) {//如果当前位置有点并且不是新增点本身
			int j = 0;
			for (; j < 15; j++) {
				if (dis[j] == d) {//如果新增点与该点的距离存在于集合中,则在集合中删除该距离
					dis[j] = -1;
					break;
				}
			}
			if (j == 15) {//说明有距离不存在于集合中
				copy(dis, discopy);//通过副本将刚才删除的距离添加回集合
				return false;
			}
		}
	}
	copy(discopy, dis);//如果所有距离都存在,则更新副本
	return true;
}

bool isempty(int dis[]) {//判断集合是否为空
	for (int i = 0; i < 15; i++) {
		if (dis[i] != -1)
			return false;
	}
	return true;
}

void Insert(int x[], int dis[], int pos, int N) {//将删除的距离重新插入到集合中
	for (int i = 1; i <= N; i++) {//pos表示需要重新放置的点的现坐标
		if (x[i] != -1) {//当该位置有点时
			int d = abs(pos - x[i]);//将它们的距离算出来,重新放回集合
			for (int i = 0; i < 15; i++) {
				if (dis[i] == -1) {
					dis[i] = d;
					break;
				}
			}
		}
	}
}

bool place(int x[], int dis[], int discopy[], int N, int left, int right) {
	bool found = false;//将found设置为false
	if (isempty(dis))//如果集合为空,则说明算法已经成功
		return true;
	int max = findmax(dis);//找到集合中的最大距离,这时新增点只有两种摆放情况
	if (find(x, dis, discopy, max, N)) {//如果将其摆放在靠右的位置且其与其他点的距离都在集合中
		x[right] = max;//则先尝试靠右的可能
		found = place(x, dis, discopy, N, left, right - 1);//递归放置新点
		if (!found) {//如果后续摆放不能成功,则需要尝试另一种可能
			x[right] = -1;
			Insert(x, dis, max, N);//将这一步删除的距离重新加入集合中
			copy(discopy, dis);
		}
	}
	if(find(x, dis, discopy, x[N] - max, N)){//如果靠左的位置符合要求,则进行与上面相同的步骤
		x[left] = x[N] - max;
		found = place(x, dis, discopy, N, left + 1, right);
		if (!found) {
			x[left] = -1;
			Insert(x, dis, x[N] - max, N);
			copy(discopy, dis);
		}
	}
	return found;//返回结果
}

bool TurnPike(int x[], int dis[], int discopy[], int N) {//初始化公路
	x[1] = 0;
	x[N] = deletemax(dis, discopy);//第一个点和最后一个点显然是确定的
	x[N - 1] = findmax(dis);//而根据对称性,第三个点可以靠近左端点也可以靠近右端点,这个点也是确定的
	if (find(x, dis, discopy, x[N - 1], N)) {//如果新增的点与其余已经存在的点的距离都存在于集合中,则说明这个点的位置目前是合理的
		return place(x, dis, discopy, N, 2, N - 2);//通过递归放置其余点
	}
	else {//如果第三个点都无法摆放,说明这个集合的要求无法实现,返回false
		return false;
	}
}

int main() {
	int dis[15] = { 1,2,2,2,3,3,3,4,5,5,5,6,7,8,10 };//一组距离集合,重建的公路要满足这些条件
	int discopy[15] = { 1,2,2,2,3,3,3,4,5,5,5,6,7,8,10 };//距离集合的副本
	int x[7] = { -1,-1,-1,-1,-1,-1,-1 };//公路上的点
	if (TurnPike(x, dis, discopy, 6))
		printf("收费公路重建完成!\n");
	else
		printf("收费公路重建失败!\n");
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC——响应处理(1)【包含源码分析】

Controller public class JsonReturnController {ResponseBodyGetMapping("/getPet")public Pet getPet(){Pet petnew Pet();pet.setAge(5);pet.setName("lily");return pet;} }项目启动后 浏览器输入 http://localhost:8080/getPet 。 debug DispatcherS…

十、vben框架如何使用table来写报表

在项目开发的过程中&#xff0c;有很多特殊的table样式&#xff0c;有的时候后端会用帆软来写报表&#xff0c;但是有的特殊的报表后端就不能支持实现了&#xff0c;那么前端是如何实现的呢&#xff0c;今天我们就来讲讲。 先上效果图&#xff1a; 本次使用的tsx组件来写的报表…

csapp第一章 --- 计算机系统漫游

重要内容大纲 1.1 C程序实现过程 一个由用户编写的“hello world”源代码到可以在屏幕上看见可执行文件经过一下过程&#xff1a; C语言翻译的阶段介绍 1.预处理cpp&#xff1a;头文件展开、宏定义替换 将 .c 文件&#xff08;源程序&#xff09;变成 .i 文件&#xff08;修改…

一文搞懂如何在 React 中使用 防抖(Debounce)和 节流(Throttle)

在前端的日常开发中&#xff0c;经常会使用到两个函数防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;&#xff0c;防抖函数可以有效控制在一段时间内只执行最后一次请求&#xff0c;例如搜索框输入时&#xff0c;只在输入完成后才进行请求接口。…

linux环境下打包c++的Qt应用程序装载vtk和itk

文章目录一、QT安装安装前准备1.1 方法一 源码编译安装(实践缺少xcb依赖)&#xff1a;1.2 方法二 run文件安装&#xff1a;二、迁移windows下qt应用到linux三、VTK安装3.1 安装ccmake 和 VTK 的依赖项3.2 linux下VTK库下载安装四、QT应用基础上引入VTK依赖五、ITK安装六、QT应用…

sikuli+eclipse对于安卓app自动化测试的应用

Sikuli是什么&#xff1f; 下面是来自于官网的介绍&#xff1a;Sikuli is a visual technology to automate and test graphical user interfaces (GUI) using images (screenshots). Sikuli includes Sikuli Script, a visual scripting API for Jython, and Sikuli IDE, an …

入门Java第十五天 线程

一、多线程 1.1进程和线程 进程&#xff1a;进程就是操作系统中运行的每一个应用程序。例如&#xff1a;微信&#xff0c;QQ 线程&#xff1a;线程是进程中的每一个任务。 多线程&#xff1a;在一个进程中&#xff0c;可以同时执行多个线程。同时完成多个任务。 并发&#x…

投票的链接怎么做出来的网上那些投票链接怎么做的网上投票器

用户在使用微信投票的时候&#xff0c;需要功能齐全&#xff0c;又快捷方便的投票小程序。而“活动星投票”这款软件使用非常的方便&#xff0c;用户可以随时使用手机微信小程序获得线上投票服务&#xff0c;很多用户都很喜欢“活动星投票”这款软件。“活动星投票”小程序在使…

【踩坑记录】使用OpenCV报错“ undefined symbol: TIFFReadRGBATileExt, version LIBTIFF_4.0”

问题描述 例如&#xff1a;使用OpenCV报错&#xff0c;找不到相关动态库&#xff1a; ImportError: /lib/libgdal.so.26: undefined symbol: TIFFReadRGBATileExt, version LIBTIFF_4.0解决方案&#xff1a; 运行前&#xff0c;先执行或者在./bashrc &#xff08;根目录下ctr…

【图像分类】卷积神经网络之ZFNet网络模型结构详解

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 1. 前言 由于AlexNet的提出,大型卷积网络开始变得流行起来,但是人们对于网络究竟为什么能表现的这么好,以及怎…

Python编写GUI界面案例:实现免费下载器

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 本次网站&#xff1a; 本文所有模块\环境\源码\教程皆可点击文章下方名片获取此处跳转 开发环境: python 3.8 运行代码 pycharm 2022.3 辅助敲代码 模块使用&#xff1a; import parsel >>> pip install parsel…

从0开始学python -41

Python3 命名空间和作用域 命名空间 先看看官方文档的一段话&#xff1a; A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。 命名空间(Namespace)是从名称到对象的映射&#xff0c;大部分的命名空间都是…

蓝牙耳机适合跑步戴吗,五款适合跑步蓝牙耳机推荐

音乐是坚持运动下去的不懈动力&#xff0c;在运动当中佩戴蓝牙耳机&#xff0c;能够让我们远离枯燥无味&#xff0c;运动更有律动感&#xff0c;运动更为畅快。运动当中佩戴的蓝牙耳机&#xff0c;佩戴舒适度以及牢固度是我们十分需要注意的&#xff0c;下面这几款比较热门的运…

IP-GUARD控制台账户输入多次错误密码锁定后该如何解锁?

其他管理员账户给锁定了,暂时只能等其锁定时间到了才可以再次输入,默认是设置是锁定30min; 1、如果急需此账户查看,可以使用admin系统管理员账户登录控制台,在工具-账户中清除这个账户的密码,重新登录设置密码。

idea远程调试线上jar包

有时候本地代码没问题但在线上运行会报错&#xff0c;这时候可以使用idea的remote功能调试线上jar包 步骤1 步骤2&#xff1a;新建remote 步骤3&#xff1a;配置服务器ip和端口 并复制生成的JVM参数供之后使用 步骤4&#xff1a;打jar包&#xff0c;并将生成的jar包放到服务…

想招到实干派程序员?你需要这种面试法

技术招聘中最痛的点其实是不精准。技术面试官或CTO们常常会向我们吐槽&#xff1a; “我经常在想&#xff0c;能不能把我们项目中的代码打印出来&#xff0c;作为候选人的面试题的一部分&#xff1f;” “能不能把一个Bug带上环境&#xff0c;让候选人来试试怎么解决&#xf…

电信网上用户资管理系统的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;在对目前市面上已经拥有的营业厅功能分析和整理后&#xff0c;为了保证营业厅中多种功能的分层次处理设计了一个的电信网上用户自管理系统&#xff0c;以web页面方式实现了与用户的交互&#xff0c;同时保证了移动电话计费管理系统…

数据结构期末复习总结(后章)

作者的话 作为一名计算机类的学生&#xff0c;我深知数据结构的重要性。在期末复习前&#xff0c;我希望通过这篇博客给大家一些复习建议。希望能帮助大家夯实数据结构的基础知识&#xff0c;并能够更好地掌握数据结构和算法的应用。 一、树与二叉树 1.基本概念 结点的度&am…

Google的中国用户注意!黑客正利用搜索结果投放恶意软件

2月16日研究人员发现&#xff0c;Google搜索结果中含有冒充知名软件的恶意软件下载链接。 研究人员通过测试后表示&#xff0c;攻击者为了增加浏览量&#xff0c;甚至通过在Google搜索结果中购买误导性广告&#xff0c;诱骗受害者下载安装恶意程序。 据悉&#xff0c;这些被冒…

【JavaSE】集合(Collection类)

文章目录1.集合框架1.1 collection1.2 map2. collection2.1.集合迭代2.2.contains和remove2.3集合中元素的删除3.List4.ArrayList5.LinkList6.Vector7.泛型7.1泛型初步7.2自动类型推断机制7.3 自定义泛型8.增强for循环9.Set9.1HashSet9.2 TreeSet1.集合框架 1.1 collection 1.…