数据结构:地图着色问题——图的应用——回溯法

这篇具有很好参考价值的文章主要介绍了数据结构:地图着色问题——图的应用——回溯法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

一、解决问题的思路

二、存储结构设计

三、代码

1.创建图函数

2.判断色号是否相同函数

3.回溯函数

4.整体代码

总结


前言

本次解决的问题:用图模拟部分地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少。

先来一张效果图

图着色问题回溯算法,c++,数据结构,算法,深度优先


一、解决问题的思路

将邻接矩阵创建好了以后,通过回溯函数,在解空间树中搜索所有的可行解,如果着色有冲突,就回溯到上一个节点。一旦到达叶子节点,也就是这个解到头了,就输出这种着色方案。

二、存储结构设计

a

抽象数据类型:

        ADT Graph{

        数据对象V:一个非空集合,该集合中的所有元素具有相同的特性。

        数据关系RR={VR}VR={<x,y> | P(x,y) (x,y∈V)}

基本操作:

        Createmap(&G)

        操作前提:已知图G不存在。

        操作结果:创建图G

        }ADT Graph;

(b) 存储结构:顺序表存储结构

        typedef struct{

           char vertax[MAX][MAX];//顶点所属的省份

           int map[MAX][MAX]; //邻接矩阵

           int n; //顶点个数

           int m;//边的个数

        }Graph;

三、代码

1.创建图函数

这里没什么好说的,都是创建图所需要的输入。顶点个数,顶点所代表的省份也就是顶点名称,边的个数,有边相连的两个顶点。

void Createmap(Graph &G) //创建邻接矩阵
{
	printf("请输入顶点(省份)个数:");
    int f=scanf("%d", &G.n);
    while(f!=1)
	{
		printf("输入值非法!\n");
		printf("请重新输入顶点(省份)个数:");
		fflush(stdin);
		f=scanf("%d", &G.n);
	}
    for(int i=1;i<=G.n;i++)
    {
    	printf("请输入第%d个顶点所代表的省份:",i);
    	cin>>G.vertax[i];
	}
    int u; //顶点1
    int v; //顶点2
    cout << "\n请输入边的个数:";
    cin >> G.m;
    cout << "请输入有边相连的两个顶点u和v:"<< endl;
    for (int i=1;i<=G.m;i++)//为邻接矩阵赋值 
    {
        cin>>u>>v;
        G.map[u][v]=1;
        G.map[v][u]=1;
    }
    cout<<endl;
}

2.判断色号是否相同函数

先判断是否相连,如果相连则判断两个顶点颜色是否一样。如果顶点颜色不冲突,就返回真,反之返回假。

bool Find(Graph G,int t) //判断色号是否相同的函数
{
    for(int j=1;j<t;j++) //判断现在扩展点t和前面t-1个顶点有没有相连的
    {
        if(G.map[t][j]) //如果相连
        {
            if(color[j]==color[t]) //且颜色一样
            {
                return false; //返回false,表示需要换个色号尝试
            }
        }
    }
    return true;
}

3.回溯函数

判断是否到达了叶子节点,如果没有,则开始试探这个顶点着此颜色行不行,行就向下递归,进入下一个节点开始着色试探,不行就换一种颜色继续试探,直到所有颜色被试探完。

void Backtrack(Graph G,int t) //回溯函数
{
    if(t>G.n) //到达叶子节点,打印一种填色方案 
    {
    	answer=0;//找到最少的颜色个数 
        sum++; //方案个数+1
        cout << "第"<< sum << "种方案:";
        for (int i=1;i<=G.n;i++)
        {
            cout << color[i] << " ";
        }
        cout << endl;
    }
    else
    {
        for (int i=1;i<=color_nums;i++) //尝试别的色号
        {
            color[t]=i;  //试探色号i 
            if(Find(G,t)) //如果色号没有撞
            {
                Backtrack(G,t+1); //向下递归 
            }
        }
    }
}

