算法课设报告--14060205133

合集下载

算法设计与分析课程报告

算法设计与分析课程报告

算法设计与分析课程报告第一章算法问题求解基础1、算法的概念:算法是指解决问题的一种方法或过程,是由若干条指令组成的有穷序列。

2、算法的特性①有穷性:一个算法必须保证执行有限步之后结束;②确切性:算法的每一步骤必须有确切的定义;③输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件;④输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。

没有输出的算法是毫无意义的;⑤可行性:算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成3、算法与程序的关系:区别:程序可以不一定满足可终止性。

但算法必须在有限时间内结束;程序可以没有输出,而算法则必须有输出;算法是面向问题求解的过程描述,程序则是算法的实现。

联系:程序是算法用某种程序设计语言的具体实现;程序可以不满足算法的有限性性质。

4、算法描述方式:自然语言,流程图,伪代码,高级语言。

第二章算法分析基础1、算法复杂性分析:算法复杂性的高低体现运行该算法所需计算机资源(时间,空间)的多少。

算法复杂性度量:期望反映算法本身性能,与环境无关。

理论上不能用算法在机器上真正的运行开销作为标准(硬件性能、代码质量影响)。

一般是针对问题选择基本运算和基本存储单位,用算法针对基本运算与基本存储单位的开销作为标准。

算法复杂性C依赖于问题规模N、算法输入I和算法本身A。

即C=F(N, I, A)。

第五章分治法1、递归算法:直接或间接地调用自身的算法。

用函数自身给出定义的函数称为递归函数。

注:边界条件与递归方程是递归函数的二个要素。

实例:①阶乘函数;②Fibonacci数列;③Ackerman函数;④排列问题;⑤整数划分问题;⑥Hanoi塔问题优缺点:①优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。

②缺点:递归算法的运行效率低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

算法与数据结构课程设计 报告

算法与数据结构课程设计 报告

算法与数据结构课程设计报告课程设计题目:图的基本操作及应用数据结构课程设计是在学完数据结构课程之后的实践教学环节。

本实践教学是培养学生数据抽象能力,进行复杂程序设计的训练过程。

要求学生能对所涉及问题选择合适的数据结构、存储结构及算法,并编写出结构清楚且正确易读的程序,提高程序设计基本技能和技巧。

一.设计目的1.提高数据抽象能力。

根据实际问题,能利用数据结构理论课中所学到的知识选择合适的逻辑结构以及存储结构,并设计出有效解决问题的算法。

2.提高程序设计和调试能力。

学生通过上机实习,验证自己设计的算法的正确性。

学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。

3.初步了解开发过程中问题分析、整体设计、程序编码、测试等基本方法和技能。

二.设计任务设计一个基于DOS菜单的应用程序。

要利用多级菜单实现各种功能。

内容如下:1.无向图的基本操作及应用①创建无向图的邻接矩阵②创建无向图的邻接表③无向图的深度优先遍历④无向图的广度优先遍历2.有向图的基本操作及应用①创建有向图的邻接矩阵②创建有向图的邻接表③拓扑排序3.无向网的基本操作及应用①创建无向网的邻接矩阵②创建无向网的邻接表③求最小生成树4.有向网的基本操作及应用①创建有向网的邻接矩阵②创建有向网的邻接表③关键路径④单源最短路径三.设计指导第一步:根据设计任务,设计DOS菜单。

