ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:73.99KB ,
资源ID:3538595      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3538595.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(0029算法笔记回溯法n后问题和01背包问题.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

0029算法笔记回溯法n后问题和01背包问题.docx

1、0029算法笔记回溯法n后问题和01背包问题1、n后问题 问题描述:在nn格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在nn格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。 问题解析:用n元数组x1:n表示n后问题的解。其中,xi表示皇后i放在棋盘的第i行的第xi列。由于不允许将2个皇后放在同一列上,所以解向量中的xi互不相同。如果将n*n的棋盘看做是二维方阵,其行号从上到下,列号从左到右依次编号为1,2,n。设两个皇后的坐标分别为(i,j)和(k,l)。若两个皇后在同一斜线上,那么这两个皇

2、后的坐标连成的线为1或者-1。因此有: 由此约束条件剪去不满足行、列和斜线约束的子树。程序的递归回溯实现如下:cppview plaincopy1. /n后问题回溯法计算递归2. #includestdafx.h3. #include4. #includemath.h5. usingnamespacestd;6. 7. classQueen8. 9. friendintnQueen(int);10. private:11. boolPlace(intk);12. voidBacktrack(intt);13. intn,/皇后个数14. *x;/当前解15. longsum;/当前已找到的可行

3、方案数16. ;17. 18. intmain()19. 20. intn=4,m;21. coutn皇后问题的解为:endl;22. m=nQueen(n);23. coutn皇后问题共有;24. coutm个不同的解!endl;25. return0;26. 27. 28. boolQueen:Place(intk)29. 30. for(intj=1;jn)43. 44. sum+;45. for(inti=1;i=n;i+)46. 47. coutxi;48. 49. coutendl;50. 51. else52. 53. /探索第t行的每一列是否有元素满足要求54. for(int

4、i=1;i=n;i+)55. 56. xt=i;57. if(Place(t)58. 59. Backtrack(t+1);60. 61. 62. 63. 64. 65. intnQueen(intn)66. 67. QueenX;68. X.n=n;69. X.sum=0;70. 71. int*p=newintn+1;72. 73. for(inti=0;i=n;i+)74. 75. pi=0;76. 77. 78. X.x=p;79. X.Backtrack(1);80. 81. deletep;82. returnX.sum;83. 数组x记录了解空间树中从根到当前扩展节点的路径,这些

5、信息包含了回溯法在回溯是所需要的信息。利用数组x所含的信息,可将上述回溯法表示成非递归的形式。进一步省去O(n)递归栈空间。迭代实现的n后问题具体代码如下:cppview plaincopy1. /n后问题回溯法计算迭代2. #includestdafx.h3. #include4. #includemath.h5. usingnamespacestd;6. 7. classQueen8. 9. friendintnQueen(int);10. private:11. boolPlace(intk);12. voidBacktrack(void);13. intn,/皇后个数14. *x;/当

6、前解15. longsum;/当前已找到的可行方案数16. ;17. 18. intmain()19. 20. intn=4,m;21. coutn皇后问题的解为:endl;22. m=nQueen(n);23. coutn皇后问题共有;24. coutm个不同的解!endl;25. return0;26. 27. 28. boolQueen:Place(intk)29. 30. for(intj=1;j0)45. 46. xk+=1;47. while(xk=n)&!(Place(k)/寻找能够放置皇后的位置48. 49. xk+=1;50. 51. 52. if(xk=n)/找到位置53.

7、 54. if(k=n)55. 56. for(inti=1;i=n;i+)57. 58. coutxi;59. 60. coutendl;61. sum+;62. 63. else64. 65. k+;66. xk=0;67. 68. 69. else70. 71. k-;72. 73. 74. 75. 76. intnQueen(intn)77. 78. QueenX;79. X.n=n;80. X.sum=0;81. 82. int*p=newintn+1;83. 84. for(inti=0;i0, wi 0, vi 0 , 1in.要求找一n元向量(x1,x2,xn,), xi0,1

8、, wi xic,且 vi xi达最大.即一个特殊的整数规划问题。 问题解析:0-1背包问题是子集选取问题。0-1 背包问题的解空间可以用子集树表示。在搜索解空间树时,只要其左儿子节点是一个可行节点,搜索就进入左子树。当右子树中有可能含有最优解时,才进入右子树搜索。否则,将右子树剪去。设r是当前剩余物品价值总和,cp是当前价值;bestp是当前最优价值。当cp+r=bestp时,可剪去右子树。计算右子树上界的更好的方法是将剩余物品依次按其单位价值排序,然后依次装入物品,直至装不下时,再装入物品一部分而装满背包。 例如:对于0-1背包问题的一个实例,n=4,c=7,p=9,10,7,4,w=3,

9、5,2,1。这4个物品的单位重量价值分别为3,2,3,5,4。以物品单位重量价值的递减序装入物品。先装入物品4,然后装入物品3和1.装入这3个物品后,剩余的背包容量为1,只能装0.2的物品2。由此得一个解为1,0.2,1,1,其相应价值为22。尽管这不是一个可行解,但可以证明其价值是最优值的上界。因此,对于这个实例,最优值不超过22。 在实现时,由Bound计算当前节点处的上界。类Knap的数据成员记录解空间树中的节点信息,以减少参数传递调用所需要的栈空间。在解空间树的当前扩展节点处,仅要进入右子树时才计算上界Bound,以判断是否可将右子树剪去。进入左子树时不需要计算上界,因为上界预期父节点

10、的上界相同。算法的具体实现如下:cppview plaincopy1. /0-1背包问题回溯法求解2. #includestdafx.h3. #include4. usingnamespacestd;5. 6. template7. classKnap8. 9. template10. friendTypepKnapsack(Typep,Typew,Typew,int);11. private:12. TypepBound(inti);13. voidBacktrack(inti);14. 15. Typewc;/背包容量16. intn;/物品数17. 18. Typew*w;/物品重量数组

11、19. Typep*p;/物品价值数组20. Typewcw;/当前重量21. 22. Typepcp;/当前价值23. Typepbestp;/当前最后价值24. ;25. 26. template27. TypepKnapsack(Typepp,Typeww,Typewc,intn);28. 29. template30. inlinevoidSwap(Type&a,Type&b);31. 32. template33. voidBubbleSort(Typea,intn);34. 35. intmain()36. 37. intn=4;/物品数38. intc=7;/背包容量39. in

12、tp=0,9,10,7,4;/物品价值下标从1开始40. intw=0,3,5,2,1;/物品重量下标从1开始41. 42. cout背包容量为:cendl;43. cout物品重量和价值分别为:endl;44. 45. for(inti=1;i=n;i+)46. 47. cout(wi,pi);48. 49. coutendl;50. 51. cout背包能装下的最大价值为:Knapsack(p,w,c,n)endl;52. return0;53. 54. 55. template56. voidKnap:Backtrack(inti)57. 58. if(in)/到达叶子节点59. 60.

13、 bestp=cp;61. return;62. 63. 64. if(cw+wibestp)/进入右子树74. 75. Backtrack(i+1);76. 77. 78. 79. template80. TypepKnap:Bound(inti)/计算上界81. 82. Typewcleft=c-cw;/剩余容量83. Typepb=cp;84. 85. /以物品单位重量价值递减序装入物品86. while(i=n&wi=cleft)87. 88. cleft-=wi;89. b+=pi;90. i+;91. 92. 93. /装满背包94. if(i=n)95. 96. b+=pi/wi

14、*cleft;97. 98. 99. returnb;100. 101. 102. classObject103. 104. template105. friendTypepKnapsack(Typep,Typew,Typew,int);106. public:107. intoperator=a.d);110. 111. private:112. intID;113. floatd;114. ;115. 116. template117. TypepKnapsack(Typepp,Typeww,Typewc,intn)118. 119. /为Knap:Backtrack初始化120. Typ

15、ewW=0;121. TypepP=0;122. 123. Object*Q=newObjectn;124. for(inti=1;i=n;i+)125. 126. Qi-1.ID=i;127. Qi-1.d=1.0*pi/wi;128. P+=pi;129. W+=wi;130. 131. 132. if(W=c)/装入所有物品133. 134. returnP;135. 136. 137. /依物品单位重量价值排序138. BubbleSort(Q,n);139. 140. KnapK;141. K.p=newTypepn+1;142. K.w=newTypewn+1;143. 144.

16、for(inti=1;i=n;i+)145. 146. K.pi=pQi-1.ID;147. K.wi=wQi-1.ID;148. 149. 150. K.cp=0;151. K.cw=0;152. K.c=c;153. K.n=n;154. K.bestp=0;155. 156. /回溯搜索157. K.Backtrack(1);158. 159. deleteQ;160. deleteK.w;161. deleteK.p;162. returnK.bestp;163. 164. 165. template166. voidBubbleSort(Typea,intn)167. 168. /记录一次遍历中是否有元素的交换169. boolexchange;170. for(inti=0;in-1;i+)171. 172. exchange=false;173. for(intj=i+1;j=n-1;j+)174. 175. if(aj=aj-1)176. 177. Swap(aj,aj-1);178. exchange=true;179. 180. 181. /如果这次遍历没有元素的交换,那么排序结束182. if(false=exchange)183. 184. break;185. 186. 187. 188. 189. templatec

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1