如何生成一个多叉树?当多叉树要用远远超过系统所能提供的内存的时候怎么办?

OSNC_17 2002-05-19 01:41:42
我以前想做个具有甲级棋手水平的电脑象棋程序。我经研究发现,决定电脑象棋程序棋力的是棋树搜索的深度和广度,受微机硬件限制,要完全搜索实际要求的深度和广度的棋树需要的时间要很多,而人机对战有严格的时间限制,不能太慢,因此只有缩小搜索深度和广度,结果,程序的棋力不能达到要求,所以,我认为是不可能开发出在目前微机上使用的高水平的人机对战电脑象棋程序的。

我想做一个针对用户提供的棋局的精确求解的解题工具。
我打算用C语言作内核,因为我会C语言,正在学C++,只会用C++做个界面。
我的算法是完全搜索深度为三十层的棋树,加上α-β修剪法。
程序的运作我是这样设想:用户使用鼠标摆好棋子,设置先行方,按下开始运算按钮之后,程序开始生成棋树,估计所需计算时间,搜索棋树,使用非常简单的审局函数,只根据是否将死和子力对比判断棋步的优劣,剪去劣枝,留下优枝,最后提供给用户的是一个最佳棋树,同时还可以根据用要求,列出用户感兴趣的变化。

在这种情况下程序不受时间限制,可以完全采用搜索整个棋树的方法,这时要用很多时间,希望能像网络蚂蚁一样,不主动占用用户太多资源,不打扰用户其它工作,要能“断点续算”,就是工作可以随时停止,随时开始,不受天时地利的影响。
问题一:如何生成一个多叉树,这个支干不是事先能规定的,是根据局面产生可能的步法,产生下一层的树枝。
问题二当多叉树要用远远超过系统所能提供的内存的时候怎么办?
问题三:搜索运算非常庞大复杂,如何做到"断点续算"?
问题四:我发现运算量一大,程序就无响应,如何有效地控制程序的资源占用?我希望它利用用户闲置的资源进行运算,不允许打扰用户其它工作,更不允许出现无响应的情况。
问题五:如何估计线程运算所需的时间。
请各位最好用C语言回答我的问题,C++的也可以。我给分一定不会吝啬。谢谢!
我的邮箱:liuhaixiao1980@163.com
...全文
124 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
laizi 2002-05-19
  • 打赏
  • 举报
回复
用虚拟内存了:)
IT_worker 2002-05-19
  • 打赏
  • 举报
回复
对于多叉树、搜索等问题starfish(海星)比我更有发言权。我这里给你提供几个程序设计上的建议。
如果你的树的节点数据结构很小,那么你可能会在生成一个节点对象的时候用调你可能没有注意到的一些空间。例如:
struct node{ node*parent,*leftchild,*rightchild;int myvalue;}
那么无论你用 node *p = new node;还是 node *p = (node*)malloc(sizeof(*p)) 你实际用掉的空间都会是sizeof(node)+20个字节。特别是当你构建了很多node对象又删除了一些对象弄的c++的heap很乱的时候,你将对new一个对象的效率不能忍受。我曾经就在做空间索引树的时候深受其苦。建议你参考一下boost库的对象池的设计。也就是说你可以这样设计:
class CTree{
pool<node> m_heap;
public:
node* alloc_node(){return m_heap.alloc();}
void free_node(node*p){m_heap.free(p);}
}通过自己管理内存减少不必要的系统开销
下面是boost库的网址
http://www.boost.org/
starfish 2002-05-19
  • 打赏
  • 举报
回复
30层的博弈树,不可能吧,你到底有没有计算过30层的博弈树需要多少的存储空间呀 :-( ,就算有剪枝规模还是很大。
另外,你的说法很奇怪,什么叫做“用C语言作内核,用C++做界面”呀~~
“可以完全采用搜索整个棋树的方法”,你到底有没有计算过整个博弈树有多大,对于中国象棋而言,用现在最快的计算机计算出整个博弈树就算计算到宇宙毁灭也不会有结果。
一般只能考虑计算3~4层的博弈树,并且加上适当的剪枝,计算超过5层以上的博弈树所花的时间就太长了,用户无法忍受这种时间等待。
下面依次回答你的问题:
第一个问题:用alpha-bata剪枝法来计算博弈树,如果你不了解alpha-bata剪枝法,先找本讲算法的书看看吧;
第二个问题,windows95下面应用程序的虚存空间是2GB,如果2GB的虚存空间还不够你用的话,就只有自己管理虚存文件了,可以把内存中的数据存储在文件中。不过,如果你的博弈树大小超过2GB的话,光是在其中搜索一个节点,所化的时间就无法忍受了;
第三个问题,你应该建立一个线程来计算博弈树,当相应用户的时候暂停该线程,并根据用户的相应进行适当的剪枝,然后继续该线程,继续计算博弈树;这大概就是你所谓的断点续传吧。
第四个问题,只要把线程的优先级设置的低一点就可以了;
第五个问题,只要估计出每层博弈树的节点数目,就可以大致地估计出计算1层博弈树所需的时间。


33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