文章目录

  • 1、0-1背包问题
  • 2、旅行售货员问题
  • 3、图的m着色问题

一、实验目的:
掌握用回溯法解题的算法框架;根据回溯法解决实际问题。

二、实验所用仪器及环境
Windows 7 以上操作系统,PC机,codeblocks环境

三、实验原理:
算法总体思想:回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树。算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯;否则,进入该子树,继续按深度优先策略搜索。
(1)问题的解向量:回溯法希望一个问题的解能够表示成一个n元式(x1,x2,…,xn)的形式。
(2)显约束:对分量xi的取值限定。
(3)隐约束:为满足问题的解而对不同分量之间施加的约束。
(4)解空间:对于问题的一个实例,解向量满足显式约束条件的所有多元组,构成了该实例的一个解空间。
基本步骤:
(1)针对所给问题,定义问题的解空间,主要有子集树(如图1所示)和排列树(如图2所示)两种解空间形式。
(2)确定易于搜索的解空间结构;
(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

图1 子集树

图2 排列树

四、实验内容:

1、0-1背包问题

有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。要求每个物品要么放进背包,要么不放进背包。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;#define maxn 100000int w[maxn]={0};
int v[maxn]={0};
int ans[maxn]={0};
int a[maxn]={0};
int n;
int Maxw,Sumv;int huisu(int t,int Sw,int Sv)
{if(t>=n)///最大层了{if(Sumv<Sv)///永远取最大值{Sumv=Sv;for(int i=0;i<n;i++){ans[i]=a[i];}}}else{for(int i=0;i<=1;i++)//0-1{a[t]=i;///临时选择方式Sw=Sw+i*w[t];Sv=Sv+i*v[t];if(Sw<=Maxw)///目前的实际重量比最大重量(重量上限)小才行{huisu(t+1,Sw,Sv);}else{Sw-=i*w[t];///拿出来Sv-=i*v[t];}}}}int main()
{cin>>n>>Maxw;for(int i=0;i<n;i++){cin>>v[i];}for(int i=0;i<n;i++){cin>>w[i];}huisu(0,0,0);///0号层,重量0,价值0for(int i=0;i<n;i++){cout<<ans[i]<<" ";/// 最优选择}cout<<endl;cout<<Sumv;return 0;
}//void backtrack(int k)
//{//    if(到达边界) 更新或者输出结果
//    else
//    {//        对于每一种可能进行操作(for循环 i)
//        {//            if(限定条件合法)
//                backtrack(k+i);
//        }
//    }
//
//}//n 代表的是物品个数
//
//MaxWight 背包能装的最大体积
//
//SumValue 物品的最大价值
//
//ans 数组,最终选择方式
//
//a 数组,临时选择方式
//
//
//
//思路:物品只有两种选择,放或者不放,构造二叉树,n 个物品就是 n 层树,然后进行最优值更新。//in
//4 10
//1 3 5 9
//2 3 4 7
//out
//0 1 0 1
//12

2、旅行售货员问题

设有一个售货员从城市1出发,到城市2,3,…,n去推销货物,最后回到城市1。假定任意两个城市i,j间的距离dij(dij=dji)是已知的,问他应沿着什么样的路线走,才能使走过的路线最短。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;#define maxn 10000int n;
int dis[maxn][maxn]={0};
int mindis=maxn;
int x[maxn];
int bestx[maxn];
int cw;///0-  n-1 城
int BackTrack(int t)
{if(t>=n){for(int i=1;i<=n;i++){bestx[i]=x[i];}mindis=cw+dis[x[n-1]][x[n]]+dis[x[n]][1];///最优值走到头才更新return mindis;}else{for(int i=t;i<=n;i++){if(cw+dis[x[t-1]][i]<mindis||mindis==maxn){swap(x[t],x[i]);///遍历全排列cw+=dis[x[t-1]][x[t]];BackTrack(t+1);cw-=dis[x[t-1]][x[t]];swap(x[t],x[i]);}}}}int main()
{cin>>n;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)cin>>dis[i][j];for(int i=1;i<=n;i++){x[i]=i;}BackTrack(2);cout<<mindis;return 0;
}//void backtrack(int k)
//{//    if(到达边界) 更新或者输出结果
//    else
//    {//        对于每一种可能进行操作(for循环 i)
//        {//            if(限定条件合法)
//                backtrack(k+i);
//        }
//    }
//
//}
//#回溯法#回溯法+排序树为什么swap?https://blog.csdn.net/qq_37967797/article/details/92624531?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1-92624531.nonecase&utm_term=%E5%9B%9E%E6%BA%AF%E6%B3%95%E6%8E%92%E5%88%97%E6%A0%91swap%E4%BD%9C%E7%94%A8&spm=1000.2123.3001.4430
//4
//-1 30 6 4
//30 -1 5 10
//6 5 -1 20
//4 10 20 -1
//25

3、图的m着色问题

(1)问题描述:给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的2个顶点着不同颜色。若这个图不是m可着色的,就输出no。若是则输出每种着色方案和可行方案数。
(2)样例1
输入:当输入如下图时

顶点数:5
颜色数 4
边数:9
各边顶点:
1 2
1 3
1 4
2 3
2 4
2 5
3 4
3 5
4 5
输出:

样例2:

(3)实验步骤
(a)首先将给定的图利用抽象图表示出来
(b)判断该节点k当前的着色是否符合条件,需要判断x[k]与k结点其他相邻节点h的x[h]是否相等
(c)回溯过程,若此时的结点值已经大于结点总数,代表已经着色完成,并且找到了一种可行解,此时可以将可行解数+1
(d)回溯从最后一个结点往上回溯,并一层一层更改结点至其他可用着色,以此来找到所有的填色方案。

#include <iostream>
#include<bits/stdc++.h>
using namespace std;#define maxn 10000int n,m,sum;
int w[maxn][maxn]={0};
int bestw=maxn;
int x[maxn];///全排列的缓冲?
int bestx[maxn];
int cw;
int tong(int k){for(int i=1;i<k;i++){if(w[k][i]==1&&x[i]==x[k]){return 0;}}return 1;
}void  BackTrack(int t)
{if(t>n){for(int i=1;i<=n;i++){cout<<x[i]<<" ";}cout<<endl;sum++;}else{for(int i=1;i<=m;i++){x[t]=i;if(tong(t)==1){//cout<<"*";BackTrack(t+1);}x[t]=0;}}}int main()
{cin>>n;
int bian;cin>>m;cin>>bian;
//    for(int i=0;i<=n;i++)
//        for(int j=0;j<=n;j++)
//            w[i][j]=-1;for(int i=1;i<=bian;i++){int x,y;cin>>x>>y;w[x][y]=1;w[y][x]=1;}//    for(int i=0;i<=n;i++)
//        {for(int j=0;j<=n;j++)
//            cout<<w[i][j]<<" ";
//        cout<<endl;}
///formatfor(int i=1;i<=n;i++)cout<<i<<" ";cout<<endl;for(int i=1;i<=n;i++)cout<<"--";cout<<endl;//BackTrack(1);cout<<sum;return 0;
}//void backtrack(int k)
//{//    if(到达边界) 更新或者输出结果
//    else
//    {//        对于每一种可能进行操作(for循环 i)
//        {//            if(限定条件合法)
//                backtrack(k+i);
//        }
//    }
//
//}.
//in1
//5
//4
//9
//1 2
//1 3
//1 4
//2 3
//2 4
//2 5
//3 4
//3 5
//4 5
//out1
//1 2 3 4 5
//----------
//1 2 3 4 1
//1 2 4 3 1
//1 3 2 4 1
//1 3 4 2 1
//1 4 2 3 1
//1 4 3 2 1
//2 1 3 4 2
//2 1 4 3 2
//2 3 1 4 2
//2 3 4 1 2
//2 4 1 3 2
//2 4 3 1 2
//3 1 2 4 3
//3 1 4 2 3
//3 2 1 4 3
//3 2 4 1 3
//3 4 1 2 3
//3 4 2 1 3
//4 1 2 3 4
//4 1 3 2 4
//4 2 1 3 4
//4 2 3 1 4
//4 3 1 2 4
//4 3 2 1 4
//24
//in2
//4 3 4
//1 2
//1 4
//2 3
//4 3
//1 2 3 4
//--------
//1 2 1 2
//1 2 1 3
//1 2 3 2
//1 3 1 2
//1 3 1 3
//1 3 2 3
//2 1 2 1
//2 1 2 3
//2 1 3 1
//2 3 1 3
//2 3 2 1
//2 3 2 3
//3 1 2 1
//3 1 3 1
//3 1 3 2
//3 2 1 2
//3 2 3 1
//3 2 3 2
//18

五、实验结果与分析:
通过运行程序验证程序的正确性,给出程序运行结果,分析程序出现的bug的原因,调试程序过程种出现的错误和解决方法。

算法分析与设计-实验四 回溯算法设计相关推荐

  1. 算法分析与设计-实验三 贪心算法设计

    文章目录 1.最优服务次序问题 2.区间相交问题 3.汽车加油问题 4.活动安排问题:考虑将一系列活动安排在科学会堂.假设有n个活动,每个活动需要花费一个单位时间.如果在时间T[i]或T[i]之前开始 ...

  2. 算法分析与设计-实验二 动态规划算法设计

    文章目录 1. 数字三角问题 2.最长公共子序列问题 3.日常购物 4.台阶问题 一.实验目的: 掌握动态规划算法的基本思想及适用条件,掌握动态规划算法的设计步骤和具体实现. 二.实验所用仪器及环境 ...

  3. java符号三角形问题_实验四 回溯算法和分支限界法 符号三角形问题

    基本题一:符号三角形问题 一.实验目的与要求 1.掌握符号三角形问题的算法: 2.初步掌握回溯算法: 二.实验题图 下面都是"-".下图是由14个"+"和14个 ...

  4. Python算法分析与设计实验:动态规划算法

    Python算法分析与设计实验:动态规划算法 一.实验目的 1.理解动态规划求解优化问题的典型步骤,以及动态规划算法求解计算问题的时间复杂度分析 2.熟练掌握利用动态规划算法求解一维.二维等典型优化问 ...

  5. 用栈、回溯算法设计迷宫程序

    目录 1.走迷宫与回溯算法 2.迷宫设计栈扮演的角色 3.Python实现走迷宫 栈的应用有许多,本篇博文着重将栈与回溯(Backtracking)算法结合,设计走迷宫程序.其实回溯算法也是人工智能的 ...

  6. (十五)算法设计思想之“回溯算法”

    算法设计思想之"回溯算法" 回溯算法是什么? 什么问题适合用回溯算法解决? 适合回溯算法解决的问题 全排列 LeetCode:46.全排列 LeetCode:78.子集 思考题 回 ...

  7. JAVA算法:走迷宫回溯算法设计(JAVA版本)

    JAVA算法:走迷宫回溯算法设计(JAVA版本) 迷宫数组 int[][] maze = {                 {0, 1, 0, 0, 0},                 {0, ...

  8. 实验四 OR指令设计实验【计算机组成原理】

    实验四 OR指令设计实验[计算机组成原理] 前言 推荐 实验四 OR指令设计实验 一.实验目的 二.实验环境 三.实验原理 四.实验任务 五.实验思考 实验四 代码 修改代码 define ID EX ...

  9. 基于STM32激光雕刻机(四)算法设计

    基于STM32激光雕刻机(四)算法设计 做一份笔记,大佬勿喷. 作者:sumjess 待更..........

最新文章

  1. 清华唐杰:GPT-3表示能力已经接近人类了
  2. 将现有MySQL数据库改为大小写不敏感
  3. [BZOJ 1834] [ZJOI2010]network 网络扩容
  4. 【POJ - 2942】Knights of the Round Table(点双连通分量,二分图判断奇环奇圈)
  5. 区块链中涉及到密码学的场景
  6. 带你自学Python系列(七):Python列表复制陷阱
  7. flutter -------- GridView的使用
  8. 在Linux上安装MySql
  9. python读取ansi编码文件,如何在Python中同时读取ANSI和Unicode txt文件?
  10. ubuntu16.04配置opencv2、python2、cuda8.0、cudnn以及caffe
  11. ModelForm操作
  12. 【HeadFirst 设计模式学习笔记】9 迭代器模式
  13. 计算机专业 学习路线
  14. php防撞库,基于单片机的倒车防撞预警系统设计和实现
  15. Blender快捷键、技巧和软件配置
  16. ArcMap对多年 NDVI 进行线性趋势和F显著性检验
  17. python源码剖析—— python中的字典对象
  18. 【补码表示】为什么定点小数的-1补码表示为1.0000以及补码表示范围问题
  19. 【采样算法】拉丁超立方采样
  20. 学习编程与学习编程语言不同

热门文章

  1. js-ajax-04
  2. 二分查找、upper_bound、lower_bound
  3. C#简单实现LRU缓存
  4. Google Chrome v48.0.2564.
  5. 转载:由图片SEO想起
  6. Oracle Enterprise Manager简介
  7. harmonyos2.0如何申请,华为鸿蒙HarmonyOS2.0手机开发者Beta版公测申请地址方法_专题_53货源网...
  8. oracle查询数据库启动时的参数文件,【Oracle】数据库启动阶段参数文件、控制文件的问题处理...
  9. 数学教师计算机能力提升,数学教师信息技术应用能力提升培训总结.doc
  10. d盘莫名其妙被占空间 win10_Win10不好用?你不可不知的Win10技巧