4.整体代码

#include <iostream>
using namespace std;
 
const int MAX=111;//最大存储个数 
typedef struct{
	char vertax[MAX][MAX];//顶点所属的省份 
	int map[MAX][MAX]; //邻接矩阵
	int n; //顶点个数
	int m;//边的个数
}Graph; 

int color[MAX]; //解空间,表示第i个省所填的颜色 
int sum=0; //记录有多少种方案

int color_nums=0; //颜色数量
int answer=1;

void Createmap(Graph &G) //创建邻接矩阵
{
	printf("请输入顶点(省份)个数:");
    int f=scanf("%d", &G.n);
    while(f!=1)
	{
		printf("输入值非法!\n");
		printf("请重新输入顶点(省份)个数:");
		fflush(stdin);
		f=scanf("%d", &G.n);
	}
    for(int i=1;i<=G.n;i++)
    {
    	printf("请输入第%d个顶点所代表的省份:",i);
    	cin>>G.vertax[i];
	}
    int u; //顶点1
    int v; //顶点2
    cout << "\n请输入边的个数:";
    cin >> G.m;
    cout << "请输入有边相连的两个顶点u和v:"<< endl;
    for (int i=1;i<=G.m;i++)//为邻接矩阵赋值 
    {
        cin>>u>>v;
        G.map[u][v]=1;
        G.map[v][u]=1;
    }
    cout<<endl;
}
 
bool Find(Graph G,int t) //判断色号是否相同的函数
{
    for(int j=1;j<t;j++) //判断现在扩展点t和前面t-1个顶点有没有相连的
    {
        if(G.map[t][j]) //如果相连
        {
            if(color[j]==color[t]) //且颜色一样
            {
                return false; //返回false,表示需要换个色号尝试
            }
        }
    }
    return true;
}
 
void Backtrack(Graph G,int t) //回溯函数
{
    if(t>G.n) //到达叶子节点,打印一种填色方案 
    {
    	answer=0;//找到最少的颜色个数 
        sum++; //方案个数+1
        cout << "第"<< sum << "种方案:";
        for (int i=1;i<=G.n;i++)
        {
            cout << color[i] << " ";
        }
        cout << endl;
    }
    else
    {
        for (int i=1;i<=color_nums;i++) //尝试别的色号
        {
            color[t]=i;  //试探色号i 
            if(Find(G,t)) //如果色号没有撞
            {
                Backtrack(G,t+1); //向下递归 
            }
        }
    }
}
 
void Print() 
{
	printf("\n最少需要%d种颜色",color_nums);
}

int main()
{
	cout << "用图模拟部分地图,对各省进行着色,要求相邻省所使用的颜色不同,并保证使用的颜色总数最少\n"<< endl;
	Graph G;

    Createmap(G);
    while(answer)
    {
    	color_nums++;//颜色总数+1 
    	Backtrack(G,1);	
	}
	 
    Print();
    return 0;
}

总结

回溯算法采取的是这条路走不通就返回换下一条路走的思想,我觉得是蛮力法的优化算法,它避免了蛮力法穷举式的搜索。这是一种具有深度优先的策略,也就是如果某一个节点满足约束条件,则继续向下一个节点试探,直到找到解为止。虽然回溯法有限界和剪枝函数减小了搜索范围,但本身是类似于穷举思想,所以时间复杂度仍然很高,但也因此解决问题的范围很广。文章来源地址https://www.toymoban.com/news/detail-766812.html