第二步:设计菜单(c语言)#include<stdio.h>void ShowMainMenu(){printf("\n");printf("**************图的基本操作及应用***************\n");printf("* 1 无向图的基本操作及应用*\n");printf("* 2 有向图的基本操作及应用*\n");printf("* 3无向网的基本操作及应用*\n");printf("* 4有向网的基本操作及应用*\n");printf("* 5退出\n");printf("***********************************************\n"); }void UDG(){int n;do{printf("\n");printf("**************无向图的基本操作及应用***************\n");printf("* 1创建无向图的邻接矩阵*\n");printf("* 2创建无向图的邻接表*\n");printf("* 3无向图的深度优先遍历*\n");printf("* 4无向图的广度优先遍历*\n");printf("* 5退出\n");printf("***********************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("----------wait-------");break;case 2:printf("----------wait-------");break;case 3:printf("----------wait-------");break;case 4:printf("----------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void DG(){int n;do{printf("\n");printf("************** 有向图的基本操作及应用***************\n"); printf("* 1创建有向图的邻接矩阵*\n");printf("* 2创建有向图的邻接表*\n");printf("* 3拓扑排序*\n");printf("* 4退出*\n");printf("*******************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("--------wait-------");break;case 2:printf("--------wait-------");break;case 3:printf("--------wait-------");break;case 4:break;default:printf("ERROR!");}}while(n!=4);}void UDN(){int n;do{printf("\n");printf("**************无向网的基本操作及***\n");printf("* 1创建无向网的邻接矩阵*\n");printf("* 2创建无向网的邻接表*\n");printf("* 3Prim算法求最小生成树*\n");printf("* 4kraskal算法求最小生成树*\n");printf("* 5退出\n");printf("*************************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");break;case 2:printf("-------wait-------");break;case 3:printf("---------wait-------");break; case 4:printf("---------wait-------");break; case 5:break;default:printf("ERROR!");}}while(n!=5);}void DN(){int n;do{printf("\n");printf("**************有向网的基本操作****\n");printf("* 1创建有向网的邻接矩阵*\n");printf("* 2创建有向网的邻接表*\n");printf("* 3关键路径*\n");printf("* 4单源顶点最短路径问题*\n");printf("* 5退出\n");printf("***********************************\n"); printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");break;case 2:printf("---------wait-------");break;case 3:printf("---------wait-------");break;case 4:printf("---------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void main(){int n;do{ShowMainMenu();printf("请选择:");scanf("%d",&n);switch(n){case 1:UDG();break;case 2:DG();break;case 3:UDN();break;case 4:DN();break;case 5:break;default:printf("ERROR!");break;}}while(n!=5);}第三步:添加功能函数。

算法课设实验报告(3篇)

算法课设实验报告(3篇)

第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。

为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。

二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。

1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。

