社区
数据结构与算法
帖子详情
请教高手一个关于回溯的算法
HuangRwen
2004-12-25 11:21:58
用回溯算法,编写一个函数fill(int num, int n),用0到num-1的数填充n*n的矩阵,要求填充的数不能重复,各行元素之和相等,各列元素之和也相同,输出所有可能的填充结果。
非常感谢!!
给出个大概算法也好。
...全文
345
22
打赏
收藏
请教高手一个关于回溯的算法
用回溯算法,编写一个函数fill(int num, int n),用0到num-1的数填充n*n的矩阵,要求填充的数不能重复,各行元素之和相等,各列元素之和也相同,输出所有可能的填充结果。 非常感谢!! 给出个大概算法也好。
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
22 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
Woodman007
2005-01-05
打赏
举报
回复
"各行元素之和相等,各列元素之和也相同",这个“每行之和”是确定的:
Σ第i行之和 = 0 +1 +2 +……+(n^2-1) , 而“每行之和”是相等的,所以
“每行之和” = [ 0 +1 +2 +……+(n^2-1)]/ n = [(n+1)(2n+1)/6]-1/n
“每列之和”也一样,所以算法可以是这样:每次填一行,每行之和为[(n+1)(2n+1)/6]-1/n,不合条件就回溯
baryjim
2005-01-01
打赏
举报
回复
的确如此,我也发现了这个情况,在递增或者递减顺序下,调试中我观察数据的变化情况,真的很难做!数据在及其缓慢向目标移动,真的很心急,如果是遗传算法直接来个变异就ok了。
我想,把数据顺序打乱,以任意顺序来做也应该不错。能尽快得出一个解,但是对输出所有解帮助不大呀
chenzhichao2008
2005-01-01
打赏
举报
回复
用回朔,可以再优化一下,将数字系列分成两半(高数区和小数区)
如(01234)和(56789)
填数时,从高数区取一个数,与低位区取一个数,分别填在对称的位置
再加一些条件限制如:每一行(列)之和不能小于最大数(9)
每一行(列)之和不能大于最大数与中间数之和(9+4(5)=13(14))
这样搜索范围就大大减小了
jp1984
2005-01-01
打赏
举报
回复
回朔的话本题不是个很好的例子,本题组合数虽然大,但是构造幻方有简便方法。
HuangRwen
2005-01-01
打赏
举报
回复
是回溯了,呵呵
加上递归和组合方面, mmmcd(超超)大哥能不能给点指导?谢谢
mmmcd
2005-01-01
打赏
举报
回复
构造一个幻方有很标准的方法。
楼主感兴趣的是回溯法还是幻方?
HuangRwen
2004-12-31
打赏
举报
回复
thank you so much, baryjim!!!!
baryjim
2004-12-31
打赏
举报
回复
我的方法是用交换的方式来给2维数组赋值的,所以不用考虑数字重复的情况,故是num!级别的!
当方阵为4×4的时候,就是16!了,所以算不出来结果,看来回溯在解决这个问题上效率捉襟见肘啊!!
建议楼主换方法吧!!
baryjim
2004-12-31
打赏
举报
回复
呜呜,没有实践就没有发言权啊!!看来jp1984(吕青萍C) 的悲观是有道理的!!我做的程序,当规模达到4的时候,几乎就不出结果了!!
#include<iostream.h>
#define length 3
#define limit length*length-1
#define total (1+(limit))*(limit)/(2*length)
int a[length][length];
int b[limit];
void output()
{
for(int i=0;i<length;i++){
for(int j=0;j<length;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
//这是排列问题,所以需要用交换函数来避免重复的数字写入
void swap(int& i,int& j)
{
int k=i;
i=j;
j=k;
}
void fill(int num,int t)
{
int k=0;
int i=0;
int j=0;
int ii=0;
if (t>limit) {
cout<<"mark"<<endl;
output();
return;
}
int row=t/length;//递归n层当前所在的行和列
int column=t%length;
for(ii=t;ii<=limit;ii++){
swap(b[t],b[ii]);
for(int i=0;i<=limit;i++)
a[i/length][i%length]=b[i];//赋值
//当前赋值过的所有数组元素是否满足条件,如果有一个不满足的,则回溯
for(i=0;i<=row;i++){//检查行元素之和
k=0;
for(j=0;j<=column;j++)
k+=a[i][j];
if (k>total) {swap(b[ii],b[t]);return;}
}
for(i=0;i<=row;i++){//检查列元素之和
k=0;
for(j=0;j<=column;j++)
k+=a[j][i];
if (k>total) {swap(b[ii],b[t]);return;}
}
fill(num,t+1);//递归到下一层
swap(b[ii],b[t]);
}
}
void main()
{
for(int i=0;i<=limit;i++)
b[i]=i;
fill(limit,0);
}
baryjim
2004-12-30
打赏
举报
回复
to rickone(RickOne):
我记得幻方比这个要求高吧!!斜线也要求相等,楼主这个没要求,所以会丢解的!!
HuangRwen
2004-12-30
打赏
举报
回复
我觉得也是啊,呵呵
有没谁方便写出比较详细一点的实现供大家
参考一下?谢谢
baryjim
2004-12-30
打赏
举报
回复
楼上说的是最坏情况下,但是到达最坏情况下的概率也是很低的,所以效果没有你想象的那么糟糕。
回溯自然不是所有空格都满的情况下判断是否合适,那样就是穷举了,没填充一个空格就要判断一下,发现不合适马上回溯!!
jp1984
2004-12-30
打赏
举报
回复
构造幻方。。直接算的话 每个格要试探 num - 1次,一共n^2格。。效率太夸张了 O(num ^(n^2))
sgal
2004-12-30
打赏
举报
回复
楼主你搞懂了?
我没看懂,你在什么时候判断是否回溯?等所有的空格都填好了再判断吗?
显然不行噻,那什么时候呢?
望指教~~~
HuangRwen
2004-12-30
打赏
举报
回复
谢谢以上各位
mmmcd
2004-12-29
打赏
举报
回复
fill(int num,int n)
{
if (n==num && 各行元素之和相等,各列元素之和也相同) output();/*直接计算吧*/
for(int i=0;i<num;i++){
a[n]=i;//这里a[n]相当于把二维矩阵映射到1维上
if (condition()==true)
fill(num,n+1);
}
}
rickone
2004-12-29
打赏
举报
回复
直接用回溯会算死人的啊~~~
看看有关幻方的构造方法吧。
HuangRwen
2004-12-29
打赏
举报
回复
关键是每次填一行和一列,而不是填一个数,这个理解有没有错?
回溯时退一行还是一个数?这个condition()应该怎么写。
希望可以得到够详细一些的解释,非常感谢 mmmcd(超超),谢谢!!
谢谢baryjim
要是分不够的话可以再加.
HuangRwen
2004-12-27
打赏
举报
回复
thank you two above so much!! but there seems sth do not match the
damands--"各行元素之和相等,各列元素之和也相同".
could you please explain more explitely to me?
any reply would be appreciate.
thank you,Baryjim
baryjim
2004-12-26
打赏
举报
回复
楼主啊!!fill(int num, int n),里面得n应该不是n阶矩阵,而是递归得层次!!
用回溯的方法!!
fill(int num,int n)
{
if (n==num) output();
for(int i=0;i<num;i++){
a[n]=i;//这里a[n]相当于把二维矩阵映射到1维上
if (condition()==true)
fill(num,n+1);
}
}
加载更多回复(2)
【记录】
一个
深度学习
算法
工程师的成长之路(思考和方法以及计划)
尤其是在就业一年比一年难的情况下,经历过好多次心态崩裂,也问过很多人,来总结一下如果想成为
一个
【深度学习 CV
算法
工程师】需要什么学习能力和知识储备。 这个文章应该会是
一个
【记录】的文章,看看自己这一路...
大神的
算法
学习之路
严格来说,本文题目应该是我的数据结构和
算法
学习之路,但这个写法实在太绕口——况且CS中的
算法
往往暗指数据结构和
算法
(例如
算法
导论指的实际上是数据结构和
算法
导论),所以我认为本文题目是合理的。 原文链接:...
新手如何学习
算法
?
算法
如何入门以及零基础入门
算法
应该学些什么?
搬运工,看到一篇关于
算法
学习之路的总结,希望对你有帮助。 原文链接:zh.lucida.me/blog/on-le 我的
算法
学习之路 MAY 4TH, 2014 | COMMENTS 关于 严格来说,本文题目应该是我的数据结构和
算法
学习之路,但这个...
学习人工智能必须学习
算法
,那要怎样才能学好
算法
?
详细介绍了常见的八大数据结构。...关于数据结构,大家普遍认为难度较大的可能就是图了,本书对图的分类,图的表示方式,图的遍历,以及图的各种经典
算法
比如迪杰斯特拉
算法
,普里姆
算法
,拓扑排序等都有大量介绍。
一个
谷歌程序员的
算法
学习之路
严格来说,本文题目应该是我的数据结构和
算法
学习之路,但这个写法实在太绕口——况且CS中的
算法
往往暗指数据结构和
算法
(例如
算法
导论指的实际上是数据结构和
算法
导论),所以我认为本文题目是合理的。 这篇文章讲...
数据结构与算法
33,027
社区成员
35,335
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章