蚁群算法(C++版)
- 格式:docx
- 大小:16.22 KB
- 文档页数:16
蚁群算法实现TSP蚁群算法(Ant Colony Optimization, ACO)是一种模拟蚂蚁觅食行为的算法,常被用来解决旅行商问题(Traveling Salesman Problem, TSP)。
旅行商问题是一个经典的组合优化问题,目标是找到一条最短的路径,使得旅行商能够访问所有城市并返回起始城市。
蚁群算法的基本思想是模拟蚂蚁寻找食物的行为,每只蚂蚁在过程中释放信息素,并根据信息素浓度和距离选择下一个城市。
信息素的释放和更新规则是蚁群算法的核心。
蚁群算法的实现步骤如下:1.初始化蚁群:随机放置一定数量的蚂蚁在不同城市。
2.计算路径长度:根据蚂蚁的选择规则,计算每只蚂蚁的路径长度。
3.更新信息素:根据路径长度,更新城市之间的信息素浓度。
4.更新蚂蚁的选择规则:根据信息素浓度和距离,更新蚂蚁的选择规则。
5.重复步骤2-4,直到达到指定的迭代次数或找到最优解。
在蚂蚁的选择规则中,信息素浓度和距离是两个重要的因素。
信息素浓度越高,蚂蚁越有可能选择该路径;距离越短,蚂蚁越倾向于选择该路径。
为了平衡这两个因素,通常使用一个参数来调节它们的权重。
在更新信息素时,一般采用全局信息素更新和局部信息素更新两种方式。
全局信息素更新是将所有蚂蚁路径上的信息素浓度进行更新,以加强优质路径的信息素浓度。
局部信息素更新是只更新最优路径上的信息素浓度,以加强当前最优路径的信息素浓度。
蚁群算法的优点是能够找到近似最优解,并且具有较好的鲁棒性和适应性。
然而,蚁群算法也存在一些问题,例如易陷入局部最优解、收敛速度较慢等。
针对TSP问题,蚁群算法的实现可以按照上述步骤进行。
具体来说,可以通过以下几个方面的设计来优化算法的性能:1.蚂蚁的选择规则:可以采用轮盘赌选择法,即根据信息素浓度和距离计算每个城市被选择的概率,然后根据概率选择下一个城市。
2.信息素更新:可以采用全局信息素更新和局部信息素更新相结合的方式,以平衡全局和局部的效果。
蚁群算法报告及代码一、狼群算法狼群算法是基于狼群群体智能,模拟狼群捕食行为及其猎物分配方式,抽象出游走、召唤、围攻3种智能行为以及“胜者为王”的头狼产生规则和“强者生存”的狼群更新机制,提出一种新的群体智能算法。
算法采用基于人工狼主体的自下而上的设计方法和基于职责分工的协作式搜索路径结构。
如图1所示,通过狼群个体对猎物气味、环境信息的探知、人工狼相互间信息的共享和交互以及人工狼基于自身职责的个体行为决策最终实现了狼群捕猎的全过程。
二、布谷鸟算法布谷鸟算法布谷鸟搜索算法,也叫杜鹃搜索,是一种新兴启发算法CS算法,通过模拟某些种属布谷鸟的寄生育雏来有效地求解最优化问题的算法.同时,CS也采用相关的Levy飞行搜索机制蚁群算法介绍及其源代码。
具有的优点:全局搜索能力强、选用参数少、搜索路径优、多目标问题求解能力强,以及很好的通用性、鲁棒性。
应用领域:项目调度、工程优化问题、求解置换流水车间调度和计算智能三、差分算法差分算法主要用于求解连续变量的全局优化问题,其主要工作步骤与其他进化算法基本一致,主要包括变异、交叉、选择三种操作。
算法的基本思想是从某一随机产生的初始群体开始,利用从种群中随机选取的两个个体的差向量作为第三个个体的随机变化源,将差向量加权后按照一定的规则与第三个个体求和而产生变异个体,该操作称为变异。
然后,变异个体与某个预先决定的目标个体进行参数混合,生成试验个体,这一过程称之为交叉。
如果试验个体的适应度值优于目标个体的适应度值,则在下一代中试验个体取代目标个体,否则目标个体仍保存下来,该操作称为选择。
在每一代的进化过程中,每一个体矢量作为目标个体一次,算法通过不断地迭代计算,保留优良个体,淘汰劣质个体,引导搜索过程向全局最优解逼近。
四、免疫算法免疫算法是一种具有生成+检测的迭代过程的搜索算法。
从理论上分析,迭代过程中,在保留上一代最佳个体的前提下,遗传算法是全局收敛的。
五、人工蜂群算法人工蜂群算法是模仿蜜蜂行为提出的一种优化方法,是集群智能思想的一个具体应用,它的主要特点是不需要了解问题的特殊信息,只需要对问题进行优劣的比较,通过各人工蜂个体的局部寻优行为,最终在群体中使全局最优值突现出来,有着较快的收敛速度。
蚁群算法在求解车辆路径安排问题中的应用蚁群算法(Ant Colony Optimization,ACO)是一种启发式算法,受到蚂蚁觅食行为的启发,可以用于求解许多组合优化问题,如旅行商问题(TSP),车辆路径安排问题等。
本文将重点讨论蚁群算法在车辆路径安排问题中的应用。
车辆路径安排问题是指在给定一组顾客需求和一部分可用车辆的情况下,如何最优地分配车辆并安排它们的路线,以最小化总成本(如总行驶距离、总行驶时间等)。
这个问题可以建模为一个组合优化问题,其中顾客需求可看作任务,车辆可看作资源。
蚁群算法通过模拟蚂蚁的觅食行为,寻求全局最优解。
蚁群算法的基本原理是通过模拟多个蚂蚁的觅食行为,逐步寻找更优解。
具体来说,每个蚂蚁在选择下一个顾客需求时,会根据当前信息素浓度和启发式信息做出决策。
信息素是一种蚂蚁在路径选择时释放的化学物质,用于传递蚂蚁对路径的偏好程度。
启发式信息是一种指导蚂蚁决策的启发式规则,如距离、需求等。
每个蚂蚁完成一次路径选择后,会更新路径上的信息素浓度,并根据选择的路径更新信息素。
蚂蚁的路径选择决策是一个随机的过程,但信息素浓度和启发式信息会对蚂蚁的选择起到指导作用。
信息素浓度高的路径会被更多的蚂蚁选择,这种选择行为会进一步增加路径上的信息素浓度。
而启发式信息则会影响蚂蚁的偏好,使其更倾向于选择比较优的路径。
在求解车辆路径安排问题中,蚁群算法可以按以下步骤进行:1.初始化信息素:将所有路径上的信息素浓度初始化为一个较小的值。
初始化启发式信息。
2.模拟蚂蚁觅食行为:多个蚂蚁同时进行路径选择,每个蚂蚁根据当前信息素浓度和启发式信息,选择下一个最优的顾客需求。
模拟蚂蚁的移动过程,直到所有蚂蚁完成路径选择。
3.更新信息素:每个蚂蚁完成路径选择后,更新路径上的信息素浓度。
信息素的更新可以采用一种蒸发和增加的策略,即每轮迭代后,信息素会以一定的速率蒸发,并根据蚂蚁选择的路径增加信息素。
4.判断终止条件:当达到迭代次数或满足特定的停止条件时,终止算法。
蚁群算法公式范文蚁群算法(Ant Colony Optimization, ACO)是一种仿生智能算法,源于对蚂蚁在寻找食物过程中的观察和分析。
蚁群算法通过模拟蚂蚁在寻找食物的过程,来优化解决各种优化问题。
在蚁群算法中,蚂蚁使用信息素和启发式信息来进行,并通过信息素更新和路径选择机制来不断优化过程。
蚂蚁在寻找食物的过程中会释放一种被称为“信息素”的化学物质。
当蚂蚁在条路径上行走时,会释放信息素,而其他蚂蚁通过检测到信息素的浓度来选择路径。
信息素的浓度越高,路径上的蚂蚁越多,其他蚂蚁就更有可能选择这条路径。
蚂蚁在行走结束后,会按照规定的方式更新路径上的信息素浓度。
蚂蚁选择路径的依据除了信息素,还有启发式信息。
启发式信息是根据蚂蚁当前所处位置与目标位置之间的距离进行计算的。
蚂蚁更倾向于选择距离目标位置更近的路径。
启发式信息对蚂蚁的路径选择起到了一定的引导作用。
蚁群算法中的公式主要涉及到信息素的更新和路径选择机制。
下面是蚁群算法中常用的公式:1.信息素的更新公式:τij(t+1) = (1-ρ) * τij(t) + Δτij(t)其中,τij(t+1)为第i只蚂蚁在第j条路径上的信息素浓度更新后的值;τij(t)为第i只蚂蚁在第j条路径上的当前信息素浓度;Δτij(t)为第i只蚂蚁在第j条路径上释放的信息素量;ρ为信息素蒸发系数,用于控制信息素的挥发速度。
2.蚂蚁选择路径的概率公式:Pij(t) = (τij(t)^α) * (ηij(t)^β) / Σ(τik(t)^α) * (ηik(t)^β)其中,Pij(t)为第i只蚂蚁在第j条路径上的选择概率;τij(t)为第i只蚂蚁在第j条路径上的信息素浓度;ηij(t)为第i只蚂蚁在第j条路径上的启发式信息;α和β分别为信息素和启发式信息的重要程度参数。
3.蚂蚁更新路径的公式:Δτij(t) = Q / Lk其中,Δτij(t)为第i只蚂蚁在第j条路径上释放的信息素量;Q为常数,表示每只蚂蚁释放的信息素总量;Lk为第k只蚂蚁的路径长度。
蚁群算法内容简介蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法群算法是由意大利学者Dorigo等人于20世纪90年代初期通过模拟自然界中蚂蚁集体寻经的行为而提出的一种基于种群的启发式随机搜索算法,蚁群算法具有并行性、鲁棒性、正反馈性等特点.蚁群算法最早成功应用于解决著名的旅行商问题以及二次分配问题、车间任务调度问题、图的着色问题、网络路由等许多复杂的组合问题。
蚁群算法是一种模拟进化算法,初步的研究表明该算法具有许多优良的性质.针对PID控制器参数优化设计问题,将蚁群算法设计的结果与遗传算法设计的结果进行了比较,数值仿真结果表明,蚁群算法具有一种新的模拟进化优化方法的有效性和应用价值。
随着人们对效益的要求越来越高,人们发现组合优化的各种方法,但在一些复杂度比较高的问题上,一些传统的方法显示了他的限制,列如计算量上升太快,时间复杂度很高,这就需要一些新的方法来解决这些问题,从而有效地克服传统蚁群算法中容易陷入局部最优解和收敛速度慢的现象。
蚁群系统(Ant Colony System),这种算法是目前国内外启发式算法中的研究热点和前沿课题,被成功地运用于旅行商问题的求解,蚁群算法在求解复杂优化问题方面具有很大的优越性和广阔的前景。
但是,根据观察实验发现,蚁群中的多个蚂蚁的运动是随机的,在扩散范围较大时,在较短时间内很难找出一条较好的路径,在算法实现的过程中容易出现停滞现象和收敛速度慢现象。
在这种弊端的情况下,学者们提出了一种自适应蚁群算法,通过自适应地调整运行过程中的挥发因子来改变路径中信息素浓度,从而有效地克服传统蚁群算法中容易陷入局部最优解和收敛速度慢的现象。
下面是一些最常用的变异蚁群算法精英蚂蚁系统全局最优解决方案在每个迭代以及其他所有的蚂蚁的沉积信息素.最大最小蚂蚁系统( MMAS)添加的最大和最小的信息素量[ τmax ,τmin ],只有全局最佳或迭代最好的巡逻沉积的信息素。
蚁群算法及算例范文蚁群算法的核心思想是通过模拟蚂蚁在路径选择过程中释放的信息素来寻找到达目标的最优路径。
蚂蚁在觅食过程中会释放一种化学物质(信息素),用于标记已经走过的路径。
当其他蚂蚁经过时,会受到这些信息素的影响,从而倾向于选择已经标记过的路径。
通过这种方式,蚂蚁群体能够找到从巢穴到食物的最短路径。
蚁群算法的算例可以参考旅行商问题(TSP,Traveling Salesman Problem)。
旅行商问题是一种经典的组合优化问题,要求在给定的城市之间找到最短的回路,使得每个城市恰好访问一次。
下面是一个应用蚁群算法解决旅行商问题的算例:1.初始化城市和蚂蚁的信息。
2.随机放置若干蚂蚁在城市中。
3.每只蚂蚁根据当前城市和信息素浓度选择下一个城市。
选择过程可以使用蚂蚁选择概率来确定,概率与信息素浓度和距离有关。
假设蚂蚁A 位于城市B,需要选择下一个城市C,蚂蚁选择概率计算公式如下:p(C)=(τ(B,C)^α)*(η(B,C)^β)/Σ[(τ(B,i)^α)*(η(B,i)^β)]其中τ(B,C)表示城市B到城市C之间的信息素浓度,η(B,C)表示城市B到城市C的适应度(与距离相关),α和β是调节信息素和适应度对蚂蚁选择的相对重要性的参数。
4.更新信息素。
当所有蚂蚁行走完成后,根据蚂蚁走过的路径长度更新信息素浓度。
更新公式如下:Δτ(B,C)=Q/L其中Δτ(B,C)表示城市B到城市C之间的信息素增量,Q是常数,L 是蚂蚁行走的路径长度。
5.重复步骤3和步骤4直到满足终止条件。
通常终止条件可以是达到最大迭代次数或者找到最优路径。
6.输出蚂蚁群体找到的最优路径和路径长度。
蚁群算法通过模拟蚂蚁觅食行为,利用信息素的正反馈机制,能够在很短的时间内找到高质量的解。
它被广泛应用于旅行商问题、资源调度问题、网络优化问题等领域。
这里发个贴吧里面的蚁群算法代码。
// AO.cpp : 定义控制台应用程序的入口点。
#pragma once#include <iostream>#include <math.h>#include <time.h>const double ALPHA=1.0; //启发因子,信息素的重要程度const double BETA=2.0; //期望因子,城市间距离的重要程度const double ROU=0.5; //信息素残留参数const int N_ANT_COUNT=34; //蚂蚁数量const int N_IT_COUNT=1000; //迭代次数const int N_CITY_COUNT=51; //城市数量const double DBQ=100.0; //总的信息素const double DB_MAX=10e9; //一个标志数,10的9次方double g_Trial[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间信息素,就是环境信息素double g_Distance[N_CITY_COUNT][N_CITY_COUNT]; //两两城市间距离//eil51.tsp城市坐标数据double x_Ary[N_CITY_COUNT]={37,49,52,20,40,21,17,31,52,51,42,31,5,12,36,52,27,17,13,57,62,42,16,8,7,27,30,43,58,58,37,38,46,61,62,63,32,45,59,5,10,21,5,30,39,32,25,25,48,56,30};double y_Ary[N_CITY_COUNT]={52,49,64,26,30,47,63,62,33,21,41,32,25,42,16,41,23,33,13,58,42,57,57,52,38,68,48,67,48,27,69,46,10,33,63,69,22,35,15,6,17,10,64,15,10,39,32,55,28,37,40};//返回指定范围内的随机整数int rnd(int nLow,int nUpper){return nLow+(nUpper-nLow)*rand()/(RAND_MAX+1);}//返回指定范围内的随机浮点数double rnd(double dbLow,double dbUpper){double dbTemp=rand()/((double)RAND_MAX+1.0);return dbLow+dbTemp*(dbUpper-dbLow);}//返回浮点数四舍五入取整后的浮点数double ROUND(double dbA){return (double)((int)(dbA+0.5));}//定义蚂蚁类class CAnt{public:CAnt(void);~CAnt(void);public:int m_nPath[N_CITY_COUNT]; //蚂蚁走的路径double m_dbPathLength; //蚂蚁走过的路径长度int m_nAllowedCity[N_CITY_COUNT]; //没去过的城市 int m_nCurCityNo; //当前所在城市编号int m_nMovedCityCount; //已经去过的城市数量public:int ChooseNextCity(); //选择下一个城市void Init(); //初始化void Move(); //蚂蚁在城市间移动void Search(); //搜索路径void CalPathLength(); //计算蚂蚁走过的路径长度};//构造函数CAnt::CAnt(void){}//析构函数CAnt::~CAnt(void){}//初始化函数,蚂蚁搜索前调用void CAnt::Init(){for (int i=0;i<N_CITY_COUNT;i++){m_nAllowedCity[i]=1; //设置全部城市为没有去过 m_nPath[i]=0; //蚂蚁走的路径全部设置为0}//蚂蚁走过的路径长度设置为0m_dbPathLength=0.0;//随机选择一个出发城市m_nCurCityNo=rnd(0,N_CITY_COUNT);//把出发城市保存入路径数组中m_nPath[0]=m_nCurCityNo;//标识出发城市为已经去过了m_nAllowedCity[m_nCurCityNo]=0;//已经去过的城市数量设置为1m_nMovedCityCount=1;}//选择下一个城市//返回值为城市编号int CAnt::ChooseNextCity(){int nSelectedCity=-1; //返回结果,先暂时把其设置为-1//============================================================================ ==//计算当前城市和没去过的城市之间的信息素总和double dbTotal=0.0;double prob[N_CITY_COUNT]; //保存各个城市被选中的概率for (int i=0;i<N_CITY_COUNT;i++){if (m_nAllowedCity[i] == 1) //城市没去过{prob[i]=pow(g_Trial[m_nCurCityNo][i],ALPHA)*pow(1.0/g_Distance[m_nCurCityNo][i],BET A); //该城市和当前城市间的信息素dbTotal=dbTotal+prob[i]; //累加信息素,得到总和}else //如果城市去过了,则其被选中的概率值为0{prob[i]=0.0;}}//============================================================================ ==//进行轮盘选择double dbTemp=0.0;if (dbTotal > 0.0) //总的信息素值大于0{dbTemp=rnd(0.0,dbTotal); //取一个随机数for (int i=0;i<N_CITY_COUNT;i++){if (m_nAllowedCity[i] == 1) //城市没去过{dbTemp=dbTemp-prob[i]; //这个操作相当于转动轮盘,如果对轮盘选择不熟悉,仔细考虑一下if (dbTemp < 0.0) //轮盘停止转动,记下城市编号,直接跳出循环{nSelectedCity=i;break;}}}}//============================================================================ ==//如果城市间的信息素非常小( 小到比double能够表示的最小的数字还要小)//那么由于浮点运算的误差原因,上面计算的概率总和可能为0//会出现经过上述操作,没有城市被选择出来//出现这种情况,就把第一个没去过的城市作为返回结果//题外话:刚开始看的时候,下面这段代码困惑了我很长时间,想不通为何要有这段代码,后来才搞清楚。
蚁群算法及其应用研究蚁群算法是一种源于自然界中蚂蚁觅食行为的优化算法,它通过模拟蚂蚁之间的信息交流和协作行为来寻找最优解。
近年来,蚁群算法在许多领域得到了广泛的应用,包括机器学习、数据挖掘、运筹学等。
本文将对蚁群算法的原理、实现方式以及应用进行详细的阐述。
蚁群算法是一种启发式优化算法,其核心思想是利用蚂蚁在寻找食物过程中的行为特征来寻找问题的最优解。
蚂蚁在寻找食物的过程中,会在路径上留下信息素,后续的蚂蚁会根据信息素的强度选择路径,并且也会在路径上留下信息素。
这样,随着时间的推移,越来越多的蚂蚁会选择信息素浓度较高的路径,从而找到问题的最优解。
蚁群算法的实现包括两个关键步骤:构造解和更新信息素。
在构造解的过程中,每只蚂蚁根据自己的概率选择下一个节点,这个概率与当前节点和候选节点的信息素以及距离有关。
在更新信息素的过程中,蚂蚁会在构造解的过程中更新路径上的信息素,以便后续的蚂蚁能够更好地找到最优解。
蚁群算法在许多领域都得到了广泛的应用。
在机器学习领域,蚁群算法被用来提高模型的性能和效果。
例如,在推荐系统中,蚁群算法被用来优化用户和物品之间的匹配,从而提高推荐准确率;在图像处理中,蚁群算法被用来进行特征选择和图像分割,从而提高图像处理的效果。
此外,蚁群算法在数据挖掘、运筹学等领域也有着广泛的应用。
总的来说,蚁群算法是一种具有潜力的优化算法,它具有分布式、自组织、鲁棒性强等优点。
然而,蚁群算法也存在一些不足之处,如易陷入局部最优解、算法参数难以调整等。
未来,可以进一步研究如何提高蚁群算法的搜索能力和优化效果,以及如何将其应用到更多的领域中。
同时,可以通过研究如何克服蚁群算法的不足之处,例如通过引入其他优化算法或者改进信息素更新策略等,来进一步提高蚁群算法的性能。
此外,随着大数据和技术的快速发展,蚁群算法在处理大规模数据问题方面也具有很大的潜力。
例如,在推荐系统中,可以利用蚁群算法处理用户和物品之间复杂的关系网络;在图像处理中,可以利用蚁群算法进行高维数据的特征选择和分类等。
蚁群算法(C语⾔实现)蚁群算法(ant colony optimization, ACO),⼜称蚂蚁算法,是⼀种⽤来在图中寻找优化路径的机率型算法。
它由Marco Dorigo于1992年在他的中提出,其灵感来源于蚂蚁在寻找⾷物过程中发现路径的⾏为。
蚁群算法是⼀种模拟进化算法,初步的研究表明该算法具有许多优良的性质.针对参数优化设计问题,将蚁群算法设计的结果与遗传算法设计的结果进⾏了⽐较,数值仿真结果表明,蚁群算法具有⼀种新的模拟进化优化⽅法的有效性和应⽤价值。
预期的结果: 各个蚂蚁在没有事先告诉他们⾷物在什么地⽅的前提下开始寻找⾷物。
当⼀只找到⾷物以后,它会向⼀种信息素,吸引其他的蚂蚁过来,这样越来越多的蚂蚁会找到⾷物!有些蚂蚁并没有象其它蚂蚁⼀样总重复同样的路,他们会另辟蹊径,如果令开辟的道路⽐原来的其他道路更短,那么,渐渐,更多的蚂蚁被吸引到这条较短的路上来。
最后,经过⼀段时间运⾏,可能会出现⼀条最短的路径被⼤多数蚂蚁重复着。
原理: 为什么⼩⼩的蚂蚁能够找到⾷物?他们具有智能么?设想,如果我们要为蚂蚁设计⼀个⼈⼯智能的程序,那么这个程序要多么复杂呢?⾸先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到⾷物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且⽐较它们的⼤⼩,⽽且更重要的是,你要⼩⼼翼翼的编程,因为程序的错误也许会让你前功尽弃。
这是多么不可思议的程序!太复杂了,恐怕没⼈能够完成这样繁琐冗余的程序。
然⽽,事实并没有你想得那么复杂,上⾯这个程序每个蚂蚁的核⼼程序编码不过100多⾏!为什么这么简单的程序会让蚂蚁⼲这样复杂的事情?答案是:简单规则的涌现。
事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关⼼很⼩范围内的眼前信息,⽽且根据这些局部信息利⽤⼏条简单的规则进⾏决策,这样,在蚁群这个集体⾥,复杂性的⾏为就会凸现出来。
蚁群算法⼩程序(CC++语⾔实现)源代码如下:/*ant.c*/#define SPACE 0x20#define ESC 0x1b#define ANT_CHAR_EMPTY '+'#define ANT_CHAR_FOOD 153#define HOME_CHAR 'H'#define FOOD_CHAR 'F'#define FOOD_CHAR2 'f'#define FOOD_HOME_COLOR 12#define BLOCK_CHAR 177#define MAX_ANT 50#define INI_SPEED 3#define MAXX 80#define MAXY 23#define MAX_FOOD 10000#define TARGET_FOOD 200#define MAX_SMELL 5000#define SMELL_DROP_RATE 0.05#define ANT_ERROR_RATE 0.02#define ANT_EYESHOT 3#define SMELL_GONE_SPEED 50#define SMELL_GONE_RATE 0.05#define TRACE_REMEMBER 50#define MAX_BLOCK 100#define NULL 0#define UP 1#define DOWN 2#define LEFT 3#define RIGHT 4#define SMELL_TYPE_FOOD 0#define SMELL_TYPE_HOME 1#include "stdio.h"#include "conio.h"#include "dos.h"#include "stdlib.h"#include "dos.h"#include "process.h"#include "ctype.h"#include "math.h"void WorldInitial(void);void BlockInitial(void);void CreatBlock(void);void SaveBlock(void);void LoadBlock(void);void HomeFoodInitial(void);void AntInitial(void);void WorldChange(void);void AntMove(void);void AntOneStep(void);void DealKey(char key);void ClearSmellDisp(void);void DispSmell(int type);int AntNextDir(int xxx,int yyy,int ddir);int GetMaxSmell(int type,int xxx,int yyy,int ddir);int IsTrace(int xxx,int yyy);int MaxLocation(int num1,int num2,int num3);int CanGo(int xxx,int yyy,int ddir);int JudgeCanGo(int xxx,int yyy);int TurnLeft(int ddir);int TurnRight(int ddir);int TurnBack(int ddir);int MainTimer(void);char WaitForKey(int secnum);void DispPlayTime(void);int TimeUse(void);void HideCur(void);void ResetCur(void);/* --------------- */struct HomeStruct{int xxx,yyy;int amount;int TargetFood;}home;struct FoodStruct{int xxx,yyy;int amount;}food;struct AntStruct{int xxx,yyy;int dir;int speed;int SpeedTimer;int food;int SmellAmount[2];int tracex[TRACE_REMEMBER];int tracey[TRACE_REMEMBER];int TracePtr;int IQ;}ant[MAX_ANT];int AntNow;int timer10ms;struct time starttime,endtime;int Smell[2][MAXX+1][MAXY+1];int block[MAXX+1][MAXY+1];int SmellGoneTimer;int SmellDispFlag;int CanFindFood;int HardtoFindPath;/* ----- Main -------- */void main(void){char KeyPress;int tu;clrscr();HideCur();WorldInitial();do{timer10ms = MainTimer();if(timer10ms) AntMove();if(timer10ms) WorldChange();tu = TimeUse();if(tu>=60&&!CanFindFood){gotoxy(1,MAXY+1);printf("Can not find food, maybe a block world."); WaitForKey(10);WorldInitial();}if(tu>=180&&home.amount<100&&!HardtoFindPath){gotoxy(1,MAXY+1);printf("God! it is so difficult to find a path.");if(WaitForKey(10)==0x0d) WorldInitial();else{HardtoFindPath = 1;gotoxy(1,MAXY+1);printf(" ");}}if(home.amount>=home.TargetFood){gettime(&endtime);KeyPress = WaitForKey(60);DispPlayTime();WaitForKey(10);WorldInitial();}else if(kbhit()){KeyPress = getch();DealKey(KeyPress);}else KeyPress = NULL;}while(KeyPress!=ESC);gettime(&endtime);DispPlayTime();WaitForKey(10);clrscr();ResetCur();}/* ------ general sub process ----------- */int MainTimer(void)/* output: how much 10ms have pass from last time call this process */{static int oldhund,oldsec;struct time t;int timeuse;gettime(&t);timeuse = 0;if(t.ti_hund!=oldhund){if(t.ti_sec!=oldsec){timeuse+=100;oldsec = t.ti_sec;}timeuse+=t.ti_hund-oldhund;oldhund = t.ti_hund;}else timeuse = 0;return (timeuse);}char WaitForKey(int secnum)/* funtion: if have key in, exit immediately, else wait 'secnum' senconds then exit input: secnum -- wait this senconds, must < 3600 (1 hour)output: key char, if no key in(exit when timeout), return NULL */{int secin,secnow;int minin,minnow;int hourin,hournow;int secuse;struct time t;gettime(&t);secin = t.ti_sec;minin = t.ti_min;hourin = t.ti_hour;do{if(kbhit()) return(getch());gettime(&t);secnow = t.ti_sec;minnow = t.ti_min;hournow = t.ti_hour;if(hournow!=hourin) minnow+=60;if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin); else secuse = secnow - secin;/* counting error check */if(secuse<0){gotoxy(1,MAXY+1);printf("Time conuting error, any keyto exit...");getch();exit(3);}}while(secuse<=secnum);return (NULL);}void DispPlayTime(void){int ph,pm,ps;ph = endtime.ti_hour - starttime.ti_hour;pm = endtime.ti_min - starttime.ti_min;ps = endtime.ti_sec - starttime.ti_sec;if(ph<0) ph+=24;if(pm<0) { ph--; pm+=60; }if(ps<0) { pm--; ps+=60; }gotoxy(1,MAXY+1);printf("Time use: %d hour- %d min- %d sec ",ph,pm,ps);}int TimeUse(void){int ph,pm,ps;gettime(&endtime);ph = endtime.ti_hour - starttime.ti_hour;pm = endtime.ti_min - starttime.ti_min;ps = endtime.ti_sec - starttime.ti_sec;if(ph<0) ph+=24;if(pm<0) { ph--; pm+=60; }if(ps<0) { pm--; ps+=60; }return(ps+(60*(pm+60*ph)));}void HideCur(void){union REGS regs0;regs0.h.ah=1;regs0.h.ch=0x30;regs0.h.cl=0x31;int86(0x10,®s0,®s0);}void ResetCur(void){union REGS regs0;regs0.h.ah=1;regs0.h.ch=0x06;regs0.h.cl=0x07;int86(0x10,®s0,®s0);}/* ------------ main ANT programe ------------- */void WorldInitial(void){int k,i,j;randomize();clrscr();HomeFoodInitial();for(AntNow=0;AntNow<MAX_ANT;AntNow++){AntInitial();} /* of for AntNow */;BlockInitial();for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j] = 0;SmellGoneTimer = 0;gettime(&starttime);SmellDispFlag = 0;CanFindFood = 0;HardtoFindPath = 0;}void BlockInitial(void){int i,j;int bn;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)block[i][j] = 0;bn = 1+ MAX_BLOCK/2 + random(MAX_BLOCK/2);for(i=0;i<=bn;i++) CreatBlock();}void CreatBlock(void){int x1,y1,x2,y2;int dx,dy;int i,j;x1 = random(MAXX)+1;y1 = random(MAXY)+1;dx = random(MAXX/10)+1;dy = random(MAXY/10)+1;x2 = x1+dx;y2 = y1+dy;if(x2>MAXX) x2 = MAXX;if(y2>MAXY) y2 = MAXY;if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2) return;if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2) return; for(i=x1;i<=x2;i++)for(j=y1;j<=y2;j++){block[i][j] = 1;gotoxy(i,j);putch(BLOCK_CHAR);}}void SaveBlock(void){FILE *fp_block;char FileNameBlock[20];int i,j;gotoxy(1,MAXY+1);printf(" ");gotoxy(1,MAXY+1);printf("Save to file...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");else strcat(FileNameBlock,".ant");if ((fp_block = fopen(FileNameBlock, "wb")) == NULL){ gotoxy(1,MAXY+1);printf("Creat file %s fail...",FileNameBlock);getch();exit(2);}gotoxy(1,MAXY+1);printf(" ");fputc(home.xxx,fp_block);fputc(home.yyy,fp_block);fputc(food.xxx,fp_block);fputc(food.yyy,fp_block);for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)fputc(block[i][j],fp_block);fclose(fp_block);}void LoadBlock(void){FILE *fp_block;char FileNameBlock[20];int i,j,k;gotoxy(1,MAXY+1);printf(" ");gotoxy(1,MAXY+1);printf("Load file...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant");else strcat(FileNameBlock,".ant");if ((fp_block = fopen(FileNameBlock, "rb")) == NULL){ gotoxy(1,MAXY+1);printf("Open file %s fail...",FileNameBlock);getch();exit(2);}clrscr();home.xxx = fgetc(fp_block);home.yyy = fgetc(fp_block);food.xxx = fgetc(fp_block);food.yyy = fgetc(fp_block);gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR);food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1;/* food.amount = MAX_FOOD; */home.amount = 0;home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; for(AntNow=0;AntNow<MAX_ANT;AntNow++){AntInitial();} /* of for AntNow */;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++){block[i][j] = fgetc(fp_block);if(block[i][j]){gotoxy(i,j);putch(BLOCK_CHAR);}}for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j] = 0;SmellGoneTimer = 0;gettime(&starttime);SmellDispFlag = 0;CanFindFood = 0;HardtoFindPath = 0;fclose(fp_block);}void HomeFoodInitial(void){int randnum;int homeplace;/* 1 -- home at left-up, food at right-down2 -- home at left-down, food at right-up3 -- home at right-up, food at left-down4 -- home at right-down, food at left-up */randnum = random(100);if(randnum<25) homeplace = 1;else if (randnum>=25&&randnum<50) homeplace = 2;else if (randnum>=50&&randnum<75) homeplace = 3;else homeplace = 4;switch(homeplace){case 1: home.xxx = random(MAXX/3)+1;home.yyy = random(MAXY/3)+1;food.xxx = random(MAXX/3)+2*MAXX/3+1;food.yyy = random(MAXY/3)+2*MAXY/3+1;break;case 2: home.xxx = random(MAXX/3)+1;home.yyy = random(MAXY/3)+2*MAXY/3+1;food.xxx = random(MAXX/3)+2*MAXX/3+1;food.yyy = random(MAXY/3)+1;break;case 3: home.xxx = random(MAXX/3)+2*MAXX/3+1;home.yyy = random(MAXY/3)+1;food.xxx = random(MAXX/3)+1;food.yyy = random(MAXY/3)+2*MAXY/3+1;break;case 4: home.xxx = random(MAXX/3)+2*MAXX/3+1;home.yyy = random(MAXY/3)+2*MAXY/3+1;food.xxx = random(MAXX/3)+1;food.yyy = random(MAXY/3)+1;break;}food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1;/* food.amount = MAX_FOOD; */home.amount = 0;home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; /* data correctness check */if(home.xxx<=0||home.xxx>MAXX||home.yyy<=0||home.yyy>MAXY||food.xxx<=0||food.xxx>MAXX||food.yyy<=0||food.yyy>MAXY||food.amount<=0){gotoxy(1,MAXY+1);printf("World initial fail, any key to exit...");getch();exit(2);}gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR);}void AntInitial(void)/* initial ant[AntNow] */{int randnum;int i;ant[AntNow].xxx = home.xxx;ant[AntNow].yyy = home.yyy;randnum = random(100);if(randnum<25) ant[AntNow].dir = UP;else if (randnum>=25&&randnum<50) ant[AntNow].dir = DOWN;else if (randnum>=50&&randnum<75) ant[AntNow].dir = LEFT;else ant[AntNow].dir = RIGHT;ant[AntNow].speed = 2*(random(INI_SPEED/2)+1);ant[AntNow].SpeedTimer = 0;ant[AntNow].food = 0;ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0;ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL;ant[AntNow].IQ = 1;for(i=0;i<TRACE_REMEMBER;i++){ant[AntNow].tracex[i] = 0;ant[AntNow].tracey[i] = 0;}ant[AntNow].TracePtr = 0;/* a sepecail ant */if(AntNow==0) ant[AntNow].speed = INI_SPEED;}void WorldChange(void){int k,i,j;int smelldisp;SmellGoneTimer+=timer10ms;if(SmellGoneTimer>=SMELL_GONE_SPEED){SmellGoneTimer = 0;for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000;if(SmellDispFlag){gotoxy(i,j);if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/* don't over write Food and Home */;else{if(smelldisp>9) putch('#');else putch(smelldisp+'0');}}Smell[k][i][j]-= 1+(Smell[k][i][j]*SMELL_GONE_RATE);if(Smell[k][i][j]<0) Smell[k][i][j] = 0;if(SmellDispFlag){if(Smell[k][i][j]<=2){gotoxy(i,j);putch(SPACE);}}}} /* of one location */} /* of time to change the world */} /* of world change */void AntMove(void){int antx,anty;int smelltodrop,smellnow;for(AntNow=0;AntNow<MAX_ANT;AntNow++){ant[AntNow].SpeedTimer+=timer10ms;if(ant[AntNow].SpeedTimer>=ant[AntNow].speed){ant[AntNow].SpeedTimer = 0;gotoxy(ant[AntNow].xxx,ant[AntNow].yyy);putch(SPACE);AntOneStep();gotoxy(ant[AntNow].xxx,ant[AntNow].yyy);/* ant0 is a sepecail ant, use different color */if(AntNow==0) textcolor(0xd);if(ant[AntNow].food) putch(ANT_CHAR_FOOD);else putch(ANT_CHAR_EMPTY);if(AntNow==0) textcolor(0x7);/* remember trace */ant[AntNow].tracex[ant[AntNow].TracePtr] = ant[AntNow].xxx;ant[AntNow].tracey[ant[AntNow].TracePtr] = ant[AntNow].yyy;if(++(ant[AntNow].TracePtr)>=TRACE_REMEMBER) ant[AntNow].TracePtr = 0;/* drop smell */antx = ant[AntNow].xxx;anty = ant[AntNow].yyy;if(ant[AntNow].food)/* have food, looking for home */{if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]){smellnow = Smell[SMELL_TYPE_FOOD][antx][anty];smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]*SMELL_DROP_RATE;if(smelltodrop>smellnow) Smell[SMELL_TYPE_FOOD][antx][anty] = smelltodrop;/* else Smell[...] = smellnow */ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]-= smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]<0) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; } /* of have smell to drop */} /* of have food */else/* no food, looking for food */{if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]){smellnow = Smell[SMELL_TYPE_HOME][antx][anty];smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_HOME]*SMELL_DROP_RATE;if(smelltodrop>smellnow) Smell[SMELL_TYPE_HOME][antx][anty] = smelltodrop;/* else Smell[...] = smellnow */ant[AntNow].SmellAmount[SMELL_TYPE_HOME]-= smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]<0) ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; } /* of have smell to drop */}} /* of time to go *//* else not go */} /* of for AntNow */textcolor(FOOD_HOME_COLOR);gotoxy(home.xxx,home.yyy); putch(HOME_CHAR);gotoxy(food.xxx,food.yyy);if(food.amount>0) putch(FOOD_CHAR);else putch(FOOD_CHAR2);textcolor(7);gotoxy(1,MAXY+1);printf("Food %d, Home %d ",food.amount,home.amount);}void AntOneStep(void){int ddir,tttx,ttty;int i;ddir = ant[AntNow].dir;tttx = ant[AntNow].xxx;ttty = ant[AntNow].yyy;ddir = AntNextDir(tttx,ttty,ddir);switch(ddir){case UP: ttty--;break;case DOWN: ttty++;break;case LEFT: tttx--;break;case RIGHT: tttx++;break;default: break;} /* of switch dir */ant[AntNow].dir = ddir;ant[AntNow].xxx = tttx;ant[AntNow].yyy = ttty;if(ant[AntNow].food)/* this ant carry with food, search for home */{if(tttx==home.xxx&&ttty==home.yyy){home.amount++;AntInitial();}if(tttx==food.xxx&&ttty==food.yyy)ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; } /* of search for home */else/* this ant is empty, search for food */{if(tttx==food.xxx&&ttty==food.yyy){if(food.amount>0){ant[AntNow].food = 1;food.amount--;ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0;ant[AntNow].dir = TurnBack(ant[AntNow].dir);for(i=0;i<TRACE_REMEMBER;i++){ant[AntNow].tracex[i] = 0;ant[AntNow].tracey[i] = 0;}ant[AntNow].TracePtr = 0;CanFindFood = 1;} /* of still have food */}if(tttx==home.xxx&&ttty==home.yyy)ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL; } /* of search for food */}void DealKey(char key){int i;switch(key){case 'p': gettime(&endtime);DispPlayTime();getch();gotoxy(1,MAXY+1);for(i=1;i<=MAXX-1;i++) putch(SPACE); break;case 't': if(SmellDispFlag){SmellDispFlag=0;ClearSmellDisp();}else SmellDispFlag = 1;break;case '1': DispSmell(SMELL_TYPE_FOOD); getch();ClearSmellDisp();break;case '2': DispSmell(SMELL_TYPE_HOME); getch();ClearSmellDisp();break;case '3': DispSmell(2);getch();ClearSmellDisp();break;case 's': SaveBlock();break;case 'l': LoadBlock();break;default: gotoxy(1,MAXY+1);for(i=1;i<=MAXX-1;i++) putch(SPACE); } /* of switch */}void ClearSmellDisp(void){int k,i,j;for(k=0;k<=1;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){gotoxy(i,j);putch(SPACE);}} /* of one location */}void DispSmell(int type)/* input: 0 -- Only display food smell1 -- Only display home smell2 -- Display both food and home smell*/{int k,i,j;int fromk,tok;int smelldisp;switch(type){case 0: fromk = 0;tok = 0;break;case 1: fromk = 1;tok = 1;break;case 2: fromk = 0;tok = 1;break;default:fromk = 0;tok = 1;break;}SmellGoneTimer = 0;for(k=fromk;k<=tok;k++)/* SMELL TYPE FOOD and HOME */for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000;gotoxy(i,j);if(i!=food.xxx||j!=food.yyy){if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/* don't over write Food and Home */;else{if(smelldisp>9) putch('#');else putch(smelldisp+'0');}}}} /* of one location */}int AntNextDir(int xxx,int yyy,int ddir){int randnum;int testdir;int CanGoState;int cangof,cangol,cangor;int msf,msl,msr,maxms;int type;CanGoState = CanGo(xxx,yyy,ddir);if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6) cangof = 1; else cangof = 0;if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5) cangol = 1; else cangol = 0;if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4) cangor = 1; else cangor = 0;if(ant[AntNow].food) type = SMELL_TYPE_HOME;else type = SMELL_TYPE_FOOD;msf = GetMaxSmell(type,xxx,yyy,ddir);msl = GetMaxSmell(type,xxx,yyy,TurnLeft(ddir));msr= GetMaxSmell(type,xxx,yyy,TurnRight(ddir));maxms = MaxLocation(msf,msl,msr);/* maxms - 1 - msf is MAX2 - msl is MAX3 - msr is MAX0 - all 3 number is 0 */testdir = NULL;switch(maxms){case 0: /* all is 0, keep testdir = NULL, random select dir */break;case 1: if(cangof)testdir = ddir;elseif(msl>msr) if(cangol) testdir = TurnLeft(ddir);else if(cangor) testdir = TurnRight(ddir);break;case 2: if(cangol)testdir = TurnLeft(ddir);elseif(msf>msr) if(cangof) testdir = ddir;else if(cangor) testdir = TurnRight(ddir);break;case 3: if(cangor)testdir = TurnRight(ddir);elseif(msf>msl) if(cangof) testdir =ddir;else if(cangol) testdir = TurnLeft(ddir);break;default:break;} /* of maxms */randnum = random(1000);if(randnum<SMELL_DROP_RATE*1000||testdir==NULL)/* 1. if testdir = NULL, means can not find the max smell or the dir to max smell can not go then random select dir2. if ant error, don't follow the smell, random select dir*/{randnum = random(100);switch(CanGoState){case 0: if(randnum<90) testdir = ddir;else if (randnum>=90&&randnum<95) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 1: if(randnum<50) testdir = TurnLeft(ddir);else testdir = TurnRight(ddir);break;case 2: if(randnum<90) testdir = ddir;else testdir = TurnRight(ddir);break;case 3: if(randnum<90) testdir = ddir;else testdir = TurnLeft(ddir);break;case 4: testdir = TurnRight(ddir);break;case 5: testdir = TurnLeft(ddir);break;case 6: testdir = ddir;break;case 7: testdir = TurnBack(ddir);break;default:testdir = TurnBack(ddir);} /* of can go state */}return(testdir);}int GetMaxSmell(int type,int xxx,int yyy,int ddir){int i,j;int ms; /* MAX smell */ms = 0;switch(ddir){case UP: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++)for(j=yyy-ANT_EYESHOT;j<yyy;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)||(i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)){ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case DOWN: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++)for(j=yyy+1;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case LEFT: for(i=xxx-ANT_EYESHOT;i<xxx;i++)for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;case RIGHT: for(i=xxx+1;i<=xxx+ANT_EYESHOT;i++)for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++){if(!JudgeCanGo(i,j)) continue;if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) {ms = MAX_SMELL;break;}if(IsTrace(i,j)) continue;if(Smell[type][i][j]>ms) ms = Smell[type][i][j];}break;default: break;}return(ms);}int IsTrace(int xxx,int yyy){int i;for(i=0;i<TRACE_REMEMBER;i++)if(ant[AntNow].tracex[i]==xxx&&ant[AntNow].tracey[i]==yyy) return(1);return(0);}int MaxLocation(int num1,int num2,int num3){int maxnum;if(num1==0&&num2==0&&num3==0) return(0);maxnum = num1;if(num2>maxnum) maxnum = num2;if(num3>maxnum) maxnum = num3;if(maxnum==num1) return(1);if(maxnum==num2) return(2);if(maxnum==num3) return(3);}int CanGo(int xxx,int yyy,int ddir)/* input: xxx,yyy - location of antddir - now diroutput: 0 - forward and left and right can go1 - forward can not go2 - left can not go3 - right can not go4 - forward and left can not go5 - forward and right can not go6 - left and right can not go7 - forward and left and right all can not go */{int tx,ty,tdir;int okf,okl,okr;/* forward can go ? */tdir = ddir;tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okf = 1;else okf = 0;/* turn left can go ? */tdir = TurnLeft(ddir);tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okl = 1;else okl = 0;/* turn right can go ? */tdir = TurnRight(ddir);tx = xxx;ty = yyy;switch(tdir){case UP: ty--;break;case DOWN: ty++;break;case LEFT: tx--;break;case RIGHT: tx++;break;default: break;} /* of switch dir */if(JudgeCanGo(tx,ty)) okr = 1;else okr = 0;if(okf&&okl&&okr) return(0);if(!okf&&okl&&okr) return(1);if(okf&&!okl&&okr) return(2);if(okf&&okl&&!okr) return(3);if(!okf&&!okl&&okr) return(4);if(!okf&&okl&&!okr) return(5);if(okf&&!okl&&!okr) return(6);if(!okf&&!okl&&!okr) return(7);return(7);}int JudgeCanGo(int xxx,int yyy)/* input: location to judegoutput: 0 -- can not go1 -- can go*/{int i,j;if(xxx<=0||xxx>MAXX) return(0);if(yyy<=0||yyy>MAXY) return(0);if(block[xxx][yyy]) return(0);return(1);}int TurnLeft(int ddir){switch(ddir){case UP: return(LEFT);case DOWN: return(RIGHT);case LEFT: return(DOWN);case RIGHT: return(UP);default: break;} /* of switch dir */}int TurnRight(int ddir){switch(ddir){case UP: return(RIGHT);case DOWN: return(LEFT);case LEFT: return(UP);case RIGHT: return(DOWN);default: break;} /* of switch dir */}int TurnBack(int ddir){switch(ddir){case UP: return(DOWN);case DOWN: return(UP);case LEFT: return(RIGHT);case RIGHT: return(LEFT);default: break;} /* of switch dir */}算法解释:程序开始运⾏,蚂蚁们开始从窝⾥出动了,寻找⾷物;他们会顺着屏幕爬满整个画⾯,直到找到⾷物再返回窝。