(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。

- 对每种算法进行时间复杂度和空间复杂度的分析。

- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。

(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。

- 编写三种排序算法的代码。

- 分析代码的时间复杂度和空间复杂度。

- 编写测试程序,生成随机测试数据,测试三种算法的性能。

- 比较三种算法的运行时间和内存占用。

2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。

(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。

- 分析贪心算法的正确性,并证明其最优性。

(3)实验步骤:- 分析活动选择问题的贪心策略。

- 编写贪心算法的代码。

- 分析贪心算法的正确性,并证明其最优性。

- 编写测试程序,验证贪心算法的正确性。

3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。

(2)实验内容:- 实现一个动态规划算法问题,如背包问题。

- 分析动态规划算法的正确性,并证明其最优性。

(3)实验步骤:- 分析背包问题的动态规划策略。

- 编写动态规划算法的代码。

- 分析动态规划算法的正确性,并证明其最优性。

- 编写测试程序,验证动态规划算法的正确性。

三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。

算法设计课程报告

算法设计课程报告

《算法设计》课程报告课题名称:算法设计课程报告课题负责人名(学号):郑雪云1143041469 同组成员名单(角色):指导教师:郭际香评阅成绩:评阅意见:提交报告时间:2014年 6 月 17 日1.自然合并排序#include <iostream.h>const int N=100;////////////////////////////////////////void ScanTarget(int target[], int n, int head[], int tail[]); int CountHead(int head[]);void MergeSort(int a[], int head[], int tail[], int m);void MergePass(int x[], int y[], int s, int a[], int b[], int m);void Merge(int c[], int d[], int l, int m, int r);//////////////////////////////////////void main(){char a;do{int target[N],head[N],tail[N];int i=0,n,m;for(; i<N; i++){head[i]=-1;tail[i]=-1;}cout<<"请输入要排序的总数:"<<endl;cin>>n;cout<<"请输入要排序的数列:" <<endl;for(i=0; i<n; i++)cin>>target[i];ScanTarget(target,n,head,tail);m=CountHead(head);MergeSort(target,head,tail,m);cout<<"排序后:"<<endl;for(i=0; i<n; i++)cout<<target[i]<<" ";cout<<endl;cout<<"是否继续(y/n):"<<endl;cin>>a;}while(a!='n' && a!='N');}/////////*******函数实现*********////////////////////////////************************///////////////////void ScanTarget(int target[], int n, int head[], int tail[])//扫描待排数组;{int i,j=0,k=0;head[k]=0;k++;for(i=1;i<n;i++){if(target[i-1]>target[i]){tail[j++]=i-1;head[k++]=i;}}tail[j]=n-1;}/////////int CountHead(int head[])//求长度;{int i(0);while(head[i]!=-1){i++;}return i;}/////////////////////void MergeSort(int a[], int head[], int tail[], int m) {int b[N];int s=1;while(s<m){MergePass(a,b,s,head,tail,m);s+=s;MergePass(b,a,s,head,tail,m);s+=s;}}//////////////////void MergePass(int x[], int y[], int s, int a[], int b[], int m){int i=0;while(i <= m-2*s){Merge(x,y,a[i],b[i+s-1],b[i+2*s-1]);i=i+2*s;}if(i+s < m){Merge(x,y,a[i],b[i+s-1],b[m-1]);}else{for(int j=i; j<m; j++)for(int k=a[j]; k<=b[j]; k++)y[k]=x[k];}}///////////////void Merge(int c[], int d[], int l, int m, int r) {int i,j,k;i=l;j=m+1;k=l;while((i<=m) && (j<=r)){if( c[i] <= c[j] )d[k++]=c[i++];else d[k++]=c[j++];}if( i>m ){for(int q=j; q<=r; q++)d[k++]=c[q];}else{for(int q=i; q<=m; q++)d[k++]=c[q];}}/////////*****程序end*****////////////////////////////////////////////////////////////2.AckermannAckermann(m, n)1. if A[m,n] >= 02. then return A[m, n];3. else if m = 0 and n > 04. then A[m,n] <- n + 1;5. else if n = 0 and m > 06. then A[m,n] <- Ackermann(m-1, 1);7. else if n > 0 and m > 08. then A[m,n] <- Ackermann(m-1, Ackermann(m, n-1));9. return A[m, n];Ackermann函数A(m,n)可递归定义如下:当m=0时,A(m,n)=n+1当m>0,n=0时,A(m,n)=A(m-1,1)当m>0,n>0时,A(m,n)=A(m-1,A(m,n-1))试设计一个计算A(m,n)的动态规划算法,该算法只占用O(m)空间。

算法设计实验报告

算法设计实验报告

算法设计实验报告一、实验目的本次算法设计实验的主要目的是通过实际操作和分析,深入理解算法的原理和应用,提高解决实际问题的能力,培养创新思维和逻辑推理能力。

二、实验环境本次实验使用的编程语言为 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. 理论学习(1)回顾了算法的基本概念,包括算法、算法复杂度、时间复杂度和空间复杂度等。

(2)学习了常用的算法设计方法,如分治法、动态规划、贪心算法、回溯法等。

(3)了解了不同算法的应用场景和适用范围。

2. 实验操作(1)使用C++语言实现了多种算法,如快速排序、归并排序、二分查找、插入排序等。

(2)针对实际问题,设计了相应的算法,如矩阵链相乘、背包问题、最小生成树等。

(3)对实验结果进行了分析,对比了不同算法的性能。

3. 实践应用(1)以小组为单位,针对实际问题进行算法设计,如数字三角形、投资问题等。

(2)编写程序代码,实现所设计的算法。

(3)对程序进行调试和优化,提高算法效率。

三、实训成果1. 提高了算法设计能力:通过实训,我们掌握了多种算法设计方法,能够根据实际问题选择合适的算法。

2. 增强了编程能力:实训过程中,我们熟练掌握了C++编程语言,提高了编程技巧。

3. 深化了算法分析能力:通过对算法复杂度的分析,我们能够更好地理解算法性能。

4. 培养了团队合作精神:在实训过程中,我们学会了与他人沟通、协作,共同完成任务。

四、实训总结1. 实训过程中,我们遇到了许多困难,如算法设计思路不明确、编程错误等。

通过查阅资料、请教老师和同学,我们逐步克服了这些问题。

2. 实训过程中,我们认识到算法设计的重要性。

一个好的算法可以显著提高程序运行效率,解决实际问题。

3. 实训过程中,我们学会了如何将实际问题转化为数学模型,并设计相应的算法。

4. 实训过程中,我们提高了自己的自学能力和解决问题的能力。

算法设计 课程设计报告

算法设计 课程设计报告

《算法设计与分析》1什么是算法?算法的特征有哪些?根据我自己的理解,算法是解决问题的方法步骤。

比如在解决高数问题的时候,可以分步骤进行解答,在编程的过程算法可以得到最好的体现。

算法是一系列解决问题的清晰指令,因为我最近在考研复习,对于会的题目还有进行多次的巩固,但是一步步的写很浪费时间,所以我只是写出关键指令,比如化简通分,洛必达法则,上下同阶。

这样可以提高效率。

算法的指令也是同样的。

能够对一定规范的输入,在有限时间内获得所要求的输出。

一个算法的优劣可以用空间复杂度与时间复杂度来衡量。

2若给定某一算法,一般如何对其分析与评价?一个算法的复杂性的高低体现在运行该算法所需要的计算机资源的多少上面,所需的资源越多,我们就说该算法的复杂性越高;反之,所需的资源越低,则该算法的复杂性越低。

计算机的资源,最重要的是时间和空间(存储器)资源。

算法的复杂性有时间复杂性和空间复杂性之分。

1.时间复杂性:例1:设一程序段如下(为讨论方便,每行前加一行号)(1) for i:=1 to n do(2) for j:=1 to n do(3) x:=x+1......试问在程序运行中各步执行的次数各为多少?解答:行号次数(频度)(1) n+1(2) n*(n+1)(3) n*n可见,这段程序总的执行次数是:f(n)=2n2+2n+1。

在这里,n可以表示问题的规模,当n趋向无穷大时,如果f(n)的值很小,则算法优。

作为初学者,我们可以用f(n)的数量级O来粗略地判断算法的时间复杂性,如上例中的时间复杂性可粗略地表示为T(n)=O(n2)。

2.空间复杂性:例2:将一一维数组的数据(n个)逆序存放到原数组中,下面是实现该问题的两种算法:算法1:for i:=1 to n dob[i]:=a[n-i+1];for i:=1 to n doa[i]:=b[i];算法2:for i:=1 to n div 2 dobegint:=a[i];a[i]:=a[n-i-1];a[n-i-1]:=tend;算法1的时间复杂度为2n,空间复杂度为2n算法2的时间复杂度为3*n/2,空间复杂度为n+1显然算法2比算法1优,这两种算法的空间复杂度可粗略地表示为S(n)=O(n)3、从下面算法策略中自选一组,结合某具体问题的求解来介绍算法思想,并加以总结、比较:递归与分治、动态规划与贪心法、回溯法与分支限界法动态规划算法类似于分治法,基本思想也是将待求解问题分解成若干个子问题。

常见算法设计实验报告(3篇)

常见算法设计实验报告(3篇)

第1篇一、实验目的通过本次实验,掌握常见算法的设计原理、实现方法以及性能分析。

通过实际编程,加深对算法的理解,提高编程能力,并学会运用算法解决实际问题。

二、实验内容本次实验选择了以下常见算法进行设计和实现:1. 排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。

2. 查找算法:顺序查找、二分查找。

3. 图算法:深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)。

4. 动态规划算法:0-1背包问题。

三、实验原理1. 排序算法:排序算法的主要目的是将一组数据按照一定的顺序排列。

常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。

2. 查找算法:查找算法用于在数据集中查找特定的元素。

常见的查找算法包括顺序查找和二分查找。

3. 图算法:图算法用于处理图结构的数据。

常见的图算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)等。

4. 动态规划算法:动态规划算法是一种将复杂问题分解为子问题,通过求解子问题来求解原问题的算法。

常见的动态规划算法包括0-1背包问题。

四、实验过程1. 排序算法(1)冒泡排序:通过比较相邻元素,如果顺序错误则交换,重复此过程,直到没有需要交换的元素。

(2)选择排序:每次从剩余元素中选取最小(或最大)的元素,放到已排序序列的末尾。

(3)插入排序:将未排序的数据插入到已排序序列中适当的位置。

(4)快速排序:选择一个枢纽元素,将序列分为两部分,使左侧不大于枢纽,右侧不小于枢纽,然后递归地对两部分进行快速排序。

(5)归并排序:将序列分为两半,分别对两半进行归并排序,然后将排序好的两半合并。

(6)堆排序:将序列构建成最大堆,然后重复取出堆顶元素,并调整剩余元素,使剩余元素仍满足最大堆的性质。

2. 查找算法(1)顺序查找:从序列的第一个元素开始,依次比较,直到找到目标元素或遍历完整个序列。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

XI`AN TECHNOLOGICAL UNIVERSITY 课程设计报告目录一、问题描述 (2)二、思路描述 (2)三、源代码展示 (3)四、函数介绍 (6)1、判断输入的顶点是否存在矩阵中 (6)2、着色函数 (7)3、判断这个颜色能不能满足要求函数 (8)五、调试运行 (8)1、中国地图简略图 (8)2、取地图一部分进行测试 (8)3、运行结果 (9)六、算法分析 (9)七、总结 (11)一、问题描述:设计要求:已知中国地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少。

二、思路描述:已知中国地图,对各省进行着色,要求相邻省所用的颜色不同,并保证使用的颜色数最少,将各省进行编号,然后利用无向图的顶点之间的边来表示各省的相邻关系,将各编号进行逐一着色,利用循环语句遍历各省,判断语句判断是否符合要求;演示程序,以用户和计算机的对话方式进行,最后结果做出简单分析及总结。

三、源代码展示:#include <stdio.h>#include <stdlib.h>#define MAXedg 100#define MAX 0#define N 4int color[30]={0};struct Graph{char vexs[MAXedg];int arcs[MAXedg][MAXedg]; int vnum,arcnum;};int LocateVex(Graph G,char u) {int i;for(i=1;i<=G.vnum;i++){if(u==G.vexs[i])return i;}if(i==G.vnum){printf("Error u!\n");exit(1);}return 0;}void CreateGraph(Graph &G) {int i,j,k, w;char v1,v2;printf("输入图的顶点数和边数:\n");scanf("%d%d",&G.vnum,&G.arcnum);getchar();printf("输入图的各顶点:\n");for(i=1;i<=G.vnum;i++){scanf("%c",&G.vexs[i]); getchar();}for(i=0;i<=G.vnum;i++)for(j=0;j<=G.vnum;j++)G.arcs[i][j]=MAX;printf("输入边的两个顶点和权值(均用1表示):\n"); for(k=0;k<G.arcnum;k++){scanf("%c", &v1);getchar();scanf("%c", &v2);getchar();scanf("%d", &w); getchar();i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcs[i][j]=w;G.arcs[j][i]=w;}}void PrintGraph(Graph G){int i,j;printf("图的各顶点:\n");for(i=1;i<=G.vnum;i++){printf("%c ",G.vexs[i]);}printf("\n");printf("图的邻接矩阵:\n");for(i=1;i<=G.vnum;i++){for(j=1;j<=G.vnum;j++)printf("%d ",G.arcs[i][j]);printf("\n");}}int colorsame(int s,Graph G){int i,flag=0;for(i=1;i<=s-1;i++){if(G.arcs[i][s]==1&&color[i]==color[s]) {flag=1;break;}}return flag;}void output(Graph G){for(int i=1;i<=G.vnum;i++){printf("%d ",color[i]);}printf("\n");}void trycolor(int s,Graph G){int i;if(s>G.vnum)/*递归出口*/{output(G);exit(1);}else{for(i=1;i<=N;i++){color[s]=i;if(colorsame(s,G)==0)trycolor(s+1,G);}}}int main(){Graph G;CreateGraph(G);PrintGraph(G);printf("着色方案:\n");trycolor(1,G);return 0;}四、函数介绍:1、判断输入的顶点是否存在矩阵中: int LocateVex(Graph G,char u){int i;for(i=1;i<=G.vnum;i++)/*从第一个结点开始到最后一个结点看是否存在*/ {if(u==G.vexs[i]) /*结点集合*/return i; /找到并返回*/}if(i==G.vnum) /*从第一个结点开始到最后一个结点都不存在*/{printf("Error u!\n");exit(1);}return 0;}2、着色函数:void trycolor(int s,Graph G)/*s为开始图色的顶点,本算法从1开始*/{int i;if(s>G.vnum)/*递归出口*/{output(G);exit(1);}else{for(i=1;i<=N;i++)/*对每一种色彩逐个测试*/{color[s]=i;if(colorsame(s,G)==0){trycolor(s+1,G);/*进行下一块的着色*/}}}}3、判断这个颜色能不能满足要求函数:int colorsame(int s,Graph G)/*判断这个颜色能不能满足要求*/ {int i,flag=0;for(i=1;i<=s-1;i++)/*分别与前面已经着色的几块比较*/ if(G.arcs[i][s]==1&&color[i]==color[s]){flag=1;break;}return flag;}五、调试运行:1、中国地图简略图2、取地图一部分进行测试有6个顶点,8条边。

各点相邻情况为:a-b ,a-e ,b-c ,b-d ,b-e ,c-d, d-e e-f3、运行结果六、算法分析:地图着色主要使用回溯法,回溯法解题的一般步骤:(1)针对所给问题,定义问题的解空间;(2)确定易于搜索的解空间结构;(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

首先把所有顶点的颜色初始化为0,然后依次为每个顶点着色。

如果其中i个顶点已经着色,并且相邻两个顶点的颜色都不一样,就称当前的着色是有效的局部着色;否则,就称为无效的着色。

如果由根结点到当前结点路径上的着色,对应于一个有效着色,并且路径的长度小于n,那么相应的着色是有效的局部着色。

这时,就从当前结点出发,继续探索它的儿子节点,并把儿子结点标记为当前结点。

在另一方面,如果在相应路径上搜索不到有效的着色,就把当前结点标记为死结点,并把控制转移去搜索对应于另一种颜色的兄弟结点。

如果对所有m个兄弟结点,都搜索不到一种有效的着色,就回溯到它的父亲结点,并把父亲结点标记为死结点,转移去搜索父亲结点的兄弟结点。

这种搜索过程一直进行,直到根结点变为死结点,或者搜索路径长度等于n,并找到了一个有效的着色为止。

由于用m种颜色为无向图G=(V,E)着色,其中,V的顶点个数为n,可以用一个n元一维数组C[i]来描述图的一种可能着色,表示赋予顶点i的颜色。

例如,5元一维组(1, 2, 2, 3, 1)表示对具有5个顶点的无向图(a)的一种着色,顶点a着颜色1,顶点b着颜色2,顶点c着颜色2,等等。

如果在n元一维组C[i]中,所有相邻顶点都不会着相同颜色,就称此n元一维组为可行解,否则为无效解。

容易看出,每个顶点可着颜色有m种选择,n个顶点就有m n种不同的着色方案,问题的解空间是一棵高度为n的完全m叉树,这里树高度的定义为从根节点到叶子节点的路径的长度。

每个分支结点,都有m个儿子结点。

最底层有m n个叶子结点。

例如,表示用3种颜色为3个顶点的图着色的状态空间树。

如图所示,对第i(i>=1)层上的每个顶点,从其父节点到该节点的边上的标号表示顶点i着色的颜色编号。

七、总结:对中国地图着色即图着色问题,用m种颜色来为无向图着色,其中顶点个数为n 。

因此,用一个n元组来描述图的一种着色。

在这种着色中,所有相邻的顶点都不会具有相同的颜色,这种着色就是有效着色。

根据这种思想编写中国地图着色算法,算法主要使用回溯法。

根据算法运行,可以看出,无论有多少点,点与点之间怎样相邻,都只需要4种颜色就可以完成着色。

通过此次对中国地图着色问题的探究,我更好更深入了学习了着色问题中回溯法的运用,在课堂上学习的理论知识只有运用到实践里才能被更好的掌握。

相关文档
最新文档