西北工业大学算法设计实验2
算法设计实验报告
算法设计实验报告一、实验目的本次算法设计实验的主要目的是通过实际操作和分析,深入理解算法的原理和应用,提高解决实际问题的能力,培养创新思维和逻辑推理能力。
二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。
同时,为了进行算法的性能分析和可视化,还使用了一些相关的库,如 time 用于计算时间开销,matplotlib 用于绘制图表。
三、实验内容(一)排序算法的实现与比较1、冒泡排序冒泡排序是一种简单的排序算法。
它重复地走访要排序的数列,一次比较两个数据元素,如果顺序不对则进行交换,并一直重复这样的走访操作,直到没有要交换的数据元素为止。
以下是冒泡排序的 Python 代码实现:```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n i 1):if arrj > arrj + 1 :arrj, arrj + 1 = arrj + 1, arrj```2、快速排序快速排序是对冒泡排序的一种改进。
它采用了分治的策略,通过选择一个基准元素,将待排序的序列分割成两个子序列,其中一个子序列的所有元素都小于等于基准元素,另一个子序列的所有元素都大于等于基准元素,然后对这两个子序列分别进行快速排序。
以下是快速排序的 Python 代码实现:```pythondef quick_sort(arr, low, high):if low < high:pi = partition(arr, low, high)quick_sort(arr, low, pi 1)quick_sort(arr, pi + 1, high)def partition(arr, low, high):pivot = arrhighi =(low 1)for j in range(low, high):if arrj <= pivot:i = i + 1arri, arrj = arrj, arriarri + 1, arrhigh = arrhigh, arri + 1return (i + 1)```(二)搜索算法的实现与比较1、顺序搜索顺序搜索是一种最简单的搜索算法,它从数组的开头开始,依次比较每个元素,直到找到目标元素或者遍历完整个数组。
西北工业大学 算法设计与分析实验指导
算法设计与分析实验指导王歧编实验一:递归与分治1.二分查找2.合并排序3.快速排序实验二:回溯1.0-1背包问题2.装载问题3.堡垒问题(ZOJ1002)4.*翻硬币问题5.8皇后问题6.素数环问题7.迷宫问题8.*农场灌溉问题(ZOJ2412)9.*求图像的周长(ZOJ1047)10.*骨牌矩阵11.*字母转换(ZOJ1003)12.*踩气球(ZOJ1004)实验三:搜索1.Floodfill2.电子老鼠闯迷宫3.跳马4.独轮车5.皇宫小偷6.分酒问题7.*找倍数8.*8数码难题实验四:动态规划1.最长公共子序列2.计算矩阵连乘积3.凸多边形的最优三角剖分4.防卫导弹5.*石子合并6.*最小代价子母树7.*旅游预算8.*皇宫看守9.*游戏室问题10.*基因问题11.*田忌赛马实验五:贪心与随机算法1.背包问题2.搬桌子问题3.*照亮的山景4.*用随即算法求解8皇后问题5.素数测试实验一:递归与分治实验目的理解递归算法的思想和递归程序的执行过程,并能熟练编写递归程序。
掌握分治算法的思想,对给定的问题能设计出分治算法予以解决。
实验预习内容编程实现讲过的例题:二分搜索、合并排序、快速排序。
对本实验中的问题,设计出算法并编程实现。
试验内容和步骤1.二分查找在对线性表的操作中,经常需要查找某一个元素在线性表中的位置。
此问题的输入是待查元素x和线性表L,输出为x在L 中的位置或者x不在L中的信息。
程序略2.合并排序程序略3.快速排序程序略实验总结及思考合并排序的递归程序执行的过程实验二:回溯算法实验目的:熟练掌握回溯算法实验内容:回溯算法的几种形式a)用回溯算法搜索子集树的一般模式void search(int m){if(m>n) //递归结束条件output(); //相应的处理(输出结果)else{a[m]=0; //设置状态:0表示不要该物品search(m+1); //递归搜索:继续确定下一个物品a[m]=1; //设置状态:1表示要该物品search(m+1); //递归搜索:继续确定下一个物品}}b)用回溯算法搜索子集树的一般模式void search(int m){if(m>n) //递归结束条件output(); //相应的处理(输出结果) elsefor(i=m;i<=n;i++){swap(m,i); //交换a[m]和a[i]if()if(canplace(m)) //如果m处可放置search(m+1); //搜索下一层swpa(m,i); //交换a[m]和a[i](换回来)}}习题1.0-1背包问题在0 / 1背包问题中,需对容量为c 的背包进行装载。
西北工业大学C语言大作业2
学院目录1 摘要 (3)1.1设计题目 (3)1.2设计内容 (3)1.3开发工具 (3)1.4应用平台 (3)2 详细设计 (3)2.1程序结构 (3)2.2主要功能 (4)2.3函数实现 (4)2.4开发日志 (5)3 程序调试及运行 (6)3.1程序运行结果 (6)3.2程序使用说明 (7)3.3程序开发总结 (7)4 附件(源程序) (8)1 摘要1.1 设计题目界面编程——简谐运动1.2 设计内容基于Windows界面编程下的SDK编程框架,设计一个带有对话框、GDI图形输出的Windows窗口的程序,实现求解简谐运动方程,能流密度,绘制简谐振动曲线。
运行程序,初始化,X0=V0=W=1时的简谐运动方程和简谐振动曲线。
当点击“运行|计算绘图”时,弹出对话框对简谐运动初相位X0,初速度V0和角频率W进行修改,点击“确认”,就能计算出简谐运动方程,能流密度,绘制简谐振动曲线,这些结果在窗口显示。
1.3 开发工具Visual C++ 6.0和Win32SDKApp1.4 应用平台Windows 2000/XP/Vista 32位2 详细设计2.1 程序结构一、程序的整体结构首先定义资源头文件resource.h;在进行资源描述文件,此过程可通过可视化操作;正式进入编写程序代码:1、由Win32SDKApp自动生成的SDK编程框架:头文件包含所有头文件或链接库文件全局定义应用实例、主窗口变量、数据结构等全局定义,固定不变消息处理函数原型给出所有消息处理函数的原型,增加/删除消息处理时变动消息映射表宏定义定义消息映射表,增加/删除消息处理时变动窗口过程窗口过程函数的实现,固定不变注册窗口类注册窗口类函数的实现,除非修改窗口属性,一般不动初始化窗口初始化窗口函数的实现,除非修改窗口初始化值,一般不动消息循环Windows应用程序主消息循环,一般不动主函数Windows应用程序基本结构,一般不动消息处理函数实现在这编写消息处理函数2、再对SDK编程框架进行修改:设置了快捷键就必须对消息循环函数修改在编写消息处理函数之前:在消息处理函数原型模块中加入要添加的消息处理函数(如WM_COMMAND、WM_ONPAIT)在消息映射表模块增加该消息映射在消息处理函数实现模块中给出该消息处理函数的实现如果消息处理函数之间有共享使用的变量,则将它定义为全局变量。
西北工业大学计算机学院
西北工业大学计算机学院计算机操作系统实验指导张羽谷建华王海鹏编2009-3一、操作系统课内实验目的:计算机操作系统课内实验作为操作系统课堂理论教学的辅助部分是加强计算机科学与技术专业实践的重要环节之一。
由于操作系统自身的庞大和复杂,造成学生在学过操作系统课程后,总有一种“雾里看花”的感觉,即只是支离破碎的了解了一些操作系统局部知识,而很难将这些知识融会贯通,对于运用操作系统知识从事设计和应用更是无从谈起。
本实验课的目的就是力图解决上述问题。
二、操作系统实验整体安排和要求:1.课内实验将按以下三个方面进行:对常用的系统调用命令的使用方式有一个较熟练的掌握;对典型操作系统的编程基础知识和机制进行学习和了解;运用一些重要的系统调用编写程序模块,对操作系统中的一些重要概念和典型算法进行实现或验证。
实验内容如下:实验一 Linux操作系统的安装及使用实验二 Linux Shell程序实验三 vi编辑器的学习和使用实验四 观察进程的并发性实验五 构造进程家族树实验六 理解进程的独立空间实验七 请求分页存储管理设计操作系统的课内实验共7个,根据具体上机条件和学时选做2~3个,其中实验2、3中必选1个,实验4~6必选,实验7可选做。
由于所有实验均在Linux环境下工作,用C语言编程,因此学生要具备一定的C语言编程能力,同时要求在充分预习实验内容中相关知识后,再进行实验的上机环节。
另外由于操作系统实验有些题目具有一定的难度和规模,建议采用分组方式进行。
2.操作系统课内实验考核:预习报告30%,上机实验35%,实验报告35%。
3.预习报告内容包括两部分,一是对相关知识学习的书面总结(知识综述和参考文献);二是对本次实验的分析报告(主要针对涉及算法的题目)。
实验报告内容主要包括本次实验的上机结果(数据结构、程序框图、源程序文档和运行情况)以及实验中难点分析和心得。
4.实验软、硬件环境要求:80386DX以上兼容机,可以使用Intel、AMD、CRIX处理器,对80386或80486SX的CPU建议具有数字协处理器。
C语言大作业西工大
实验报告 数据结构 实现深度优先搜索与广度优先搜索算法
一、实验目的 1、通过本实验,掌握图,无向图的基本概念,掌握图的遍历; 2、掌握图的深度优先搜索(DFS)与广度优先搜索(BFS)算法。
二、实验内容 1、建立图的存储方式; 2、图的深度优先搜索算法; 3、图的广度优先搜索算法。
pStack->parc = p; pStack->next = Stack->next; Stack->next = pStack; while(p && (Stack->next)) {
while(p) {
if(Visited[p->adjvex]) p=p->nextarc;
else
{
Visited[p->adjvex]=1;
printf(" %c ",ag.vertices[p->adjvex].cData);
printf("%d\t%c\t",i,pag->vertices[i].cData); p = pag->vertices[i].firstarc; while(p) {
printf("%d\t",p->adjvex); p = p->nextarc; } printf("\n"); } return 1; } int CreateGraph(ALGraph* pag,int start,int end) { ArcNode* arcNodes = (ArcNode*)malloc(sizeof(ArcNode)); ArcNode* arcNodee = (ArcNode*)malloc(sizeof(ArcNode)); ArcNode* p; if(!arcNodes || !arcNodee) return 0; arcNodes->adjvex = end; p = pag->vertices[start].firstarc; if(!p) {
西北工业大学-算法设计大作业
目录1 摘要 (3)1.1设计题目 (3)1.2设计内容 (3)1.3开发工具 (3)1.4应用平台 (3)2 详细设计 (3)2.1程序结构 (3)2.2主要功能 (10)2.4开发日志 (11)3 程序调试及运行 (11)3.1程序运行结果 (11)3.2程序使用说明 (13)3.3程序开发总结 (13)1 摘要1.1 设计题目(1)阶乘求和(2)数组排序(3)图形绘制1.2 设计内容(1)求1!+2!+3!+4!+5!(2)有一个数组中有10个数组元素,输入所有数组元素的值,对数组进行从大到小排序(3)绘制图形1.3 开发工具Raptor是一种基于流程图的可视化编程开发环境。
流程图是一系列相互连接的图形符号的集合,其中每个符号代表要执行的特定类型的指令。
符号之间的连接决定了指令的执行顺序。
一旦开始使用Raptor 解决问题,这样的理念将会变得更加清晰。
1.4 应用平台Windows XP / 7/Vista 32位2 详细设计2.1 程序结构(1)(2)(3)2.2 主要功能(1)通过调用子程序,利用循环思想,实现阶乘求和;(2)先输入十个数组元素,再利用冒泡法,使它们按照由大到小的顺序排列;(3)通过过程调用,进行图形编程,计算坐标,合理排布线段、矩形、圆等图形,最后绘制出优美的图形。
2.4 开发日志按照题目要求设计程序,运用各种工具把程序编写好,然后进行试运行,找出错误进行改正后,继续运行,知道运行结果正确。
3 程序调试及运行3.1 程序运行结果(1)(2)(3)3.2 程序使用说明(1)先切换至中级模式,再开始运行程序,最后可得到结果;(2)开始运行后,按照程序提示,依次输入10个数组元素,程序运行后即可使其按从大到小排列;(3)直接运行程序,即可得到预先设计好的美丽的图形。
3.3 程序开发总结(1)了解了如何调用子程序,切实感受到了利用子程序可以使程序更为简捷,运行更为迅速,十分方便;(2)实际体会了循环,判断等思想在数组排序中的应用,受益匪浅;(3)体会到了raptor的强大功能,可以快速而准确地绘制图形。
工业算法测试实验报告
一、实验背景随着工业自动化和信息化的快速发展,算法在工业领域的应用日益广泛。
为了确保算法在实际工业环境中的可靠性和高效性,本实验对几种常见的工业算法进行了测试和分析。
二、实验目的1. 了解不同工业算法的原理和特点。
2. 评估算法在工业环境中的性能表现。
3. 为工业自动化系统的算法优化提供依据。
三、实验内容本实验选取了以下几种工业算法进行测试:1. 快速排序算法2. 归并排序算法3. 希尔排序算法4. 堆排序算法四、实验方法1. 数据准备:随机生成大量测试数据,包括升序、降序、逆序和随机排列的数组。
2. 算法实现:根据每种算法的原理,分别实现相应的代码。
3. 性能测试:对每种算法进行性能测试,包括排序时间、内存消耗和算法稳定性等方面。
4. 结果分析:对测试结果进行统计分析,比较不同算法的性能差异。
五、实验结果与分析1. 快速排序算法- 原理:快速排序是一种分治算法,通过选取一个基准值,将数组划分为两部分,分别对这两部分进行快速排序。
- 性能测试:在升序、降序、逆序和随机排列的数组中,快速排序的平均排序时间分别为0.015秒、0.017秒、0.018秒和0.020秒。
- 分析:快速排序在升序和降序数组中表现较好,而在逆序和随机排列的数组中性能略有下降。
2. 归并排序算法- 原理:归并排序是一种稳定的排序算法,通过将数组分割成多个子数组,然后对这些子数组进行排序,最后将排序后的子数组合并成一个有序数组。
- 性能测试:在升序、降序、逆序和随机排列的数组中,归并排序的平均排序时间分别为0.018秒、0.020秒、0.022秒和0.024秒。
- 分析:归并排序在各种类型的数组中表现稳定,但在逆序和随机排列的数组中性能相对较差。
3. 希尔排序算法- 原理:希尔排序是一种基于插入排序的算法,通过设置一个增量序列,逐步缩小增量,对数组进行排序。
- 性能测试:在升序、降序、逆序和随机排列的数组中,希尔排序的平均排序时间分别为0.012秒、0.014秒、0.016秒和0.018秒。
西北工业大学java实验报告.
Forth.java——
说明:编写图形界面的Java Applet,接受用户输入的一个整形数和一个浮点型数,单击按钮求两数之和。
实验1-5:
WaysOfTakingMoney.java——
说明:小明有5分、2分、1分硬币,想拿出1元钱,有几种拿法?给出所有拿法。实现方式不限。
在此题中运用了穷举法,列出了各种取法。
实验5-1:
FileInfor.java——
说明:编写一个图形化小工具,功能类似系统工具dir,可查看用户给定文件的创建时间、文件类型、文件大小等信息。
创建时间、文件大小等信息可直接通过file类取得,文件类型需要写方法判断,接受用户输入的文件名,截取其后缀,根据其后缀判断文件的类型。例如后缀为.java的是Java的源程序文件,后缀为.txt的是文本文件。注意提高程序的容错性(输入的格式的多样性和不确定性)。
实验4-1:
(1)Rectangular1.java——
(2)Rectangular2.java——
说明:在实验3第3题的基础上,分别实现下列5个步骤的要求。
Step1:
为实验3中定义的矩形类派生一个子类:正方形类。正方形类的操作同样是求周长和面积。则这个子类除了从父类继承来的方法之外,还需要定义哪些方法?列出正方形类的所有域与方法。编程验证所编写的正方形类。
在做本本题时原本真对26个字母分别设计了变量,后来进行了优化,运用了数组变量,大大减少了代码量。
实验4-3:
Palindrome.java——
说明:采用递归方法编程,检查一个任意给定的字符串是否是回文。
------------------------------------------------------------
人工智能实验指导书+作业展示
《人工智能技术导论》实验指导书西北工业大学计算机学院目录一实验纲要 (1)二上机要求 (2)三实验内容 (3)实验一图搜索与问题求解 (3)实验1.1 启发式搜索 (3)实验1.2 A*算法搜索 (9)实验1.3 其他应用问题 (12)实验二产生式系统推理 (14)实验三TSP问题的遗传算法实现 (20)四实验报告模板 (27)人工智能实验一实验报告 (27)人工智能实验二实验报告 (28)人工智能实验三实验报告 (29)附件1 TSP问题的遗传算法程序模板 (30)附件2 学生作业作品展示 (35)一实验纲要一实验教学的目的、任务与要求将人工智能基础理论应用于实际问题的解决当中,加深学生对所学知识的理解,提高学生的实际动手能力。
二实验项目内容1图搜索策略实验用启发式搜索方法/A*算法求解重排九宫问题/八数码问题。
2产生式系统的推理以动物识别系统为例,实现基于产生式规则的推理系统。
3 TSP问题的遗传算法实现以N个结点的TSP问题为例,用遗传算法加以求解。
三参考教材人工智能技术导论-第3版,廉师友编著,西安电子科技大学出版社,2007。
四使用主要仪器设备说明在Windows2000/XP上,选用Java/C/C++/Matlab等语言进行实现。
五实验考核实验为12学时,分4次课完成。
每个实验题目在课堂上分别按百分制给出。
其中包括课堂纪律、程序运行结果、课堂回答问题及实验报告成绩等。
实验课总成绩为3个实验题目的平均成绩。
实验课要求学生提前预习,上课时需向辅导老师提交预习报告,报告格式和内容不作过多要求,只需简要说明自己本次实验的大体思想。
预习报告形式不限,电子版或手写版均可。
1 考核方法由各班辅导老师当堂检查源程序和运行结果,并提问相关问题,课堂上给出成绩并记录。
每个题目完成后把源代码和实验报告提交,由辅导老师检查实验报告并给出报告成绩。
2 评分标准每个实验题目根据以下标准进行考核:1)考勤分20分。
模拟法算法设计实验报告(3篇)
第1篇一、实验名称:模拟法算法设计实验二、所属课程名称:算法设计与分析三、学生姓名:[姓名] 学号:[学号] 合作者:[合作者姓名]四、实验日期和地点:[年月日] [实验地点]五、实验目的1. 理解模拟法的基本概念和原理。
2. 掌握模拟法在算法设计中的应用。
3. 提高算法设计和分析能力。
六、实验原理模拟法是一种通过模拟实际问题来设计算法的方法。
它将实际问题抽象为一个模型,然后通过对模型的操作来得到问题的解。
模拟法通常适用于难以直接计算或推导的问题,如随机过程、排队系统等。
七、实验内容1. 确定实验课题:选择一个实际问题作为模拟对象,如随机行走问题、排队系统问题等。
2. 建立模型:根据实际问题,建立相应的数学模型,包括状态变量、转移概率、收益函数等。
3. 设计算法:根据模型,设计模拟算法,包括初始化、模拟过程、结果输出等。
4. 实验验证:通过实际运行模拟算法,验证算法的正确性和效率。
八、实验环境和器材1. 操作系统:Windows 102. 编程语言:Python3. 软件环境:PyCharm九、实验步骤1. 初始化参数:根据实际问题,设定初始参数,如随机行走问题中的初始位置、排队系统中的初始顾客数量等。
2. 模拟过程:a. 根据转移概率,生成下一状态。
b. 记录收益或损失。
c. 更新状态变量。
3. 结果输出:输出模拟结果,包括收益、损失、平均收益等。
4. 优化算法:根据实验结果,对模拟算法进行优化,提高算法效率。
十、实验结果与分析1. 实验结果:(1)随机行走问题模拟结果:- 初始位置:坐标 (0, 0)- 步长:1- 模拟步数:10000- 模拟结果:最终位置坐标 (500, 500)(2)排队系统问题模拟结果:- 初始顾客数量:10- 服务器数量:2- 模拟时间:1000秒- 模拟结果:平均等待时间 20 秒2. 分析:(1)随机行走问题模拟结果表明,模拟算法能够正确模拟随机行走过程,且步长和模拟步数对结果影响较大。
西北工业大学数据结构课程方案实验报告
2018--2018数据结构课程设计实验报告学院:班级:姓名:学号:邮箱:日期:2018年1月17日《数据结构》实验报告◎实验题目:单词<词组)检索◎实验内容:现在有一个英文字典<每个单词都是由小写的'a'-'z'组成),单词量很大,达到100多万的单词,而且还有很多重复的单词。
此外,我们现在还有一些 Document,每个Document 包含一些英语单词。
针对这个问题,请你选择合适的数据结构,组织这些数据,使时间复杂度和空间复杂度尽可能低,并且解决下面的问题和分析自己算法的时间复杂度。
1)基本型问题<必须采用字符串哈希,hash散列算法)<1)将所有的英文单词生成一个字典Dictionary。
<2)给定一个单词,判断这个单词是否在字典Dictionary中。
如果在单词库中,输出这个单词总共出现的次数。
否则输出NO。
<3)输出Dictionary中出现次数最高的10个单词。
<必须采用快速排序或堆排序算法)2)扩展型问题<可选择合适的数据结构)<4)给定一个单词,按字典序输出字典Dictionary 中所有以这个单词为前缀的单词。
例如,如果字典 T={a,aa, aaa, b, ba}, 如果你输入 a,那么输出应该为{a, aa, aaa}。
<5)给定一个单词,输出在Dictionary 中以这个单词为前缀的单词的出现频率最高的10个单词,对于具有相同出现次数的情况,按照最近<即最后)插入的单词优先级比较高的原则输出。
对于以下问题,需采用2种不同的数据结构<hash散列与Trie树,并针对以下题目,比较两种数据结构的优缺点。
)3)高级型问题<6)现在我们有一些Document,每个Document 由一些单词组成,现在的问题就是给你一个word,检索出哪些Document包含这个word,输出这些Document的DocumentID<就如同搜索引擎一样,即输入一些关键字,然后检索出和这些关键字相关的文档)。
西北工业大学-软件-算法实验2Word版
实验二动态规划算法姓名:王智慷学号:2015303118 班级:14011502 一.问题描述小明想要在王者荣耀游戏里晋升一个段位,假设他一共需打了n场比赛,且必须成功赢得至少70%的场次才能成功晋升。
假设每场比赛小明获胜的概率分别为p1,p2,…,p n,请帮他算出成功晋级段位的概率是多少?输入:参数1:整数num(0 ≤num≤ 1000),表示比赛的场数。
参数2:整数数组p[num] = {p1,p2,…,p num},其中p i表示小明有p i%的概率赢得第i场比赛。
(0 ≤p i ≤ 100)输出:成功晋级段位的概率,保留小数点后5位,最后结果四舍五入。
二.实验目的及要求1.理解动态规划法的设计思想2.掌握动态规划法的求解步骤3.掌握用动态规划法解题的算法框架三.实验分析1.分析问题的最优子结构将问题分解为子问题求解:完成到第i局比赛时并赢下j局的概率。
则晋级的概率为,完成所有num局比赛时,赢下0.7*num局到赢下num局的概率之和。
而完成到第i局比赛赢下j局比赛的概率可由完成到第i-1局比赛的概率得出,即,完成到第i-1局比赛时赢下j局并且第i局没有赢、完成第i-1局比赛时赢下j-1局比赛并且第i局赢了,这两者概率之和。
2.建立递归关系ans[i][j] = ans[i-1][0]*(1-pt[i]) (j=0)或ans[i-1][j] * (1-pt[i]) + ans[i-1][j-1] * pt[i] (j>0)四.算法伪代码或流程图for i←1 to num-1 doans[i][0] = ans[i-1][0] * (1-pt[i])for j←1 to i+1 doans[i][j] = ans[i-1][j] * (1-pt[i]) + ans[i-1][j-1] * pt[i]for i←0.7*num to num dopass = pass + ans[num-1][i]五.算法时间复杂性分析两重循环,操作数为1+2+3+4+…+(num+1),所以时间复杂度为O(n2)。
西工大《算法设计与分析B卷》18年10月作业考核(答案)
D大夫比E大夫晚二天值班;
B大夫比G大夫早三天值班;
F大夫的值班日在B和C大夫的中间,且是星期四;
请确定每天究竟是哪位大夫值班?并用计算机实现。
2.编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数求1/1+1/3+...+1/n。(利用指针函数)
西北工业大学网络教育学院
2018年10月大作业
学习中心: 课程名称: 算法设计与分析
考试时间 120分钟 考试形式:大作业 A卷□B卷√
学
号
ห้องสมุดไป่ตู้姓名
考试日期
年 月 日
编程题(C、JAVA、C++等均可)(每小题50分,共100分)
1.医院有A、B、C、D、E、F、G七位大夫,在一星期内(星期一至星期天)每人要轮流值班一天。现在已知:
西北工业大学算法设计与分析试题2017A2
C.问题可以找到最优解,但利用贪心法不能找到最优解
D.每次决策必须是当前看来最优的决策才可以找到最优解
3.在下列算法设计方法中,_B_在求解问题的过程中并不从整体最优上加以考虑,而是做出在当前看来是最好的选择。_B_不能保证求得0/1背包问题的最优解。
A.分治法 B.贪心法 C.动态规划法D.回溯法
{
for(j=1;j<=i;j++)
cin>>s[i][j];
}
for(i=n;i>=2;i--)
for(j=1;j<i;j++)
{
s[i-1][j]+=max(s[i][j],s[i][j+1]);//从下往上找
}
cout<<s[1][1]<<endl;
}
return 0;
}
4.对8个元素的序列A = (9, 4, 5,2, 1, 7, 4, 6)进行从小到大的排序,给出归并排序的基本思想,画出归并排序(递归实现)的求解过程。
姓 名
一、选择题(每题3分,共18分)
1.下面函数中渐进时间最小的是D_。
A.T1(n)=n+nlognB.T2(n)=2n+nlogn
C.T3(n)=n2-lognD.T4(n)=n+100logn
2.采用动态规划策略求解问题的显著特征是满足最优子结构性质,其含义是
_B_。
A.当前所做出的决策不会影响后面的决策
{
Break;
}
}
If(j==i)
{
Isprime[i]==1;
}
}
A[1]=1;
西工大noj答案解析(完整版)
西北工业大学POJ答案绝对是史上最全版(不止100题哦……按首字母排序)1.“1“的传奇2.A+B3.A+BⅡ4.AB5.ACKERMAN6.Arithmetic Progressions7.Bee8.Checksum algorithm9.Coin Test10.Dexter need help11.Double12.Easy problem13.Favorite number14.Graveyard15.Hailstone16.Hanoi Ⅱ17.Houseboat18.Music Composer19.Redistribute wealth20.Road trip21.Scoring22.Specialized Numbers23.Sticks24.Sum of Consecutive25.Symmetric Sort26.The Clock27.The Ratio of gainers to losers28.VOL大学乒乓球比赛29.毕业设计论文打印30.边沿与内芯的差31.不会吧,又是A+B32.不屈的小蜗33.操场训练34.插入链表节点35.插入排序36.插入字符37.成绩表计算38.成绩转换39.出租车费40.除法41.创建与遍历职工链表42.大数乘法43.大数除法44.大数加法45.单词频次46.迭代求根47.多项式的猜想48.二分查找49.二分求根50.发工资的日子51.方差52.分离单词53.分数拆分54.分数化小数55.分数加减法56.复数57.高低交换58.公园喷水器59.韩信点兵60.行程编码压缩算法61.合并字符串62.猴子分桃63.火车站64.获取指定二进制位65.积分计算66.级数和67.计算A+B68.计算PI69.计算π70.计算成绩71.计算完全数72.检测位图长宽73.检查图像文件格式74.奖金发放75.阶乘合计76.解不等式77.精确幂乘78.恐怖水母79.快速排序80.粒子裂变81.链表动态增长或缩短82.链表节点删除83.两个整数之间所有的素数84.路痴85.冒泡排序86.你会存钱吗87.逆序整数88.排列89.排列分析90.平均值函数91.奇特的分数数列92.求建筑高度93.区间内素数94.三点顺序95.山迪的麻烦96.删除字符97.是该年的第几天98.是该年的第几天?99.数据加密100.搜索字符101.所有素数102.探索合数世纪103.特殊要求的字符串104.特殊整数105.完全数106.王的对抗107.危险的组合108.文件比较109.文章统计110.五猴分桃111.小型数据库112.幸运儿113.幸运数字”7“114.选择排序115.寻找规律116.循环移位117.延伸的卡片118.羊羊聚会119.一维数组”赋值“120.一维数组”加法“121.勇闯天涯122.右上角123.右下角124.圆及圆球等的相关计算125.圆及圆球等相关计算126.程序员添加行号127.找出数字128.找幸运数129.找最大数130.整数位数131.重组字符串132.子序列的和133.子字符串替换134.自然数立方的乐趣135.字符串比较136.字符串复制137.字符串加密编码138.字符串逆序139.字符串排序140.字符串替换141.字符串左中右142.组合数143.最次方数144.最大乘积145.最大整数146.最小整数147.最长回文子串148.左上角149.左下角1.“1“的传奇#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){int n,i,j,k=0,x=1,y,z,m,p,q,a,s=0; scanf("%d",&n);m=n;for(i=1;i<12;i++){m=m/10;k++;if(m==0)break;}q=n;k=k-1;for(a=1;a<=k;a++){x=x*10;}y=q%x;z=q/x;p=q-y;if(z>=2)s=s+x+z*k*(x/10);elses=s+z*k*(x/10);for(j=p;j<=n;j++){m=j;for(i=1;i<12;i++) {x=m%10;if(x==1)s++;m=m/10;if(m==0)break;}}printf("%d",s);return 0;}2.A+B#include <stdio.h>int doubi(int n,int m) {n=n+m;n=n%100;return n;}int main(){int t,i,a[100],n,m;scanf("%d",&t);for (i=0;i<=(t-1);i++){ scanf("%d%d",&n,&m); a[i]=doubi(n,m);}for (i=0;i<=(t-1);i++)printf("%d\n",a[i]); return 0;}3.A+BⅡ#include <stdio.h>int main(){int A,B,sum;scanf("%d%d",&A,&B);sum=A+B;printf("%d\n",sum); return 0;}4.AB#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){char s[100],q[100];double a,b,c;int n=0,i;scanf("%lf%lf",&a,&b);c=a*b;sprintf(s,"%.0lf",c);for(i=0;i<strlen(s);i++){n=n+s[i]-48;}while(n>=10){sprintf(q,"%d",n);n=0;for(i=0;i<strlen(q);i++) n=n+q[i]-48;}printf("%d",n);return 0;}5.ACKERMAN#include <stdio.h>#include <stdlib.h>#include <math.h>int ack(int x,int y){int n;if (x==0) {n=y+1;return n;}else if (y==0) n=ack(x-1,1);else n=ack(x-1,ack(x,y-1)); return n;}int main(){int m,b;scanf("%d%d",&m,&b);m=ack(m,b);printf("%d",m);return 0;}6.Arithmetic Progressions#include <stdio.h>#include <stdlib.h>#include <math.h>int g(int n){int i;if(n==1) return 0;if(n==2) return 1;if(n==3) return 1;for(i=2;i<=sqrt(n);i++) if(n%i==0) return 0; return 1;}int f(int a,int b,int c){int i=0,s=a-b;if(c==1&&g(a)==1) return a;if(b==0&&g(a)!=1) return -1;while(1){s=s+b;if(g(s)) i++;if(i>=c) break;}return s;int main(){int a,b,c,d[100],i=0,n;while(1){scanf("%d%d%d",&a,&b,&c); if(a==0&&b==0&&c==0) break; d[i]=f(a,b,c);i++;}n=i;for(i=0;i<n;i++)printf("%d\n",d[i]);return 0;}7.Bee#include <stdio.h>#include <stdlib.h>int main()int A[100],i=0,j,k,female=0,male=1,x; for(;;i++){scanf("%d",&A[i]);if(A[i]==-1)break;}for(j=0;j<i;j++){female=0,male=1;for(k=1;k<A[j];k++){x=female;female=male;male=x+male+1;}printf("%d %d\n",male,female+male+1);}return 0;}8.Checksum algorithm#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){int i,n,t,j;char s[100][100];for(i=0;;i++){gets(s[i]);if(s[i][0]=='#') break;}n=i;for(i=0;i<n;i++){t=0;for(j=0;j<strlen(s[i]);j++)if(s[i][j]==32) t=t;else t=t+(j+1)*(s[i][j]-64);printf("%d\n",t);}return 0;}9.Coin Test#include <stdio.h>#include <stdlib.h>int main(){char A[100000];int n,i=0,a=0,b=0,j; double x;while(1){scanf("%c",&A[i]);if(A[i]=='\n')break;i++;}for(j=0;j<i;j++){if(A[j]=='S'){printf("WA");goto OH;}if(A[j]=='U')a++;if(A[j]=='D')b++;}x=a*1.0/(a+b)*1.0;if(x-0.5>0.003||x-0.5<-0.003) printf("Fail");elseprintf("%d/%d",a,a+b);OH:return 0;}10.Dexter need help#include <stdio.h>int fun(int a){if(a==1) return 1;elsereturn fun(a/2)+1;}int main(){int a,b[100],i=0,j; while(1){scanf("%d",&a);if(a==0)break;b[i]=fun(a);i++;}for(j=0;j<i;j++){printf("%d\n",b[j]); }return 0;}11.Double#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){int a[100],b[100],i,j,n,t=0; for(i=0;;i++){scanf("%d",&a[i]);if(a[i]==0) break;}n=i;for(i=0;i<n;i++)b[i]=2*a[i];for(i=0;i<n;i++)for(j=0;j<n;j++)if(a[i]==b[j]) t++;printf("%d",t);return 0;}12.Easy problem#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){int N,i,n,j=0;scanf("%d",&N);for(i=2;i<N+1;i++){if((N+1)%i==0)j++; }printf("%d",j/2);return 0;}13.Favorite number#include <stdio.h>#include <string.h>#define MAXNUM 100000int prime_number = 0;int prime_list[MAXNUM]; bool is_prime[MAXNUM];int ans[MAXNUM + 2];int dp[MAXNUM + 2];void set_prime() {int i, j;memset(is_prime, 0, sizeof(is_prime));for (i = 2; i < MAXNUM; i++) {if (is_prime[i] == 0) {prime_list[prime_number++] = i;if (i >= MAXNUM / i) continue;for (j = i * i; j < MAXNUM; j+=i) { is_prime[j] = 1;}}}}int main() {int i, j, k,o=0,d[100];memset(dp, -1, sizeof(dp));set_prime();ans[0] = 0;dp[1] = 0;for (i = 1; i <= MAXNUM; i++) {ans[i] = ans[i - 1] + dp[i];if (dp[i + 1] == -1 || dp[i + 1] > dp[i] + 1) {dp[i + 1] = dp[i] + 1;}for (j = 0; j < prime_number; j++) {if (i > MAXNUM / prime_list[j]) break; k = i * prime_list[j];if (dp[k] == -1 || dp[k] > dp[i] + 1) { dp[k] = dp[i] + 1;}}}while (scanf("%d%d", &i, &j) == 2 && (i || j)) { d[o]=ans[j] - ans[i - 1];o++;}for(i=0;i<o;i++)printf("%d\n",d[i]);}14.Graveyard#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){int a[100],b[100],n,i,j;double s,p,l,t;for(i=0;;i++){scanf("%d%d",&a[i],&b[i]);if(a[i]==0&&b[i]==0) break;}n=i;for(i=0;i<n;i++){p=10000;if(b[i]%a[i]==0){printf("0.0000\n");continue;}; t=10000/((double)a[i]);for(j=1;j<a[i]+b[i];j++){l=10000/((double)(a[i]+b[i]));l=t-j*l;l=fabs(l);if(l<p) p=l;}s=(a[i]-1)*p;printf("%.4lf\n",s); }return 0;}15.Hailstone#include <stdio.h>#include <stdlib.h>#include <string.h>int f(int n){int s=1;while(1){if(n==1) return s;else if(n%2==0) n=n/2,s++; else n=3*n+1,s++;}}int main(){int n,m,i,j=0,t;scanf("%d%d",&m,&n);printf("%d %d",m,n);if(m>n) t=m,m=n,n=t;for(i=m;i<=n;i++)if(f(i)>j) j=f(i);printf(" %d",j);return 0;}16.Hanoi Ⅱ#include <stdio.h>#include <stdlib.h>#define M 70int start[M], targe[M];long long f(int *p, int k, int fina) {if(k==0) return 0;if(p[k]==fina) return f(p,k-1,fina);return f(p,k-1,6-fina-p[k])+(1LL<<(k-1));}int main (){long long ans;int n;while(scanf("%d",&n),n){int i;for(i=1;i<=n;i++) scanf("%d",&start[i]);for(i=1;i<=n;i++) scanf("%d",&targe[i]);int c=n;for(;c>=1&&start[c]==targe[c];c--);if(c==0){printf("0\n"); continue;}int other=6-start[c]-targe[c];ans=f(start,c-1,other)+f(targe,c-1,other)+1; printf("%lld\n",ans);}return 0;}17.Houseboat#include <stdio.h>#include <stdlib.h>#include <math.h>#define pi 3.1415926int f(float x,float y){int i;for(i=0;;i++)if(50*i>sqrt(x*x+y*y)*sqrt(x*x+y*y)*pi/2) break;return i;}int main(){int n,i,a[100];float x,y;scanf("%d",&n);for(i=0;i<n;i++){scanf("%f%f",&x,&y);a[i]=f(x,y);}for(i=0;i<n;i++)printf("%d %d\n",i+1,a[i]);return 0;}18.Music Composer19.Redistribute wealth#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){inta[1000],b[1000],n,i,j,s,sum,t,m,mid,c[100],k=0; while(1){scanf("%d",&n);if(n==0) break;{s=0;for(i=1;i<=n;i++){scanf("%d",&a[i]);s=s+a[i];}m=s/n;b[1]=a[1]-m;b[0]=0;for(i=2;i<n;++i)b[i]=b[i-1]+a[i]-m;for(i=0;i<n;i++)for(j=0;j<n-1-i;j++)if(b[j]>b[j+1])t=b[j],b[j]=b[j+1],b[j+1]=t;mid=b[n/2];sum=0;for(i=0;i<=n-1;++i) sum=sum+fabs(mid-b[i]); c[k]=sum;k++;}}for(i=0;i<k;i++) printf("%d\n",c[i]);return 0;}20.Road trip#include <stdio.h>#include <stdlib.h>#include <math.h>int f(int n){int a[100],b[100],i,s;for(i=0;i<n;i++)scanf("%d%d",&a[i],&b[i]); s=a[0]*b[0];for(i=1;i<n;i++)s=s+a[i]*(b[i]-b[i-1]);return s;}int main(){int n,c[100],i=0;while(1){scanf("%d",&n);if(n==-1) break;c[i]=f(n);i++;}n=i;for(i=0;i<n;i++)printf("%d\n",c[i]);return 0;}21.Scoring#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){int i,j,sum,min,c,count,n,a,b; char s1[50],s2[50];scanf("%d",&n);for(i=0;i<n;i++){count=sum=0;scanf("%s",s2);for(j=0;j<4;j++){scanf("%d%d",&a,&b);if(b!=0){sum+=(a-1)*20+b;count++;}}if(i==0){c=count,min=sum;strcpy(s1,s2);}else if(count>c||(count==c&&sum<min)) {min=sum;c=count;strcpy(s1,s2);}}printf("%s %d %d\n",s1,c,min); return 0;}22.Specialized Numbers#include <stdio.h>#include <stdlib.h>int main(){int i,n,sum10,sum12,sum16;for(i=2992;i<3000;i++){n=i;sum10=0;while(n){sum10+=n%10;n/=10;}n=i;sum12=0;while(n){sum12+=n%12;n/=12;}n=i;sum16=0;while(n){sum16+=n%16;n/=16;}if(sum10==sum12&&sum12==sum16) printf("%d\n",i);}return 0;}23.Sticks#include <stdio.h>#include <string.h>#include <stdlib.h>int len[64], n, minlen, get;bool b[64];int cmp(const void *a, const void *b){return *(int *)a < *(int *)b ? 1 : -1;}bool dfs(int nowlen, int nowget, int cnt){if(cnt >= n) return false;if(get == nowget) return true;int i;bool f = false;if(nowlen == 0) f = true;for(i = cnt; i < n; i++){if(!b[i]){if(len[i] + nowlen == minlen) {b[i] = true;if(dfs(0, nowget+1, nowget)) return true;b[i] = false;return false;}else if(len[i] + nowlen < minlen){b[i] = true;if(dfs(nowlen+len[i], nowget, i+1)) return true;b[i] = false;if(f) return false;while(i + 1 < n && len[i] == len[i+1]) i++;}}}return false;}int main(){int i, tollen;while(scanf("%d", &n), n){tollen = 0;int j = 0, p;for(i = 0; i < n; i++){scanf("%d", &p);if(p <= 50){len[j] = p;tollen += len[j];j++;}}n = j;if(n == 0){printf("0\n");continue;}qsort(len, n, sizeof(int), cmp); for(minlen = len[0]; ; minlen++) {if(tollen % minlen) continue; memset(b, 0, sizeof(b));get = tollen / minlen;if(dfs(0, 0, 0)){printf("%d\n", minlen);break;}}}return 0;}24.Sum of Consecutive#include <stdio.h>#include <stdlib.h>#include <string.h>int len[64],n,minlen,get;int b[64];int cmp(const void *a,const void *b){return *(int *)a<*(int *)b?1:-1;}int dfs(int nowlen,int nowget,int cnt){if(cnt>=n) return 0;if(get==nowget) return 1;int i,f=0;if(nowlen==0) f=1;for(i=cnt;i<n;i++){if(len[i]+nowlen==minlen){b[i]=1;if(dfs(0,nowget+1,nowget)) return 1;b[i]=0;return 0;}else if(len[i]+nowlen<minlen){b[i]=1;if(dfs(nowlen+len[i],nowget,i+1)) return 1;b[i]=0;if(f) return 0;while(i+1<n&&len[i]==len[i+1]) i++;}}return 0;}int main(){int i,tollen,q=0,c[100];while(scanf("%d",&n),n){tollen=0;int j=0,p;for(i=0;i<n;i++){scanf("%d",&p);if(p<=50){len[j]=p;tollen+=len[j];j++;}}n=j;if(n==0){printf("0\n");continue;}qsort(len,n,sizeof(int),cmp); for(minlen=len[0];;minlen++){if(tollen%minlen) continue; memset(b,0,sizeof(b));get=tollen/minlen;if(dfs(0,0,0)){c[q]=minlen;q++;break;}}}for(i=0;i<q;i++)printf("%d\n",c[i]);return 0;}25.Symmetric Sort#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){double A[100];int i=0,j=0,k=0,l=0,sum=0; while(1){scanf("%lf",&A[i]);if(A[i]==0)break;i++;}for(j=0;j<i;j++){if(A[j]==2)printf("1\n");else{int B[10000],m=1,number=0;double n;B[0]=2;for(k=3;k<=A[j];k+=2){n=(double)k;for(l=2;l<=sqrt(n);l++){if(k%l==0)goto ai;}B[m]=k;m++;ai:;}for(k=0;k<m;k++){sum=0;for(l=k;l<m;l++){sum+=B[l];if(sum==A[j]){number++;break;}}}printf("%d\n",number);}}return 0;}26.The Clock#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){char s[100][100],a[100];int i,j,n;scanf("%d",&n);for(i=0;i<n;i++) scanf("%s",s[i]);for(i=0;i<n-1;i++)for(j=0;j<n-1-i;j++)if(strlen(s[i])>strlen(s[i+1]))strcpy(a,s[i]),strcpy(s[i],s[i+1]),strcpy(s[i+1],a) ;if(n%2==0){for(i=0;i<n-1;i=i+2) printf("%s ",s[i]);printf("%s ",s[n-1]);for(i=i-3;i>0;i=i-2) printf("%s ",s[i]);}else{for(i=0;i<n-1;i=i+2) printf("%s ",s[i]); printf("%s ",s[n-1]);for(i=i-1;i>0;i=i-2) printf("%s ",s[i]); }return 0;}27.The Ratio of gainers to losers#include<stdio.h>int main(){char s[5];int i,sum=0;gets(s);for(i=0;s[i]!='\0';i++){switch(s[i]){case'I': sum+=1;break;case'V': sum=5-sum;break; case'X':sum=10-sum;break; }}printf("%d\n",sum);return 0;}28.VOL大学乒乓球比赛#include <stdio.h>#include <stdlib.h>int main(){printf("A=Z\nB=X\nC=Y\n"); return 0;}29.毕业设计论文打印#include <stdio.h>#include <stdlib.h>int main(){int a[100],j=1,i,n,m;scanf("%d%d",&n,&m);for(i=0;i<n;i++)scanf("%d",&a[i]);for(i=0;i<n;i++)if(a[i]>a[m]) j++;printf("%d",j++);return 0;}30.边沿与内芯的差#include <stdio.h>#include <stdlib.h>int main(){int A[100][100],i,j,m,n,s=0,t=0; scanf("%d%d",&n,&m);for(i=1;i<=n;i++){for(j=1;j<=m;j++){scanf("%d",&A[i][j]);。
西北工业大学算法设计实验2
实验二:回溯法VS分支定界法一、问题分析回溯法可以处理货郎担问题,分支定界法也可以处理货郎担问题,回溯法和分支定界法哪个算法处理货郎担问题效率更高呢?实现回溯法、分支定界法,以及不同的界值函数(课上讲过的或者自己新设计的),通过随机产生10 个不同规模的算例(城市数量分别为10,20,40,80,100,120,160,180,200,500,或者其它规模),比较回溯法和分支定界法在相同界值函数下的执行效率。
另外,分别比较回溯法和分支定界法在不同界值函数下的执行效率。
二、算法基本思想1、回溯法从初始状态出发,搜索其所能到达的所有“状态” ,当一条路走到尽头,再后退一步或若干步,从另外一种状态出发,继续搜索,直到所有的路径都搜索过。
这种不断前进、不断回溯寻找解的方法叫回溯法。
回溯法通常将问题解空间组织成“树”结构,采用系统的方法搜索解空间树,从而得到问题解。
搜索策略:深度优先为主,也可以采用广度优先、函数优先、广度深度结合等。
避免无效搜索策略:约束函数:在扩展结点处剪去不满足约束条件的子树界限函数:在扩展结点处剪去得不到最优解的子树2、分支限界法分支界限法类似与回溯法,也是在问题解空间中搜索问题解的一种算法。
分支界限法与回溯法思想对比:求解目标:回溯法的可以用于求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标通常是找出满足约束条件的一个解或最优解。
搜索方式的不同:回溯法主要以深度优先的方式搜索解空间树,而分支限界法则主要以广度优先或以最小耗费优先的方式搜索解空间树。
在分支限界法中,每个活结点只有一次机会成为扩展结点。
一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
三、算法设计1、回溯法TSP问题的目的是得到一条路径,即一个解向量 ( X1,X2...Xn ),为排列树问题。
西工大计算机实习报告
计算机实习报告一、趣味题彩色的圆环:分析图形可知,一共有n个同心圆,外面大圆n等分,然后从每个等分点作所有同心圆的两条切线。
如果用极坐标表示,可以很容易求解切点,代码如下所示:n=10; %同心圆数量m=40; %等分点数R=1; %外圆半径s=0:0.01*pi:2*pi; %控制圆的光滑程度的极坐标角度t=0:2*pi/m:2*pi; %等分点极坐标角度x0=R*cos(t);y0=R*sin(t); %等分点直角坐标color=['b','r','c','g','m','y']; %画图颜色lc=length(color); %颜色数量长度,超出后从头开始for i=1:n %开始同心圆循环r=R/n*i; %当前同心圆半径a=acos(r/R); %切线与圆心线角度(弧度制)x1=r*cos(t-a);y1=r*sin(t-a); %任意等分点相对当前同心圆的第一个切点x2=r*cos(t+a);y2=r*sin(t+a); %任意等分点相对当前同心圆的第二个切点plot(r*cos(s),r*sin(s),color(mod(i,lc)+1));hold on; %画同心圆for j=1:m %对每一个等分点循环plot([x0(j),x1(j)],[y0(j),y1(j)],color(mod(i,lc)+1));hold on;%第一条切线plot([x0(j),x2(j)],[y0(j),y2(j)],color(mod(i,lc)+1)); hold on; %第二条切线endendaxsi equal; %横纵坐标比例一致实验绘图结果如下图所示:二、算法题求无向图的最短路径(Dijkstra算法):实验原理分析、原理及代码如下所示(此实验代码不仅包含了实验所要求的求带权无向图最短路径,我还拓展了求有向、无向、带权有向图最短路径的内容):#include<iostream>#include<iomanip>using namespace std;#define wuqiong 0class tu{public:int chazhao(int);//查找void zjdingdian(int x);//增加顶点tu();void zengjia();//控制增加弧边和点void zjhubian();//增加弧边void bianli();//控制遍历void shendu(int );//深度void guangdu(int );//广度void jindui(int );//进队列int chudui();//出对了bool pankong();//判空//上面所有的函数与邻接矩阵有关void zxgouzao();//初始化与最小路劲有关的东东void zxshuchu();//求S中的最小路劲private:int kind; //类图;int length; // 顶点个数int *dingdian; //顶点int *juzhen; //矩阵int num;//最大顶点数目int* visted;//访问情况int *duilie;//模拟队列int duichang;//队列长度//上面所有的变量与邻接矩阵有关int *s;//存放当前顶点int slength;//当前顶点的长度int* dist;//存放最小路劲int* pre;//存放路劲;int* final;//存放顶点};tu::tu()//初始化图{cout<<"请输入图的种类1:有向.2:无向.3:带权有向.4:带权无向"<<endl;//图的种类cin>>kind;cout<<"请输入图的顶点数目"<<endl;//为顶点赋值cin>>num;dingdian = new int[num];//为顶点分配内存保存juzhen = new int[num*num];//产生矩阵if(kind==1||kind==2)//为无权图初始化矩阵{for(int i =0;i<num*num;i++)juzhen[i] = 0;}else//有权图初始化矩阵{for(int i =0;i<num*num;i++)juzhen[i] = wuqiong;}length = 0;}//增加顶点void tu::zjdingdian(int x){if(chazhao(x)!=-1||length==num)cout<<"图内有此顶点或图内无空间可插入,插入失败"<<endl;else{dingdian[length] = x;length++;}}//增加边void tu::zjhubian(){int i;//弧头int j;//弧尾if(kind==1||kind==2)//无权图{cout<<"请输入弧的头和尾"<<endl;cin>>i>>j;if(kind == 1)//有向图{juzhen[i*num+j]=1;}else//无向图,两边同时取值{juzhen[i*num+j]=1;juzhen[j*num+i]=1;}}else//权值,同上,将1改为K(权值)即可{int k;cin>>i>>j>>k;if(kind == 3){juzhen[i*num+j]=k;}else{juzhen[i*num+j]=k;juzhen[j*num+i]=k;}}}//查找,将该数所在位置返回,若无则返回-1int tu::chazhao(int x){for(int i =0;i<length;i++)if(x == i)return i;return -1;}//控制遍历函数void tu::bianli()//遍历函数{cout<<"该图的邻接矩阵为:";int i;int j;for(i =0;i<length;i++)//将矩阵输出{cout<<endl;for(j=0;j<length;j++)cout<<setw(6)<<juzhen[i*length+j]<<" ";}cout<<endl;visted = new int[length];//为设置访问状态定义内存空间cout<<"深度搜索:";for(i =0;i<length;i++)//全部初始化为0即未访问状态visted[i]=0;shendu(0);//将0作为0点运用深度访问函数cout<<endl;cout<<"广度搜索:";for(i =0;i<length;i++)//重新设置访问状态visted[i]=0;duilie = new int[length+1];duilie[0]=-1;//队列初始化duichang = 0;guangdu(0);//将0作为0点运用广度访问函数}//深度遍历void tu::shendu(int x)//采用递归的手法{int p;visted[x] = 1;//访问后置1防止重复访问cout<<x<<" ";p = x*length+1;while(p%length!=0){if(juzhen[p]!=0&&visted[p%length]!=1) shendu(p%length);p++;}}//广度遍历void tu::guangdu(int x){int p;visted[x] = 1;cout<<x<<" ";p = length*x+1;while(p%length!=0)//没有遍历属于根节点的后代的所有兄弟结点加入到队列中(这样可以先进先出,后来的子代加入后也是先输出父亲结点){if(juzhen[p]!=0&&visted[p%length]!=1){visted[p%length] = 1;//判断是否已经加入队列或访问jindui(p%length);}p++;//进行下一个判断}while(pankong())//加入所有的子代兄弟节点后现在出队列并且访问,访问的方式一致会访问后优先加入其子代结点然后出队列访问{guangdu(chudui());}}//进队列,在队头插入一个函数,这个出队入队为了广度输出void tu::jindui(int x){duilie[duichang+1] = -1;duilie[duichang] = x;duichang++;}//出队列,将队列中的最后一个数返回int tu::chudui(){int j;j = duilie[0];for(int i=0;i<duichang;i++)duilie[i] = duilie[i+1];duichang--;return j;}//判空函数,函数为空的时候返回0bool tu::pankong(){if(duichang == 0)return false;elsereturn true;}//控制增加函数void tu::zengjia(){int j ;for(int i =0;i<num;i++)//插入顶点zjdingdian(i);cout<<"请输入需要增加的弧数(最少"<<num-1<<"条且保证连通)"<<endl;//插入弧cin>>j;cout<<"请输入弧的头和尾和权值"<<endl;for(i=0;i<j;i++){//cout<<"插入第"<<i+1<<"条弧"<<endl;zjhubian();}}/***算法思想:依次递增序列求出最小路劲,首先将顶点加入到S当中(本程序默认为0号顶点),然后用dist数组保存到每一个顶点的最小路径长度**dist起始为顶点到其他顶点的权值(到自身为0,到无弧顶点为无穷大)**1:然后每次取v0-vk(k属于V-S)最小的路劲长度,取完之后将Vk加入S当中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二:回溯法VS分支定界法一、问题分析回溯法可以处理货郎担问题,分支定界法也可以处理货郎担问题,回溯法和分支定界法哪个算法处理货郎担问题效率更高呢?实现回溯法、分支定界法,以及不同的界值函数(课上讲过的或者自己新设计的),通过随机产生10个不同规模的算例(城市数量分别为10,20,40,80,100,120,160,180,200,500,或者其它规模),比较回溯法和分支定界法在相同界值函数下的执行效率。
另外,分别比较回溯法和分支定界法在不同界值函数下的执行效率。
二、算法基本思想1、回溯法从初始状态出发,搜索其所能到达的所有“状态”,当一条路走到尽头,再后退一步或若干步,从另外一种状态出发,继续搜索,直到所有的路径都搜索过。
这种不断前进、不断回溯寻找解的方法叫回溯法。
回溯法通常将问题解空间组织成“树”结构,采用系统的方法搜索解空间树,从而得到问题解。
搜索策略:深度优先为主,也可以采用广度优先、函数优先、广度深度结合等。
避免无效搜索策略:约束函数:在扩展结点处剪去不满足约束条件的子树界限函数:在扩展结点处剪去得不到最优解的子树2、分支限界法分支界限法类似与回溯法,也是在问题解空间中搜索问题解的一种算法。
分支界限法与回溯法思想对比:求解目标:回溯法的可以用于求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标通常是找出满足约束条件的一个解或最优解。
搜索方式的不同:回溯法主要以深度优先的方式搜索解空间树,而分支限界法则主要以广度优先或以最小耗费优先的方式搜索解空间树。
在分支限界法中,每个活结点只有一次机会成为扩展结点。
一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
三、算法设计1、回溯法TSP问题的目的是得到一条路径,即一个解向量(X1,X2...Xn),为排列树问题。
对所有城市进行编号后,按大小顺序存储于数组path中,构造一个交换函数swap();对数组path进行遍历,判断当前城市与目标城市是否连通,若连通,通过swap函数对当前节点和目标城市进行交换,即树的节点拓展。
若不连通则恢复,并进入下一次的循环,循环到叶子节点时,判断叶是否与初始节点相连,并计算代价cost是否小于当前最小代价bestc,若小于,则更新bestc,再返回上一节点,知道遍历完树中的所有节点。
2、分支限界法因为问题是经典的TSP问题,所以确定问题的解空间树为排列树。
问题解的表示:可以将问题的解表示成一个n元式 [x1,x2,…,xn]。
使用优先级队列实现最小耗费优先求解。
界函数的确定:首先利用贪心的方法获得一个较优的上界。
对于当前路径下的扩展的过程中,每一步需要存储的当前的结点的下界。
其中的第二部分需要计算的是当前路径的起始结点以及终止结点各自与仍未访问过的结点中的结点只存存在的最小代价。
结点的扩展过程如下:根据优先级从队列中选取优先级最高的元素,当结点不是叶子结点的父节点时,扩展该结点的所有子节点,在扩展的过程中需要根据计算所得的下界与当前求解得到的最优解进行对比,如果下界大于当前的最优解则对相应的子节点时进行剪枝处理,否则扩展该子节点,将其加入到队列中。
当当前所访问的结点为叶子结点的父节点时,判断当前费用+当前结点到叶子结点的费用+叶子结点到起始结点的费用之和是否优于最优解,如果是则更新最优解,并将当前的解加入到队列中。
如果不是则继续取队列中的元素进行扩展。
但取出的元素为叶子节点或者队列中的元素为空的时候,则搜索结束,输出当前的最优解。
四、算法实现1、回溯法核心代码:public void backtrack(int depth){//depth深度if(depth==size){if(map[path[depth-1]][path[depth]] != -1 &&map[path[depth]][path[1]]!= -1&& cost +map[path[depth]][path[1]]<bestc){bestp=path.clone();bestc = cost + map[path[depth]][path[1]];//bestc = cost +a[path[i-1]][path[i]]+a[path[i]][path[1]];//重复计算了上一边}}else{for(int j =depth;j<=size;j++){if(map[path[depth]][path[j]]!=-1){swap(path,depth+1,j);cost +=map[path[depth]][path[depth+1]];//System.out.println(Arrays.toString(x)+":"+cost);backtrack(depth+1);cost -=map[path[depth]][path[depth+1]];swap(path,depth+1,j);}}}}2、分支限界法核心代码:public float fzxj(int[]m){int n=m.length-1;//节点数LinkedList<TSPnode>heap=new LinkedList<TSPnode>();//minOut[i]=i的最小出边费用float[]minOut=new float[n+1];float minSum=0;//最小出边费用和for(int i=1;i<=n;i++){//针对每个节点,找到最小出边//计算minOut[i]和minSumfloat min=Float.MAX_VALUE;for(int j=1;j<=n;j++){if(map[i][j]<Float.MAX_VALUE&&map[i][j]<min)min=map[i][j];}if(min==Float.MAX_VALUE)return Float.MAX_VALUE;minOut[i]=min;minSum+=min;}//初始化int[]x=new int[n];for(int i=0;i<n;i++)x[i]=i+1;TSPnode enode=new TSPnode(0,0,minSum,0,x);float bestc=Float.MAX_VALUE;//搜索排列空间树while(enode!=null&&enode.p<n-1){//非叶节点x=enode.path;if(enode.p==n-2){//当前扩展结点是叶节点的父节点//再加两条边构成回路//所构成回路是否优于当前最优解if(map[x[n-2]][x[n-1]]!=-1&&map[x[n-1]][1]!=-1&&enode.cost+ map[x[n-2]][x[n-1]]+map[x[n-1]][1]<bestc){//找到费用更小的回路bestc=enode.cost+map[x[n-2]][x[n-1]]+map[x[n-1]][1];enode.cost=bestc;enode.lcost=bestc;enode.p++;heap.add(enode);Collections.sort(heap);}}else{//内部结点//产生当前扩展结点的儿子结点for(int i=enode.p+1;i<n;i++){if(map[x[enode.p]][x[i]]!=-1){//可行儿子结点float cc=enode.cost+map[x[enode.p]][x[i]];float rcost=enode.rcost=minOut[x[enode.p]];float b=cc+rcost;//下界if(b<bestc){//子树可能含有最优解,结点插入最小堆int[]xx=new int[n];for(int j=0;j<n;j++)xx[j]=x[j];xx[enode.p+1]=x[i];xx[i]=x[enode.p+1];TSPnode node=newTSPnode(b,cc,rcost,enode.p+1,xx);heap.add(node);Collections.sort(heap);}}}}//取下一个扩展结点enode=heap.poll();}//将最优解复制到v[1...n]for(int i=0;i<n;i++)m[i+1]=x[i];return bestc;}五、算法复杂性理论分析1、回溯法TSP问题是排列树问题,因而该算法的时间复杂度为O(n!)。
2、分支限界法TSP问题是排列树问题,在分支限界法界函数无法剪枝时有最坏情况时间复杂性为O(n!),但通过界函数剪枝可以使复杂度下降。
六、算法代码(单独文件提交)见项目文件七、算法测试(报告只写测试方法与用例设计方法与结果,测试程序单独提交)八、实验中的问题总结回溯法:优点:可以快速的找到一组解,并在此基础之上进行调整。
当搜索完解空间时便可以得到所有的解。
缺点:需要搜索大量的结点,存在一定的盲目性,而且随着结点的个数不断地增加之后,解空间按照阶乘的增长速度递增,因而算法效率较低。
分支限界法:优点:分支限界法采用采用价值队列优先的方式进行搜索,具有一定的目的性。
同时利用贪心算法得到的一个上界,以及设定当前路径下的下界函数。
通过设置界函数进行剪枝,提高算法的效率。
缺点:复杂性高,上下界设计困难。