到了这里,关于数据结构:地图着色问题——图的应用——回溯法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构专题实验7——图的应用(景点管理)(C++实现)

    实验内容:应用图的技术,根据需求文件要求的功能,实现旅游景点的管理。实验要求: 使用图的数据结构建立一个景点图的结构。 可以查找各景点信息。 旅游景点导航,使用深度优先,从一个景点开始遍历所有景点。 查找一个景点到另一个景点的最短路径。 对景点道路

    2024年02月04日
    浏览(46)
  • Java高阶数据结构 & 图的最短路径问题

    图的最短路径问题! 图的基础知识博客:传送门 最短路径问题: 从在带权图的某一顶点出发,找出一条通往另一顶点的最短路径, 最短也就是沿路径各边的权值总 和达到最小 。 一共会讲解三种算法 Dijkstra算法【单源最短路径】 Bellman-Ford算法【单源最短路径】 改进:SPF

    2024年02月04日
    浏览(49)
  • 【Java高阶数据结构】图的最短路径问题

    图的最短路径问题! 图的基础知识博客:传送门 最短路径问题: 从在带权图的某一顶点出发,找出一条通往另一顶点的最短路径, 最短也就是沿路径各边的权值总 和达到最小 。 一共会讲解三种算法 Dijkstra算法【单源最短路径】 Bellman-Ford算法【单源最短路径】 改进:SPF

    2024年02月08日
    浏览(35)
  • 数据结构-图的遍历和应用(DAG、AOV、AOE网)

    目录 *一、广度优先遍历(BFS) 广度优先生成树 广度优先生成森林 *二、深度优先遍历 深度优先生成树 深度优先生成森林 二、应用 2.1最小生成树 *Prim算法 *Kruskal算法 2.2最短路径  *BFS算法 *Dijkstra算法  *Floyd算法 *2.3有向无环图(DAG网)  *2.4拓扑排序(AOV网) *逆拓扑排序  *2.5关键路

    2024年02月10日
    浏览(40)
  • C语言数据结构——图的最短路径算法解决实例问题

    一、问题描述 W公司在某个地区有6个产品销售点,现根据业务需要打算在其中某个销售点上建立一个中心仓库,负责向其他销售点提供产品。由于运输线路不同,运输费用也不同。假定每天需要向每个销售点运输一次产品,那么应将中心仓库建在哪个销售点上,才能使运输费

    2024年02月08日
    浏览(45)
  • 数据结构(12)Dijkstra算法JAVA版:图的最短路径问题

    目录 12.1.概述 12.1.1.无权图的最短路径  12.1.2.带权图的最短路径 1.单源最短路径 2.多源最短路径 12.2.代码实现 无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。 有权图的最短路径,不考虑权重为负数的情况,因为权重为负

    2024年02月06日
    浏览(44)
  • 【数据结构】图的应用:最小生成树;最短路径;有向无环图描述表达式;拓扑排序;逆拓扑排序;关键路径

    目录 1、最小生成树 1.1 概念  1.2 普利姆算法(Prim) 1.3 克鲁斯卡尔算法(Kruskal)  2、最短路径 2.1 迪杰斯特拉算法(Dijkstra) 2.2 弗洛伊德算法(Floyd)  2.3 BFS算法,Dijkstra算法,Floyd算法的对比 3、有向无环图描述表达式 3.1 有向无环图定义及特点 3.2 描述表达式 4、拓扑排序

    2024年02月07日
    浏览(46)
  • 数据结构第11周 :(图的遍历及连通性 + 犯罪团伙 + 图形窗口问题 + 最小生成树的权值之和 + Jungle Roads )

    【问题描述】 根据输入的图的邻接矩阵A,判断此图的连通分量的个数。请使用邻接矩阵的存储结构创建图的存储,并采用BFS优先遍历算法实现,否则不得分。 【输入形式】 第一行为图的结点个数n,之后的n行为邻接矩阵的内容,每行n个数表示。其中A[i][j]=1表示两个结点邻接

    2024年02月06日
    浏览(40)
  • 图的着色问题

    问题1: 图着色问题是一个著名的NP完全问题。给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解决这个着色问题,而是对给定的一种颜色分配,请你判断这是否是图着色问题的一个解。 输入

    2023年04月20日
    浏览(31)
  • 【python-回溯法-图的m着色问题】

         

    2024年02月11日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包