算法分析与复杂性理论 实验报告 凸包问题
算法设计与分析实验报告——基于回溯法的0-1背包等问题
实验报告. 基于回溯法的0-1背包等问题实验内容本实验要求基于算法设计与分析的一般过程(即待求解问题的描述、算法设计、算法描述、算法正确性证明、算法分析、算法实现与测试),通过回溯法的在实际问题求解实践中,加深理解其基本原理和思想以及求解步骤。
求解的问题为0-1背包。
作为挑战:可以考虑回溯法在如最大团、旅行商、图的m着色等问题中的应用。
实验目的◆理解回溯法的核心思想以及求解过程(确定解的形式及解空间组织,分析出搜索过程中的剪枝函数即约束函数与限界函数);◆掌握对几种解空间树(子集树、排列数、满m叉树)的回溯方法;◆从算法分析与设计的角度,对0-1背包等问题的基于回溯法求解有进一步的理解。
环境要求对于环境没有特别要求。
对于算法实现,可以自由选择C, C++或Java,甚至于其他程序设计语言如Python等。
实验步骤步骤1:理解问题,给出问题的描述。
步骤2:算法设计,包括策略与数据结构的选择。
步骤3:描述算法。
希望采用源代码以外的形式,如伪代码或流程图等;步骤4:算法的正确性证明。
需要这个环节,在理解的基础上对算法的正确性给予证明;步骤5:算法复杂性分析,包括时间复杂性和空间复杂性;步骤6:算法实现与测试。
附上代码或以附件的形式提交,同时贴上算法运行结果截图;步骤7:技术上、分析过程中等各种心得体会与备忘,需要言之有物。
说明:步骤1-6在“实验结果”一节中描述,步骤7在“实验总结”一节中描述。
实验结果步骤1:问题描述。
给定 n个物品,其中第 i 个物品的重量为w i ,价值为 v i 。
有一容积为 W 的背包,要求选择一些物品放入背包,使得物品总体积不超过W的前提下,物品的价值总和最大。
0-1背包问题的限制是,每种物品只有一个,它的状态只有放和不放两种。
0-1背包问题是特殊的整数规划问题,其可用数学语言表述为:对于给定 n >0,W >0,v,w (v i ,w i >0,1≤i ≤n),找出一个 n 元0-1向量x =( x 1, x 2,⋯, x n ) 其中x i ∈{0,1},1≤i ≤n ,使得∑v i n i=1x i 最大,并且∑w i n i=1x i ≤W ,即:max x (∑v i ni=1x i ) s.t.∑w i ni=1x i ≤W, x i ∈{0,1},1≤i ≤n步骤2:算法设计,即算法策略与数据结构的选择。
算法分析与设计实验报告之01背包问题
算法分析与设计实验报告[0/1背包问题]0/1背包问题的不同算法解决方案组员02黄希龙 09455321张育强05周麒目录一.问题描述 (1)二.算法分析 (2)1.穷举法: (2)2.递归法: (4)3.贪心法: (5)4.动态规划法分析: (6)5.回溯法分析: (7)6.分支限界法: (9)三.时空效率分析 (10)1.穷举法: (10)2.递归法: (11)3.动态规划法: (11)4.回溯法: (11)5分支限界法: (11)四.运行结果 (12)1.穷举法输出结果: (12)2.递归法输出结果: (13)3.动态规划法输出结果: (14)4.回溯法输出结果: (15)5.分支限界法输出结果: (16)五.分析输出结果 (17)六.总结与反思 (18)一.问题描述0/1背包问题:现有n 种物品,对1<=i<=n ,已知第i 种物品的重量为正整数W i ,价值为正整数V i ,背包能承受的最大载重量为正整数W ,现要求找出这n 种物品的一个子集,使得子集中物品的总重量不超过W 且总价值尽量大。
(注意:这里对每种物品或者全取或者一点都不取,不允许只取一部分)二.算法分析根据问题描述,可以将其转化为如下的约束条件和目标函数:)2(max )1()1}(1,0{11∑∑==⎪⎩⎪⎨⎧≤≤∈≤ni i i ini i i x v n i x Wx w 于是,问题就归结为寻找一个满足约束条件(1),并使目标函数式(2)达到最大的解向量),......,,,(321n x x x x X =。
首先说明一下0-1背包问题拥有最优解。
假设),......,,,(321n x x x x 是所给的问题的一个最优解,则),......,,(32n x x x 是下面问题的一个最优解:∑∑==⎪⎩⎪⎨⎧≤≤∈-≤ni i i ini i i x v n i x x w W x w 2211max )2}(1,0{。
算法分析与复杂性理论 实验报告 背包问题
深圳大学实验报告课程名称:算法分析与复杂性理论实验名称:实验四动态规划学院:计算机与软件学院专业:软件工程报告人:文成学号:2150230509班级:学术型同组人:无指导教师:杨烜实验时间:2015/11/5——2015/11/18实验报告提交时间:2015/11/18教务处制一. 实验目的与实验内容实验目的:(1) 掌握动态规划算法设计思想。
(2) 掌握背包问题的动态规划解法。
实验内容:1.编写背包问题的动态规划求解代码。
2.背包容量为W ,物品个数为n ,随机产生n 个物品的体积(物品的体积不可大于W )与价值,求解该实例的最优解。
3. 分别针对以下情况求解 第一组:(n=10,W=10),(n=10,W=20),(n=10,W=30) 第二组:(n=20,W=10),(n=20,W=20),(n=20,W=30) 第三组:(n=30,W=10),(n=30,W=20),(n=30,W=30)4. 画出三组实验的时间效率的折线图,其中x 轴是W 的值,y 轴是所花费的时间,用不同的颜色表示不同n 所花费的时间。
二.实验步骤与结果背包问题的问题描述:给定n 种物品和一个背包。
物品i 的重量是i w ,其价值为i v ,背包容量为C 。
问应该如何选择装入背包的物品,使得装入背包中物品的总价值最大?背包问题的算法思想:考虑一个由前i 个物品(1<=i<=n )定义的实例,物品的重量分别为w1,…,w2、价值分别为v1,…,vi ,背包的承重量为j (1<=j<=w )。
设v[i,j]为该实例的最优解的物品总价值,也就是说,是能够放进承重量为j 的背包中的前i 个物品中最有价值子集的总价值。
可以把前i 个物品中能够放进承重量为j 的背包中的子集分成两个类别:包括第i 个物品的子集和不包括第i 个物品的子集。
1. 根据定义,在不包括第i 个物品的子集中,最优子集的价值是V[i-1,j]。
算法分析及复杂性理论实验报告基本排序
深圳大学实验报告课程名称:算法设计与分析实验名称:多种排序算法的算法实现及性能比较学院:计算机与软件学院专业:计算机科学与技术报告人:张健哲学号: 2013150372 班级: 3 同组人:无指导教师:李炎然实验时间: 2015/3/25——2015/4/8 实验报告提交时间: 2015/4/8教务处制一.实验目的1.掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理2.掌握不同排序算法时间效率的经验分析方法,验证理论分析与经验分析的一致性。
二.实验步骤与结果实验总体思路:利用switch结构来选择实验所要用的排序算法,每一种排序都用相同的计算运行时间的代码,不同的算法就在算法实现部分进行改动(如下代码1至5所示)。
不断的改变数据规模,每一个规模在实验时,用循环进行多次实验并作为样本记录消耗的时间。
最后输出在不同排序算法下,不同的数据规模的20次实验样本和平均用时(如下图1至5所示)。
各排序算法的实现及实验结果:(注1:以下代码全部为伪代码,具体代码实现请参照程序中的代码)(注2:图中显示的时间单位均为毫秒,图中“排序所花时间”一项为平均消耗时间,平均消耗时间结果以20组样本计算平均值后取整得到(并非四舍五入)。
)1、选择排序代码1:for i=0 to n-2min=ifor j= i+1 to n-1if ele[min]>ele[j] min=jswap(ele[i],ele[min]) //交换图1、选择排序在不同数据规模下排序所消耗的时间2、冒泡排序代码2:for i= 0 to n-1for j=0 to n-1-iif a[j]>a[j+1]swap(a[j],a[j+1]) //交换图2、冒泡排序在不同数据规模下排序所消耗的时间3、合并排序代码3:Merge(ele[1...n],left,right)middle=(left+right)/2if right>1eft+1Merge(ele,left,middle)Merge(ele,middle+1,right)l←left r←right i←leftwhile l<=middle&&r<=right //两组分别一一比较,数据小的放入ele if ele[l]<=ele[r]t[i++]←ele[l++]elset[i++]←ele[r++]while l>middle&&r<=r //只剩一组还有剩余的时,将剩下的按顺序放入ele[i++]=s[r++]while l<=middle && r>rightele[i++]=s[l++];图3、合并排序在不同数据规模下排序所消耗的时间4、快速排序代码4:quick(ele[0...n-1],left,right)if l<rl←left r←right x←ele[l];while l<rwhile l<r && x<=ele[r] //找到一个比x小的数之后交换到前面的部分r--if l<rele[l]←ele[r] l++while l<r && x>ele[l] //与上面相反ll++if l<rele[r]←ele[l] r--ele[l]←x;quick(ele,left,l-1) // 递归调用quick(ele,l+1,right)图4、快速排序在不同数据规模下排序所消耗的时间5、插入排序代码5:for i=1→n-1if ele[i]<ele[i-1] temp=ele[i]for j= i-1 to 0 && ele[j]>tempele[j+1]←ele[j]ele[j+1]←temp图5、插入排序在不同数据规模下排序所消耗的时间三.实验分析选择排序:图6、由图1数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表1、图7所示):(由于图片占空间大且表达不直白,我将所得数据做成表格分析,下同)表1、选择排序在不同数据规模下排序所消耗的时间图7、由表1数据整合而成的折线图图形上:形状基本符合n2(二次增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000: 158*22=632≈634 10000→30000:158*32=1422≈142420000→40000: 634*22=2536≈2541其他倍数也可得到类似的结果。
【算法】凸包问题--分治法
【算法】凸包问题--分治法凸包问题--分治法求能够完全包含平⾯上n个给定点的凸多边形。
⽰例:⼀、分治法:(⼀)算法思路:(这⾥所说的直线都是有向直线的。
)将数组升序排序,若x轴坐标相同,按照y轴坐标升序排序。
最左边的点p1和最右边的点p_n⼀定是该集合凸包的顶点。
该直线将点分为两个集合,上包为S1,下包为S2。
在p1 p_n线上的点不可能是凸包的顶点,所以不⽤考虑。
在上包S1中,找到p_max(距离直线p1p_n最远距离的点),若有两个距离同样远的点,取∠p_max p1 p_n最⼤的那个点(即△p_max p1 p_n⾯积最⼤)。
(⼀次递归到这⾥结束)找出S1中所有在直线p1 p_max左边的点,这些点中⼀定有构成上包中左半部分边界的顶点,⽤上⾯的算法递归查找点,直到上包就是以p1和p_n 为端点的线段。
下包S2中找下边界同理。
*如何判断点是否在直线p1 p_max左边(同 p1 p_n上⽅)?如果q1(x1,y1),q2(x2,y2),q3(x3,y3)是平⾯上的任意三个点,那么三⾓形△q1 q2 q3的⾯积等于下⾯这个⾏列式绝对值的⼆分之⼀。
当且仅当点q3=(x3,y3)位于直线q1 q2的左侧时,该表达式的符号为正,该点位于两个点确定的直线的左侧。
(⼆)实现中碰到的问题如何⽤快速排序来排序Point类(内有坐标x,y)的⼀维数组?按照x坐标排序很简单,若碰到x相同,y不同的怎么办?在快排的原基础上修改,以j向前逼近说明:(第⼀个while循环)当前⽐较数的横坐标>基准点的时,j向前逼近。
此处不加等于号,排序是不稳定的,即相等元素的相对位置可能发⽣改变。
(快排详见博客:(第⼆个while为添加内容)⽐较相等元素的纵坐标,基准点的更⼩,j继续向前逼近,即相等元素的相对位置不发⽣改变;否则,则改变。
也就是将原来快排中while循环拆分为两个,增加相等元素另外⽐较纵坐标的情况。
while (i < j && points[j].getX() > center.getX()) {j--;}while (i < j && center.getX() == points[j].getX() && points[j].getY() > center.getY()) {j--;}/** (i<j)若points[j].getX()< center.getX()或 center.getX() ==* points[j].getX()且points[j].getY()<center.getY() 以上两种情况,需要赋值*/if (i < j)// 跳出循环也有可能时因为i=j,所以这⾥要判断⼀下points[i++] = points[j];如果使⽤全局数组visit标识点是否访问,能确定凸包的所有顶点,但怎么顺序输出?在已经求的凸包顶点⾥逐⼀确定边界,判断是不是所有点都在这条边界的⼀侧,如果是则确定⼀条边界。
关于凸包问题
关于凸包问题Graham扫描法基本思想:通过设置⼀个关于候选点的堆栈s来解决凸包问题。
操作:输⼊集合Q中的每⼀个点都被压⼊栈⼀次,⾮CH(Q)(表⽰Q的凸包)中的顶点的点最终将被弹出堆栈,当算法终⽌时,堆栈S中仅包含CH(Q)中的顶点,其顺序为个各顶点在边界上出现的逆时针⽅向排列的顺序。
注:下列过程要求|Q|>=3,它调⽤函数TOP(S)返回处于堆栈S 顶部的点,并调⽤函数NEXT-TO –TOP(S)返回处于堆栈顶部下⾯的那个点。
但不改变堆栈的结构。
GRAHAM-SCAN(Q)1 设P0 是Q 中Y 坐标最⼩的点,如果有多个这样的点则取最左边的点作为P0;2 设<P1,P2,……,Pm>是Q 中剩余的点,对其按逆时针⽅向相对P0 的极⾓进⾏排序,如果有数个点有相同的极⾓,则去掉其余的点,只留下⼀个与P0 距离最远的那个点;3 PUSH(p0 , S)4 PUSH(p1 , S)5 PUSH(p3 , S)6 for i ← 3 to m7 do while 由点NEXT-TOP-TOP(S),TOP(S)和Pi 所形成的⾓形成⼀次⾮左转8 do POP(S)9 PUSH(pi , S)10 return S⾸先,找⼀个凸包上的点,把这个点放到第⼀个点的位置P0。
然后把P1~Pm 按照P0Pi的⽅向排序,可以⽤⽮量积(叉积)判定。
做好了预处理后开始对堆栈中的点<p3,p4,...,pm>中的每⼀个点进⾏迭代,在第7到8⾏的while循环把发现不是凸包中的顶点的点从堆栈中移去。
(原理:沿逆时针⽅向通过凸包时,在每个顶点处应该向左转。
因此,while循环每次发现在⼀个顶点处没有向左转时,就把该顶点从堆栈中弹出。
)当算法向点pi推进、在已经弹出所有⾮左转的顶点后,就把pi压⼊堆栈中。
举例如下: ⽮量的概念: 如果⼀条线段的端点是有次序之分的,我们把这种线段成为有向线段(directed segment)。
算法设计算法实验报告(3篇)
第1篇一、实验目的本次实验旨在通过实际操作,加深对算法设计方法、基本思想、基本步骤和基本方法的理解与掌握。
通过具体问题的解决,提高利用课堂所学知识解决实际问题的能力,并培养综合应用所学知识解决复杂问题的能力。
二、实验内容1. 实验一:排序算法分析- 实验内容:分析比较冒泡排序、选择排序、插入排序、快速排序、归并排序等基本排序算法的效率。
- 实验步骤:1. 编写各排序算法的C++实现。
2. 使用随机生成的不同规模的数据集进行测试。
3. 记录并比较各算法的运行时间。
4. 分析不同排序算法的时间复杂度和空间复杂度。
2. 实验二:背包问题- 实验内容:使用贪心算法、回溯法、分支限界法解决0-1背包问题。
- 实验步骤:1. 编写贪心算法、回溯法和分支限界法的C++实现。
2. 使用标准测试数据集进行测试。
3. 对比分析三种算法的执行时间和求解质量。
3. 实验三:矩阵链乘问题- 实验内容:使用动态规划算法解决矩阵链乘问题。
- 实验步骤:1. 编写动态规划算法的C++实现。
2. 使用不同规模的矩阵链乘实例进行测试。
3. 分析算法的时间复杂度和空间复杂度。
4. 实验四:旅行商问题- 实验内容:使用遗传算法解决旅行商问题。
- 实验步骤:1. 设计遗传算法的参数,如种群大小、交叉率、变异率等。
2. 编写遗传算法的C++实现。
3. 使用标准测试数据集进行测试。
4. 分析算法的收敛速度和求解质量。
三、实验结果与分析1. 排序算法分析- 通过实验,我们验证了快速排序在平均情况下具有最佳的性能,其时间复杂度为O(nlogn),优于其他排序算法。
- 冒泡排序、选择排序和插入排序在数据规模较大时效率较低,不适合实际应用。
2. 背包问题- 贪心算法虽然简单,但在某些情况下无法得到最优解。
- 回溯法能够找到最优解,但计算量较大,时间复杂度较高。
- 分支限界法结合了贪心算法和回溯法的特点,能够在保证解质量的同时,降低计算量。
3. 矩阵链乘问题- 动态规划算法能够有效解决矩阵链乘问题,时间复杂度为O(n^3),空间复杂度为O(n^2)。
凸包算法详解
凸包算法详解Graham扫描法时间复杂度:O(n㏒n)思路:Graham扫描的思想是先找到凸包上的⼀个点,然后从那个点开始按逆时针⽅向逐个找凸包上的点,实际上就是进⾏极⾓排序,然后对其查询使⽤。
步骤:1. 把所有点放在⼆维坐标系中,则纵坐标最⼩的点⼀定是凸包上的点,如图中的P0。
2. 把所有点的坐标平移⼀下,使 P0 作为原点,如上图。
3. 计算各个点相对于 P0 的幅⾓α,按从⼩到⼤的顺序对各个点排序。
当α相同时,距离 P0 ⽐较近的排在前⾯。
例如上图得到的结果为P1,P2,P3,P4,P5,P6,P7,P8。
我们由⼏何知识可以知道,结果中第⼀个点 P1 和最后⼀个点 P8 ⼀定是凸包上的点。
(以上是准备步骤,以下开始求凸包)以上,我们已经知道了凸包上的第⼀个点 P0 和第⼆个点 P1,我们把它们放在栈⾥⾯。
现在从步骤3求得的那个结果⾥,把 P1 后⾯的那个点拿出来做当前点,即 P2 。
接下来开始找第三个点:4. 连接P0和栈顶的那个点,得到直线 L 。
看当前点是在直线 L 的右边还是左边。
如果在直线的右边就执⾏步骤5;如果在直线上,或者在直线的左边就执⾏步骤6。
5. 如果在右边,则栈顶的那个元素不是凸包上的点,把栈顶元素出栈。
执⾏步骤4。
6. 当前点是凸包上的点,把它压⼊栈,执⾏步骤7。
7. 检查当前的点 P2 是不是步骤3那个结果的最后⼀个元素。
是最后⼀个元素的话就结束。
如果不是的话就把 P2 后⾯那个点做当前点,返回步骤4。
最后,栈中的元素就是凸包上的点了。
以下为⽤Graham扫描法动态求解的过程: 下⾯静态求解过程1 #include<iostream>2 #include<string.h>3 #include<algorithm>4 #include<cstdio>5 #include<cmath>6using namespace std;7const int maxn=105;8const double PI=acos(-1.0);9struct node{int x,y;};10 node vex[maxn];//存⼊所有坐标点11 node stackk[maxn];//凸包中所有的点12bool cmp1(node a,node b){//按点的坐标排序13if(a.y==b.y)return a.x<b.x;//如果纵坐标相同,则按横坐标升序排14else return a.y<b.y;//否则按纵坐标升序排15 }16bool cmp2(node a,node b){//以基点为坐标原点,极⾓按升序排,这⾥可⽤atan2函数或者叉积来进⾏极⾓排序,但是⽤atan2函数来排序效率⾼时间快,不过精度⽐叉积低17double A=atan2(a.y-stackk[0].y,a.x-stackk[0].x);//返回的是原点⾄点(x,y)的⽅位⾓,即与x轴的夹⾓18double B=atan2(b.y-stackk[0].y,b.x-stackk[0].x);19if(A!=B)return A<B;//逆时针⽅向为正值,极⾓⼩的排在前⾯20else return a.x<b.x;//如果极⾓相同,则横坐标在前⾯的靠前排列21 }22int cross(node p0,node p1,node p2){//计算两个向量a、b(a=(x1,y1),b=(x2,y2))的叉积公式:a×b=x1y2-x2y1 ===> p0p1=(x1-x0,y1-y0),p0p2=(x2-x0,y2-y0)23return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);24 }25double dis(node a,node b){//计算两点之间的距离26return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));27 }28int main(){29int t;30while(~scanf("%d",&t)&&t){31for(int i=0;i<t;++i)//输⼊t个点32 scanf("%d%d",&vex[i].x,&vex[i].y);33if(t==1)printf("%.2f\n",0.00);//如果只有⼀个点,则周长为0.0034else if(t==2)printf("%.2f\n",dis(vex[0],vex[1]));//如果只有两个点,则周长为两个点的距离35else{36 memset(stackk,0,sizeof(stackk));//清037 sort(vex,vex+t,cmp1);//先按坐标点的位置进⾏排序38 stackk[0]=vex[0];//取出基点39 sort(vex+1,vex+t,cmp2);//将剩下的坐标点按极⾓进⾏排序,以基点为坐标原点40 stackk[1]=vex[1];//将凸包中的第⼆个点存⼊凸集中41int top=1;//当前凸包中拥有点的个数为top+142for(int i=2;i<t;++i){//不断地找外围的坐标点43while(top>0&&cross(stackk[top-1],stackk[top],vex[i])<=0)top--;//如果叉积为负数或0(0表⽰两向量共线),则弹出栈顶元素44//虽然第2个凸点显然是最外围的⼀点,但加上top>0保证了栈中⾄少有2个凸点45 stackk[++top]=vex[i];46 }47double s=0;48for(int i=1;i<=top;++i)//计算凸包的周长49 s+=dis(stackk[i-1],stackk[i]);50 s+=dis(stackk[top],vex[0]);//最后⼀个点和第⼀个点之间的距离51 printf("%.2f\n",s);52/*53 int s=0;//计算凸包的⾯积54 for(int i=1;i<=top;i++)55 s+=cross(st[i-1],st[i],e[0])/2;56*/57 }58 }59return0;60 }。
凸包问题解题报告
凸包问题解题报告题目:在平面上给定了N 个点,求包含这N 个点的最小凸几何体,如下:算法思路:找出输入节点中的y 值最小的点,如果有若干个y 值相同的点,选择出x 最小的点(标号为min )从min 开始,按逆时针方向搜寻下一个点,先寻找右上方的点,要求斜率k>0,且斜率要最小,如果右上方找不到点了,再寻找左上方的点,此时要求斜率k<0,且斜率要最小,如果左上方也找不到点了,继续寻找左下方的点,此时要求斜率k>0,且斜率要最小,如果左下方也找不到满足要求的点了,则最后寻找右下方的点,直到重新找到起始的min 点,说明此次搜寻结束。
算法思路并不难,下面说一些程序运行时的技巧。
1、从上面的思路中可以看到,有四个方向要去寻找,如果分4段写,无疑是比较麻烦的,有没有什么好的办法,可以缩短代码?可以,我们可以考虑用一个循环来一次将四个方向都给搜遍:注意观察一下,假设当前节点的坐标为{ EMBED Equation.KSEE3 \* MERGEFORMAT |)(00,y x ,而被测试节点的坐标为,考虑到实际运算的情况,则四个方向分别满足如下条件即可:右上方的满足条件是:(在右侧的点的必定大于)左上方的满足条件是:(在上方的点的必定小于)左下方的满足条件是:(在左侧的点的必定小于)右下方的满足条件是:(在下方的点的必定大于)而如果第一个和第二个条件不等式的两边同时乘以1,第三个和第四个条件不等式的两边同时乘以-1,则四个不等式全都是大于的关系。
而第一个和第三个比较的是和的关系,第二个和第四个比较的是和的关系,因此对于如下循环For(int i = 0; i < 4; ++ i)表示的四个方向循环for (int j = 0; j < num; ++ j) //依次选择每个点比较的条件可以用如下一个式子表示:If(point[min][i%2]*pow(-1,i/2) > point[j][i%2]*pow(-1,i/2)){.......}由此解决了四个方向的循环问题。
背包问题 实验报告
实验报告课程名称:算法设计与分析实验名称:解0-1背包问题任课教师:王锦彪专业:计算机应用技术班级: 2011 学号: ****** 姓名:严焱心完成日期: 2011年11月一、实验目的:掌握动态规划、贪心算法、回溯法、分支限界法的原理,并能够按其原理编程实现解决0-1背包问题,以加深对上述方法的理解。
二、实验内容及要求:1. 要求分别用动态规划、贪心算法、回溯法和分支限界法求解0-1背包问题;2. 要求显示结果。
三、实验环境和工具:操作系统:Windows7开发工具:Eclipse3.7.1 jdk6开发语言:Java四、实验问题描述:0/1背包问题:现有n 种物品,对1<=i<=n ,第i 种物品的重量为正整数W i ,价值为正整数V i ,背包能承受的最大载重量为正整数C ,现要求找出这n 种物品的一个子集,使得子集中物品的总重量不超过C 且总价值尽量大。
动态规划算法描述: 根据问题描述,可以将其转化为如下的约束条件和目标函数:⎪⎩⎪⎨⎧≤≤∈≤∑∑==)1}(1,0{C max 11n i x x w x v ini i i ni ii寻找一个满足约束条件,并使目标函数式达到最大的解向量),......,,,(321n x x x x X =,使得C 1∑=≤n i i i x w ,而且∑=ni i i x v 1达到最大。
0-1背包问题具有最优子结构性质。
假设),......,,,(321n x x x x 是所给的问题的一个最优解,则),......,,(32n x x x 是下面问题的一个最优解:∑∑==⎪⎩⎪⎨⎧≤≤∈-≤n i i i ini i i x v n i x x w x w 2211max )2}(1,0{C 。
如果不是的话,设),......,,(32n y y y 是这个问题的一个最优解,则∑∑==>n i n i i i i i x v y v 22,且∑=≤+n i i i y w x w 211C 。
《算法导论》第33章 凸包问题
《算法导论》第33章凸包问题目录1.凸包问题的定义和背景2.凸包问题的应用3.凸包问题的解决方案4.凸包问题的算法分析5.凸包问题的实际应用案例正文一、凸包问题的定义和背景凸包问题是计算机图形学和计算几何中的一个经典问题。
它指的是给定一组二维或三维空间中的点,寻找一个最小的凸多边形,使得这个多边形包含了所有的点。
也就是说,任意一个点只要在凸包内部,就能被凸包上的某一点所见到,反之则不能。
二、凸包问题的应用凸包问题在计算机图形学和计算几何中有广泛的应用,例如:1.几何优化:通过凸包可以得到一组点的最小包围,可以应用于几何形状的优化和压缩。
2.碰撞检测:在计算机图形学中,凸包可以用于检测物体的碰撞,只要两个物体的凸包有交集,就说明两个物体发生了碰撞。
3.可视化:在数据可视化中,凸包可以帮助我们快速找到一组数据的主要分布区域。
三、凸包问题的解决方案凸包问题的解决方案主要有以下几种:1.基于三角剖分的方法:该方法通过将凸包分解成若干个三角形,然后利用三角形的性质来求解凸包。
2.基于团问题的方法:该方法将凸包问题转化为求解团问题,然后再将团问题转化为组合优化问题进行求解。
3.基于 Graham 扫描的方法:该方法是一种基于扫描线的方法,通过扫描线逐点扫描点集,可以快速得到凸包。
四、凸包问题的算法分析以上三种方法都有对应的时间复杂度和空间复杂度。
例如,基于三角剖分的方法的时间复杂度为 O(nlogn),空间复杂度为 O(n);基于团问题的方法的时间复杂度为 O(n),空间复杂度为 O(n);基于 Graham 扫描的方法的时间复杂度为 O(n),空间复杂度为 O(1)。
五、凸包问题的实际应用案例以碰撞检测为例,假设我们有两个物体 A 和 B,每个物体由多个点组成。
我们可以通过计算物体 A 和 B 的凸包,然后检测两个凸包是否有交集,如果有,就说明两个物体发生了碰撞。
青岛科技大学算法设计与分析实验报告-算法实训-背包问题
数据结构与算法分析2 课程设计报告书班级学号姓名指导教师庞志永课程设计项目名称:背包问题的多项式时间近似方案1.问题描述:背包问题可描述为如下的整数规划形式,其中M 为背包的容量,P 为物体的价值,W 为物体的体积。
2.基本要求:(1)在给定参数K 的条件下,设计背包问题的满足近似性能比不大于1+1/(k+1)的多项式时间近似方案,并选择适当的编程语言在计算机上实现。
(2)程序能够正常运行,计算结果正确,满足设计要求。
3.算法描述:将装入背包的物体进行多次尝试,其方法是:取K 为确定的非负整数,考虑背包问题的实例I 中的n 个物体的合的K 元素子集C ,|C|=K 。
(1)尝试将每个K 元素子集C 中的物体优先装入背包;(2)利用解答背包问题的贪心算法A 将(n-K)个物体尝试装入背包。
合并先装入的K 个物体和用算法A 装入的剩余物体作为算法的最终解。
过程如下:Procedure ε-APPROX(P,W,M,n,K)(1) P MAX =0;(2) For all combinations C of size=K & weight≤M do(3) P C =∑i∈C P i(4) P MAX =max{P MAX ,P C + L(I, P, W, M, n)};(5) End for(6) End ε-APPROXProcedure L(I,P,W,M,n)(1) S 1=0; T=M - ∑i∈C W i ;(2) For i=1 to n do(3) If i ∉C and W i ≤T then(4) S 1=S 1+P i , T=T – W i(5) End if(6) End for11max {0,1},1n i i i i n i i i Px x i n W x M==⎧⎪∈≤≤⎨≤⎪⎩∑∑(7) S=max{S1,max{P i| i ∉C}};(8) Return (S)(9) End L4.模块划分(仅供参考):(1)输入及存储原始数据模块(2)ε-APPROX(P,W,M,n,K)模块(3)L(I,P,W,M,n)模块(4)存储及输出结果模块5.本课程设计中遇到的关键问题及其解决方法:背包使用面向对象方法:package knapsack;public class Knapsack {/** 背包重量 */private int weight;/** 背包物品价值 */private int value;/**** 构造器*/public Knapsack(int weight, int value) {this.value = value;this.weight = weight;}public int getWeight() {return weight;}public int getValue() {return value;}public String toString() {return"[weight: "+ weight+ "\t"+ "value: "+ value + "]";}}获取最优解:package knapsack;import java.util.ArrayList;import java.util.List;import javax.swing.JOptionPane;import algorithm.dynamicplan.Knapsack;/*** 背包* 首先将最多 k件物品放人背包,* 如果这k件物品重量大于 c,则放弃它。
算法分析与复杂性理论-实验报告-求最近点对的问题
深圳大学实验报告教务部制1.对于平面上给定的N个点,给出所有点对的最短距离,即,输入是平面上的N个点,输出是N点中具有最短距离的两点。
2.要求随机生成N个点的平面坐标,应用蛮力法编程计算出所有点对的最短距离。
3.要求随机生成N个点的平面坐标,应用分治法编程计算出所有点对的最短距离。
4.分别对N=100,1000,10000,100000 ,统计算法运行时间,比较理论效率与实测效率的差异,同时对蛮力法和分治法的算法效率进行分析和比较。
5.利用Unity3D输出分治算法中间每个步骤的计算结果,并增设help按钮,详细解释算法思想。
算法思想提示1.预处理:根据输入点集S中的x轴和y轴坐标进行排序,得到X和Y,很显然此时X和Y 中的点就是S中的点。
2.点数较少时的情形直接计菊只有三个疽3.点数|S|>3时,将平面点集S分割成为大小大致相等的两个子集S L和S R,选取一个垂直线L作为分割直线,考虑X L和X R,Y L和Y R,这里还需要排序吗?4.两个递归调用,分别求出S L和S R中的最短距离为d i和d r。
5.取d=min(dl, dr),在直线L两边分别扩展d,得到边界区域Y, Y'是区域Y中的点按照y坐标值排序后得到的点集,Y'又可分为左右两个集合Y 'L和Y 'RL.一L<dL+d6.对于Y'L中的每一点,检查Y'R中的点与它的距离,更新所获得的最近距离实验过程及内容:(实验代码已作为附件提交,名为“算法实验二.cpp)当点的数量小丁3时,直接计算,当点的个数大丁3时,采用分治法当N=1时当N=2时只有两个点,最近点对就是这两个点测试数据为(1,1 ) (2,2)预期结果为d=1.414使用蛮力法求最近点对,核心代码如下〃求距离平方的函数double Distinyuish2(Node a t Node b)return ((d.x-b.x)*(a.x-b.x)) + ((a.y-tj.y)*(a.y-b.y));〃蛮力法求最近对uoid BriiteForce(const HList & L,CloseHode & cnode,int begin v int end)For(int i=t)egin;i<=end;i*+)Forfinit j<-end;j + + )double space = Di stinguish2(L.data[i],L.data[j]); iF<sp^ce<cnode.5pact)cnode_a=L.data[l]; cnade.b=L.data[j]; cnode .space=space;(计算两点之间的距离,分别将每个点与其它点的距离求出来,找出最近点距离)当N>3时,使用分治法的情况核心代码如下:;15E 〃当n》3时进行分治<APOIHT *SL-nev fi_POINT[(high-low)/2+1];■[POINT *SR-nev A>0IHT[ (hi^i-low)/2];n)= (high-low)/2; /成曦(组以缺)界划分为茜半j=k=t);for(i=B;i<=high-lou;i*+)if(V[i]*indeK<=n){SL[ ji ] T [i];〃收集左边子集中的最近点对pise{SR[kt+]=Y[i];〃收集右边子集中的最近点对>)closest (K.SL,low,■,al,bl,dl);//i+ 算左边子集的最近点对closes t (X,Sft,m+1,tiigh,ar.br,dr 算右边子靠的最近点对if(dl<dr);b=bl;d=dl;}else(a=ar;b=tjr ;d=dr;POIlfT *2=new POI NT[higti-low+1 ];k=o;For(i=B;i<=t*igh-lcw;i*+)//收集距离中线?寤小于U的元素,保存S懒组?中(iF(f=abstX[n] .x-V[l] .x)<d>2(k].x=V[i],x;£[k^+].y=V[i]^:for(i-l;l<k;l++)< far(j=i>1;(-y-Z[i] j++)dl=aist(Z[i]^[j]);{a = 2[iJ;b - Z[j];ri = d) ■当N=6时,给定一组测试数据下面随机生成N个点的平面坐标,求解最近点对。
凸包问题
凸包问题摘要:凸包问题是计算机几何中的一个经典问题,它要求将平面内的点集用最少的凸点将所有的顶点封闭。
凸包问题的应用十分广泛,很多最优化问题经过抽象后可以发现它最终是凸包问题模型;它还可以用于人际关系网络的最小化搜索,通过人际关系,可以合理推断出某人的身份,职位等个人特征。
目前求取凸包的常用算法有:穷举法,格雷厄姆扫描法(Graham),分治法,蛮力法和Jarris 步进法。
其中穷举法与蛮力法都是建立在穷举的算法思想上,它们的时间复杂度比较大,格雷厄姆扫描法采用几何方面的知识,降低了求解过程的时间复杂度。
关键词:凸包问题;计算机几何;格雷厄姆扫描法一、引言凸包问题的完整描述:令S 是平面上的一个点集,封闭S 中所有顶点的最小凸多边形,称为S 的凸包,表示为CH(S)。
如下图一所示,由红色线段表示的多边形就是点集Q={p0,p1,...p12}的凸包。
图一凸包问题是计算机几何的一个经典问题,它可以解决很多优化模型,目前目前求取凸包的常用算法有:穷举法,格雷厄姆扫描法(Graham),分治法,蛮力法和Jarris步进法。
本文主要讨论穷举法,蛮力法,以及格雷厄姆扫描法,通过算法思想的描述,计算出相应的时间复杂度,比较这几种算法的优劣。
二、穷举法穷举法的思想很简单直接,它利用凸包性质—如果点集中的两个点的连线属于凸多边形的边,当且仅当点集中其余的点都在这两个点连线的同一侧。
假设点集合S 中有n 个顶点,则这n 个顶点共可以构成(1)2n n -条边,对于任何一条边来讲,检查其余的n-2 个点的相对于该直线段的正负性。
如果它们有相同的正负性,说明该边是凸多边形的边,反之就不属于凸多边形,继续检查。
算法流程图如下:不相同 相同NY图二:算法流程图上述算法(穷举法)需要执行n(n-1)/2 次,再次检查n-2 个点的正负性,故算法时间复杂性为2(1)2n n -∑=3()o n 。
显然这并非一个高效的算法凸包问题有许多更加有效的算法可以达到log n n 的渐近时间复杂度。
凸包问题_实验报告
摘要:本文旨在通过实验探究凸包问题的求解方法,对比不同算法的效率和适用场景。
实验包括凸包问题的基本概念介绍、实验环境搭建、实验设计、实验结果分析以及结论总结。
关键词:凸包问题;算法;实验;比较分析一、引言凸包问题是指给定平面上的点集,找到能够覆盖所有点的最小凸多边形。
在计算机科学和几何学中,凸包问题有着广泛的应用,如计算机图形学、地理信息系统、机器学习等领域。
本文通过实验对比了几种常见的凸包求解算法,包括 Graham 扫描、Jarvis步进法和快速傅里叶变换(FFT)方法。
二、实验环境搭建1. 硬件环境:实验在个人笔记本电脑上进行,操作系统为 Windows 10,CPU 为Intel Core i5,内存为 8GB。
2. 软件环境:使用 Python3.8 作为编程语言,依赖 NumPy 和 SciPy 库进行数值计算和绘图。
三、实验设计1. 实验目的:- 对比 Graham 扫描、Jarvis 步进法和 FFT 方法在求解凸包问题上的性能。
- 分析不同算法的时间复杂度和空间复杂度。
- 探究不同算法在不同规模数据集上的表现。
2. 实验数据:- 随机生成不同规模的点集,如 1000、2000、3000、4000 和 5000 个点。
- 对于每个点集,分别使用三种算法求解凸包。
3. 实验步骤:- 使用 NumPy 随机生成点集。
- 对每个点集,分别使用 Graham 扫描、Jarvis 步进法和 FFT 方法求解凸包。
- 记录每个算法的运行时间、空间复杂度和生成的凸包面积。
- 使用 Matplotlib 绘制点集和生成的凸包。
四、实验结果分析1. 运行时间:- 在小规模数据集(1000 个点)上,三种算法的运行时间相差不大。
- 随着数据集规模的增加,Graham 扫描和 FFT 方法的运行时间明显优于Jarvis 步进法。
2. 空间复杂度:- 三种算法的空间复杂度均为 O(n),其中 n 为点集规模。
背包问题实习报告
背包问题摘要:背包问题在信息加密、预算控制、项目选择、材料切割、货物装载、嘲络信息安全等应用中具有重要的价值。
从计算复杂性理论看,背包问题是一个经典NP 难解问题。
半个多世纪以来,该问题一直是算法与复杂性研究的热点问题之一。
论文研究了背包问题的实用求解算法,提出了改进的新算法,并利用Maltab 对几种算法进行了仿真实验,测试的结果显示出新算法在解决0/1背包问题时表现出了良好的性能。
关键字:蚁群算法,背包问题,遗传算法,MATLAB引言背包问题(knapsackproblem ,简称KP)是运筹学中一个典型的优化难题,在预算控制、项目选择、材料切割、货物装载等实践中有重要应用,并且还常常作为其他问题的子问题加以研究。
随着网络技术的不断发展,背包公钥密码在电子商务中的公钥设计中也起着重要的作用。
背包问题的数学模型为:Max ƒ(21,x x …n x )=j j nj x c 1=∑ 2,1=j …nt s . nj 1=∑ j j ij b x a ≤ 2,1=i …{}1,0⊆j i x m式中,n 为物品的编号:m为资源的编号;j c 为第j 个物品的受益量;i b 成为第i 种资源的预算:ij a 为第j个物品占用第i 种资源的量:j x 为o-1决策变量(当物品j被选择时j x =1否贝j x =0)。
KP的语言描述可以这样:现有j(j=1,2,⋯,n)个物品,每个物品将会消耗m种资源啦a=(1,2,⋯,m),如果将物品j装人ij背包将会获益q,与此同时,要求所有装入背包的物品消耗的资源I 不能超过b。
i背包问题可以衍生出一系列与之相关的优化问题,如有限背包问题(物体可具有相同价值和重量但数量是有限的),无限背包问题(具有相同价值和重量的物体数量可以是无限的),多背包问题(将物体装入多个容量不同的背包)等。
本文中所指背包问题如无特殊说明,均指"Fl的简单0/1背包问题。
背包问题在实践中有广泛的应用背景。
算法分析与复杂性理论-实验报告-最大流问题
深圳大学实验报告课程名称:算法分析与复杂性理论实验名称:实验五最短增益路径法求最大流问题学院:计算机与软件学院专业:软件工程报告人:文成学号:2150230509 班级:学术型同组人:无指导教师:杨烜实验时间:2015/11/23——2015/11/30实验报告提交时间:2015/11/28教务处制一.实验目的与实验内容实验目的:(1)掌握最短增益路径法思想。
(2)学会最大流问题求解方法。
实验内容:1.给定下面的通信网络,该网络中各节点之间的路径流量给定,使用最短增益路径法求解该网络的最大流量,并进行流量分配。
2.要求用加权矩阵输入该网络,输出每次迭代过程中的最大流量及各路径分配的流量。
3.如果能利用图形界面输出动态求解过程(在网络结构的图形显示中,标注每一次求得的增益路径,并显示当前流量分配),可获加分。
算法思想提示:1. 利用二维数组C[i,j]和F[i,j]分别存放容量和流量。
2. 构建队列类Queue,该类具有取队首元素,加入队尾元素等方法。
3. 具体算法过程参见教材pp.271-272二.实验步骤最大流问题的问题描述:如上图。
s是源点,t为汇点,每条边上数字的含义是边能够允许流过的最大流量。
可以将边看成管道,3代表该管道每秒最多能通过3个单位的流量。
最大流问题即是说,从s点到t点,最大允许流量是多少?最大流问题的算法思想:最短增益路径法(先标记先扫描算法):用两个记号来标记一个新的顶点第一个标记指出从源点到被标记顶点还能增加多少流量第二个标记指出另一个顶点的名字,可加上+或-来表示顶点时通过前向边还是后向边访问到的思路以及代码解释:(全部源代码见附件)先创建一个解决问题的类,命名为G。
计算最大流作为这个类中的一个方法来实现。
利用二维数组Map[i,j]和Flow[i,j]分别存放容量和流量。
添加头文件#include <queue>,后面需要用到队列,需要该类的取队首元素,加入队尾元素等方法。
凸包算法设计
2.2 具体描述
在平面上,穿过两个点(x1,y1)和(x2,y2)的直线是由下面的方程 定的:
ax + by = c (其中,a=y2-y1,b=x1-x2,c=x1y2-y1x2)
(由(y-y₁)/(y₂-y₁)=(x-x₁)/(x₂-x₁)(两点式) 交叉相乘得:(y-y₁)(x₂-x₁)=(y₂-y₁)(x-x₁) 去括号整理可得:(y₂-y₁)x+(x₁-x₂)y-x₁y₂+x₂y₁=0 ∴a=y₂-y₁ b=x₁-x₂ c=x₁y₂-x₂y₁)
dealwith(VAR side,list, resultList) //处理某一条边side及其所属的离散点集list,并把找到的凸包顶点 放到凸包顶点集resultList中 if not is Empty(list) then { node:=LongNode(side,list);//找出list中离这条边最远的点,并 把它从List中删除 insert(resultList,side, node);//该点肯定是凸包的顶点,把它放 到凸包顶点集的相应位置,该位置就在该边起点的后面 Triangle:=create Triangle(side,node); //该点和原先的边生成 一个三角形 while(not is Empty(list)) do
谢谢
算法: Void convex_hull() { int i,j,k,sign=0;//sign用于记录满足条件的点 double a=0,b=0,c=0; for(i=0;i<MAXNUM;++i)//MAXNUM for(j=i+1;j<MAXNUM;++j) {
凸包生成算法实验报告
实验报告班级:学生姓名:学号: 201101218日期: 2014年5月11日判断点线关系及计算多边形内角一、点与线的关系(1)定义:平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量:|x1 x2 x3|S(P1,P2,P3) = |y1 y2 y3| = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)|1 1 1 |当P1P2P3逆时针时S为正的,当P1P2P3顺时针时S为负的。
令矢量的起点为A,终点为B,判断的点为C,如果S(A,B,C)为正数,则C在矢量AB的左侧;如果S(A,B,C)为负数,则C在矢量AB的右侧;如果S(A,B,C)为0,则C在直线AB上。
(2)算法二、计算多边形内角(1)算法过程第一步:输入一系列的离散点;第二步:找x坐标值最小的点p0,这样能确定由此点构成的多边形的角是凸的;第三步:定义与p0点相邻的前后两个点p1,p2,若超出数组边界,则用首点或尾点取代;第四步:计算p2与向量p1p0的位置关系,若p2在向量p1p0的左边,则多边形呈逆时针方向;若p2在向量p1p0的右边,则多边形呈顺时针方向。
第五步:计算多边形的各个内角,利用两个向量的夹角公式计算。
由于多边形有凹凸性,所以算角时要分情况。
找规律可知,若多边形是逆时针走向,那么,若三个相邻的点构成凸角,三点的走向始终是逆时针走向,否则,是顺时针走向,故可根据此来确定角度。
(2)算法实现12详细代码:3float angle = MyMath::CalcuAngle(pi_1,p,pi1,flag);trangleArray.Add ((int)angle);}return true;}return false;}(3)算法结果凸包生成算法一、凸包定义通俗的说就是:一组平面上的点,求一个包含所有点的最小凸多边形,这个最小凸多边形就是凸包。
二、Graham算法思想概要:Graham算法的主要思想就是,最终形成的凸包,即包围所有点的凸多边形,假定多边形是按逆时针方向生成的,那么多边形内部包围的所有点与多边形每个有向边的关系都是:点在有向边的左边。
计算复杂性理论总结报告
计算复杂性理论总结报告(总10页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--计算复杂性理论总结报告一、图灵机(1)图灵机基本模型图灵机是由图灵(Alan Mathisom Turing)在1936年提出的,它是一个通用的计算模型。
通过图灵机,来研究递归可枚举集和部分递归函数,对算法和可计算性进行研究提供了形式化描述工具。
图灵机的基本模型包括一个有穷控制器,一条含有无数个带方格的输入带和一个读写头。
其直观物理模型如下图1所示。
基本图灵动作有以下三种:(1)改写被扫描带方格内容,控制器转化为下一状态。
(2)读写头向左移一个带方格,控制器转化为下一状态。
(3)读写头向左移一个带方格,控制器转化为下一状态。
图1图灵机(2)图灵机形式化定义,图灵机演算过程及语言描述定义:一个基本图灵机定义为一个七元组 TM={Q,C,δ,A,B,q1,F}。
其中Q是状态集合,(图灵机所有的状态)非空有限集;C是带符号表,(放在带方格中的符号集合)非空集;δ是控制函数或过程转换函数(定义控制器)δ:QxC QxC∪(R,L);A是输入字母表,A⊆C;B是空白符,B∈C;q1是初始状态,q1∈Q;F是终态集,F ⊆Q.TM的扫描符号串主要由δ来确定:(1)δ(q,s)=(q’,s’);(2)δ(q,s)=(q’,R);(3)δ(q,s)=(q’,L);(4)δ(q,s)无效,对应无定义时图灵机终止。
TM的工作用“格局”的转换来描述。
格局:σ:a1a2a3…aj-1qajaj+1…其中q∈Q,ai∈C;(1)若δ(q,ai)无定义,称σ为停机格局;(2)若q∈F,称σ为接受格局;(3)若q为初始状态,称σ为初始格局;格局σ到格局τ的转换σ├mτ若成立σ=σ1├m1σ2├m2σ…3├Mσk 记为σ1├*σk (k>=0)(3)图灵机其他形式(1)五元机δ:QxC→QxCx{R,L}基本动作:qsq’s’即δ(q,s)=(q’,s’);qsq’L即δ(q,s)=(q’,L);qsq’R即δ(q,s)=(q’,R)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
由此就可得到凸包问题的分治算法。
Step1:把 S 中的点按 x 坐标进行排序。 Step2:划分成两个子集 S1,S2. Step3:P1=CH(S1)和 P2=CH(S2). Step:合并 P1,P2 得到解集 P.
蛮力法解决凸包问题核心代码
分治法解决凸包问题核心代码如下:
如图所示,分治法实现后的运行程序如下 做一个 6 个点的测试
实验结论: 分治法的思想就是将一个规模为 n 的问题分解为 k 个规模较小的子问题,这些子问 题互相独立且与原问题相同。递归地解这些子问题,然后将各个子问题解合并得到原问 题的解。 蛮力法求凸包问题随着规模的增大,效率会越来越低,而使用一种最简单的凸包分 治算法效率更高:将点集依照某种划分方法分为 N 部分,对每个部分求子凸包,最后将 几个子凸包合成一个更大的凸包。 通过本次试验我对分治法有了更深的了解。利用分治法可以将问题简化,这有助于 我们在实际中解决一些复杂性较大的问题,提高程序的运行效率。
实验过程及内容: (实验代码已作为附件提交,名为“算法实验三.cpp” ) 凸包问题的描述与定义: 凸包的定义为: 平面的一个子集 S 被称为是“凸”的, 当且进当对于任意两点 p,q∈S, 线段都完全属于 S。几何 S 的凸包 CH(S),就是包含 S 的最小凸集,更准确地说,它是 包含 S 的所有凸集的交。由此还可以推出凸包的很多性质,包括一条直线如果与凸包相 交(不是相切)的话,最多交于两条边或者两个面。 一组平面上的点,求一个包含所有点的最小凸边形,既是凸包问题。 形象地说:在一平木板(平面)上钉若干钉子(点) ,将一橡皮筋套上去后,会把 钉子圈起来,形成一个凸边形,即为该点集的凸包。
关于用分治法求凸包问题的思路: 分治法是一种很基础的算法。基本思路是将问题分解为等价的几个子问题,对子问 题进行递归分解和求解,然后将子问题的解合成为所求的解。
由此, 可以得到一种最简单的凸包分治算法: 将点集依照某种划分方法分为 N 部分, 对每个部分求子凸包,最后将几个子凸包合成一个更大的凸包。
最终求出 3 个顶点(-5,-5) (9,9) (-1,1)为正确答案 将程序改成随机产生点,只需输入点的个数。输入 30 个点。 最终得到凸包的表边与点。
数据处理分析: 关于蛮力法求凸包问题 选择不同的两个点有 C n
2
n(n 1)
2
种选择,对这不同的两个点都要对其他的
3
n-2 个点求出 a*x+b*y-c 的值,即时间效率属于 O(n ),
1. 对于平面上给定的 N 个点,确定这个点集的凸包,即,输入是平面上的 N 个点,输 出是凸包轮廓。 2. 要求随机生成 N 个点的平面坐标,应用蛮力法编程计算出点集凸包。 3. 要求随机生成 N 个点的平面坐标,应用分治法编程计算出点集凸包。 4. 分别对 N=100,1000,10000,100000,统计算法运行时间,比较理论效率与实测效率 的差异,同时对蛮力法和分治法的算法效率进行分析和比较。注意需要在不同数据量之 间增加测试点,例如 10000 到 100000 之间需要增加 20000、30000。 。 。 ,以分析效率变化 趋势。 5. 利用 Unity 3D 输出算法中间结果,直至最后算法计算结果。同时增加 help 按钮, 详细介绍算法原理。
600 60.95 0
650 76.42 5
700 93.92 8
750 115.4 1
800 144.0 0
850 169.6 3
900 203.8 1
950 236.6 5
根据上表通过 Matlab 描点画图可得下图:
关于分治法求凸包问题 本人程序暂有些问题,当点数增大到 1000,10000,后并没有做出来 目前只能解决小规模的问题。未采集分治法的时间数据。
实验要求 1. 在 blackboard 提交电子版实验报告,注意实验报告的书写,整体排版。 2. 实验报告的实验步骤部分需详细给出算法思想与实现代码之间的关系解释,不可直 接粘贴代码(直接粘贴代码者视为该部分内容缺失) 。 3. 实验报告样式可从 http://192.168.2.3/guide.aspx 表格下载-学生适用-在校 生管理-实践教学-实验:深圳大学学生实验报告) 4. 源代码作为实验报告附件上传。 5. 在实验绩评定:
指导教师签字: 年 月 日
备注:
注:1、报告内的项目或内容设置,可根据实际情况加以调整和补充。 2、教师批改学生实验报告时间应在学生提交实验报告时间后 10 日内。
深 圳 大 学 实 验 报 告
课程名称:
算法分析与复杂性理论
实验项目名称:
实验三 分治法求凸包问题
学院:
计算机与软件学院
专业:
软件工程
指导教师:
杨烜
报告人:文成
学号:2150230509 班级: 15 级软工学术型
实验时间:
2015-10-22
实验报告提交时间:
2015-10-24
教务部制
实验目的与要求: 实验目的: (1) 掌握分治法思想。 (2) 学会凸包问题求解方法。
输入不同的 n 观察输出结果的时间,并填入如下表中: n Time(s) 100 0.281 150 0.920 200 2.247 250 4.399 300 7.504 350 12.02 8 400 17.84 7 450 25.13 2 500 34.39 9
n Time(s)
550 47.56 5