回溯法(2)--图着色问题和旅行商问题

目录

一、图着色问题

1、算法设计

2、代码

二、旅行商问题 

1、概述问题

2、穷举法

3、回溯法 


一、图着色问题

1、算法设计

        图着色问题,给定图中各个区域的相邻关系,抽象成一个无向图G=(V,E),给定m种颜色,可以选择一个颜色可以对每一个区域(无向图的顶点)进行着色,但需要保证相邻区域之间不能颜色相同,如下图的无向图表示。

        无向图采用建立邻接矩阵a[ ][ ]来表示。注意:i和j都是从1开始的,而不是0开始的,所以邻接矩阵的0行0列,设定为-1,表示不存在。

                a[i][j]=\left\{\begin{matrix} 1 \qquad (i,j)\in E\\ 0 \qquad \quad others \end{matrix}\right. 

         算法:回溯法,子集树方法。

        backtrack回溯过程:

(1)首先判断是否叶子结点已经搜索,即t>n,若满足条件,则输出当前着色方法,sum++。

(2)若不满足条件,则在当前层遍历m种颜色,若该颜色满足扩展条件,则扩展该叶子结点搜索下一层,否则选择下一个颜色,直到所有颜色都不满足条件则回溯上一层。

(3)扩展条件:遍历n个结点,若结点与叶子结点有相邻关系a[t][i]==1且叶子结点和该遍历的结点颜色相同x[t]==x[i],则返回false,否则存在一个结点有相邻关系且颜色不同,返回true用来做新的扩展结点。

(4)另外,判断(t<=n)&&x[t]==m,如果当前层数不在叶子结点层(第n层),且该层修改的颜色值为最后一个颜色(由于颜色按顺序遍历),则颜色置0,退出当前迭代层,返回上一层。也就是说当前叶子结点的所有子树都搜索过了,该结点变为死结点,要么返回到该叶子结点的邻树,要么返回叶结点上一层。

2、代码

//图着色问题
public class graphcoloration {static int n=5;          //顶点数static int m=3;          //颜色数static int a[][]={         //邻接矩阵{-1,-1,-1,-1,-1,-1},{-1,0,1,1,1,0},{-1,1,0,1,0,1},{-1,1,1,0,1,1},{-1,1,0,1,0,1},{-1,0,1,1,1,0}};   //-1是不存在0点,0是不可达static int sum=0;                   //可行解public static void main(String[] args){int x[]=new int[n+1];           //x存储可达的路线backtrack(1, x);                //初始节点在第一层System.out.println(sum);        //输出有多少种可行解}public static void backtrack(int t,int x[]){if(t>n){    sum++;for(int i=1;i<=n;i++){System.out.print(x[i]+" ");}System.out.println();}else{for(int i=1;i<=m;i++){x[t]=i;if(OK(t,x))                       //如果满足扩展条件则扩展backtrack(t+1, x);if((t<=n)&&x[t]==m)               //如果当前层数不在叶子结点,且该层修改的数为最后一个颜色,则颜色置0,退出当前迭代层                              {   x[t]=0;break;}}}}public static boolean OK(int t,int x[]){for(int i=1;i<=n;i++){if((a[t][i]==1)&&x[t]==x[i])        //判断所有相邻关系中颜色相同的返回falsereturn false;}return true;                            //留下的都是存在相邻关系且颜色不同的返回true}
} 

二、旅行商问题 

1、概述问题

        一个旅行商希望从一个城市出发访问n个城市,每个城市只能访问一次,且开始和结束在同一城市,给出一个不同城市之间距离的加权完全图,请设计一个算法,找到旅行商的最短路径。也就是图论中的求出最小的哈密顿回路。

        下面的算法依照下图为例,出发为a点。

2、穷举法

        穷举法就是求所有a为出发点,a为终点的全排列。

        全排列算法:

(1)全排列算法使用递归算法,如果迭代到最后一层,则计算当前路线的加权和(注意第一个值不用进行全排列,因为初始点不动),minl存放加权和最小的值。

(2)若没有迭代到最后一层,则遍历k<=i<=n,k为当前全排列迭代的层数,交换op[i]和op[k],继续排列k+1层,再交换op[i]和op[k],保证对后续没有影响。

代码如下:

//旅行商问题
public class tsp {public static final int MAX=9999;public static int[][] a={{MAX,MAX,MAX,MAX,MAX},{MAX,MAX,2,5,8},{MAX,2,MAX,7,3},{MAX,5,7,MAX,1},{MAX,8,3,1,MAX},};public static int n=4;public static int minl=999;public static void main(String []args){int op[]=new int[n+1];for(int i=1;i<=n;i++)op[i]=i;perm(2,op);System.out.println(minl);} //全排列算法public static void perm(int k,int op[]){if(k==n){  int tmp=calulate(op);minl=tmp<minl?tmp:minl;}for(int i=k;i<=n;i++){swap(i,k,op);perm(k+1,op);swap(i,k,op);}}//交换数组中元素public static void swap(int i,int k,int []op){int tmp=op[i];op[i]=op[k];op[k]=tmp;}//计算全排列后当前排列的加权和public static int calulate(int []op){int tot=0;for(int i=1;i<n;i++){tot+=a[op[i]][op[i+1]];}tot+=a[op[n]][1];return tot;}
}

3、回溯法 

        时间复杂度分析:对于回溯法(本质上也是穷举法)和穷举法的时间复杂度都是O(n!),所以随着城市的数量增加,计算时间指数级增长,所以对于大规模的TSP问题可以采用动态规划、启发式算法等方法,来在短时间接近最优解,但这一定不是完备的。

        算法流程:

(1)首先判断是否叶子结点已经搜索,即满足k>n,则计算当前加权和,minl保存最小的加权和。

(2)若不满足,则遍历所有叶子结点,是否存在可以扩展的结点,进行扩展迭代到下一层,若没有则返回上一层。

(3)扩展条件:判断所有结点中满足a[k][i]!=MAX即待扩展节点与判断结点不可达,且x[k]==x[i]待扩展节点与判断结点相同,则不可扩展。也就是存在某一节点可以到达,且与上一个结点不同,则扩展。

//旅行商问题
public class tsp {public static final int MAX=9999;public static int[][] a={{MAX,MAX,MAX,MAX,MAX},{MAX,MAX,2,5,8},{MAX,2,MAX,7,3},{MAX,5,7,MAX,1},{MAX,8,3,1,MAX},};public static int n=4;public static int minl=999;public static void main(String []args){int op[]=new int[n+1];int x[]=new int[n+1];for(int i=1;i<=n;i++)op[i]=i;backtrack(1,x);System.out.println(minl);} //回溯法public static void backtrack(int k,int x[]){//注意这里一定要大于号,也就是已经判断好当前路径的叶子结点,再进行输出,或者替换最小值。if(k>n){int tot=0;for(int i=1;i<n;i++)tot+=a[x[i]][x[i+1]]; tot+=a[x[n]][x[1]];minl=minl<tot?minl:tot;}else{for(int i=1;i<=n;i++){x[k]=i;if(Ok(k, x))backtrack(k+1,x);}}}//判断是否能继续扩展public static boolean Ok(int k,int x[]){for(int i=1;i<=n;i++){if(a[k][i]!=MAX&&x[k]==x[i])return false;}return true;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WinForm详细教程四】WinForm中的ProgressBar 、ImageList和ListView控件

文章目录 1.ProgressBar2. ImageList3.ListView控件 1.ProgressBar 用于显示某个操作的进度。 属性&#xff1a; Value: 表示当前进度条的值&#xff0c;其范围由Min和Max决定。Step: 设置每次调用PerformStep()方法时增加的步长。MarqueeAnimationSpeed: 在Style设置为Marq…

【强化学习】13 —— Actor-Critic 算法

文章目录 REINFORCE 存在的问题Actor-CriticA2C&#xff1a; Advantageous Actor-Critic代码实践结果 参考 REINFORCE 存在的问题 基于片段式数据的任务 通常情况下&#xff0c;任务需要有终止状态&#xff0c;REINFORCE才能直接计算累计折扣奖励 低数据利用效率 实际中&#…

AI:47-基于深度学习的人像背景替换研究

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…

Py之transformers_stream_generator:transformers_stream_generator的简介、安装、使用方法之详细攻略

Py之transformers_stream_generator&#xff1a;transformers_stream_generator的简介、安装、使用方法之详细攻略 目录 transformers_stream_generator的简介 1、Web Demo T1、original T2、stream transformers_stream_generator的安装 transformers_stream_generator的…

恒驰服务 | 华为云数据使能专家服务offering之数仓建设

恒驰大数据服务主要针对客户在进行智能数据迁移的过程中&#xff0c;存在业务停机、数据丢失、迁移周期紧张、运维成本高等问题&#xff0c;通过为客户提供迁移调研、方案设计、迁移实施、迁移验收等服务内容&#xff0c;支撑客户实现快速稳定上云&#xff0c;有效降低时间成本…

[论文笔记]GTE

引言 今天带来今年的一篇文本嵌入论文GTE, 中文题目是 多阶段对比学习的通用文本嵌入。 作者提出了GTE,一个使用对阶段对比学习的通用文本嵌入。使用对比学习在多个来源的混合数据集上训练了一个统一的文本嵌入模型,通过在无监督预训练阶段和有监督微调阶段显著增加训练数…

重磅消息!优维发布全新产品“应急管理”

近日&#xff0c;蚂蚁集团旗下的在线文档编辑与协同工具语雀平台发生了一次严重的宕机事件&#xff0c;导致用户无法正常使用其各项功能。从故障发生到完全恢复正常&#xff0c;语雀整个宕机时间将近 8 小时&#xff0c;如此长时间的宕机已经达到了 P0 级事故&#xff0c;并在网…

1-1 暴力破解-枚举

枚举&#xff1a;枚举所有的情况&#xff0c;逐个判断是否是问题的解 判断题目是否可以使用枚举&#xff1a;估算算法复杂度 1秒计算机大约能处理107的数据量&#xff0c;即O(n)107&#xff0c;则O(n2)能处理的数据量就是根号107≈3162 复杂度对应的数据量是该算法能处理的最…

Git 入门指南:从新手到高手的完全指南

Git是一种强大的分布式版本控制系统&#xff0c;广泛应用于软件开发中。它的使用不仅可以帮助开发团队更好地管理代码&#xff0c;还可以提高团队协作效率和代码质量。随着软件开发的不断发展&#xff0c;版本控制成为了程序员必备的一项技能。 Git的基本概念 Git的基本概念对…

华为云资源搭建过程

网络搭建 EIP&#xff1a; 弹性EIP&#xff0c;支持IPv4和IPv6。 弹性公网IP&#xff08;Elastic IP&#xff09;提供独立的公网IP资源&#xff0c;包括公网IP地址与公网出口带宽服务。可以与弹性云服务器、裸金属服务器、虚拟IP、弹性负载均衡、NAT网关等资源灵活地绑定及解绑…

【嵌入式】【GIT】如何迁移老的GIF到新的仓库时使用LFS功能并保持LOG不变

一、正常迁移流程 假设有仓库 ssh://old/buildroot-201902 需要迁移到新的仓库 ssh://old/buildroot-201902时,我们可以使用以下命令来完成: # 下载老的仓库 git clone ssh://old/buildroot-201902 # 向新的仓库上传所有的tags git push ssh://new/buildroot-201902 --tag…

成为一个优秀的测试工程师需要具备哪些知识和经验?

看到这个题目&#xff0c;头脑中马上就拆分出了3个小问题&#xff1a; 1、什么是优秀的测试工程师&#xff1f; 2、优秀测试工程师需要哪些知识&#xff1f; 3、优秀测试工程师需要哪些经验&#xff1f; 一个个讲解。 一、什么才是一名优秀的测试工程师呢&#xff1f; 什么才是…