我正在从一本书中学习人工智能,这本书对我即将发布的代码解释得不够详细,我猜是因为作者假设每个人都已经体验过山地攀登算法。这个概念相当简单,但我只是不理解下面的某些代码,我希望有人能帮助我更清楚地理解这个算法,然后我再继续学习。
我已经在最让我困惑的部分旁边加了注释,这些行的总结对我会非常有帮助。
int HillClimb::CalcNodeDist(Node* A, Node* B){ int Horizontal = abs(A->_iX - B->_iX); int Vertical = abs(A->_iY - B->_iY); return(sqrt(pow(_iHorizontal, 2) + pow(_iVertical, 2)));} void HillClimb::StartHillClimb(){ BestDistance = VisitAllCities(); int CurrentDistance = BestDistance; while (true) { int i = 0; int temp = VisitAllCities(); while (i < Cities.size()) { //交换节点 Node* back = Cities.back(); Cities[Cities.size() - 1] = Cities[i]; Cities[i] = back; // 为什么要将最后一个城市与第一个城市交换? CurrentDistance = VisitAllCities(); // 为什么要再次访问所有节点? if (CurrentDistance < BestDistance) // 这是在做什么? { BestDistance = CurrentDistance; //??? break; } else { back = Cities.back(); Cities[Cities.size() - 1] = Cities[i]; Cities[i] = back; } i++; } if (CurrentDistance == temp) { break; } }}int HillClimb::VisitAllCities(){ int CurrentDistance = 0; for (unsigned int i = 0; i < Cities.size(); i++) { if (i == Cities.size() - 1)//检查是否为最后一个城市,连接回第一个城市 { CurrentDistance += CalcNodeDist(Cities[i], Cities[0]); } else { CurrentDistance += CalcNodeDist(Cities[i], Cities[i + 1]); } } return(CurrentDistance);}
此外,书中没有说明这是哪种类型的山地攀登算法。我假设这是基本的山地攀登,因为它在卡住时不会重新开始?
回答:
本质上,它用伪代码做了以下操作:
初始化一个节点顺序(即一个列表),它代表一个圆圈do{ 在列表中找到一个元素,使得将其与列表的最后一个元素交换后, 由该列表强加的圆圈长度更短}(直到找不到这样的元素)
VisitAllCities 是一个辅助函数,用于计算该圆圈的长度,CalcNodeDist 是一个辅助函数,用于计算两个节点之间的距离,外部的 while 循环是我所说的 do-until 循环,内部的 while 循环遍历所有元素。
if (CurrentDistance < BestDistance)
部分只是检查通过交换改变列表是否会导致长度变小,如果是,则更新距离,如果不是,则撤销该更改。
我是否涵盖了你想知道的一切?关于特定部分有问题吗?