⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 allocationant.cpp

📁 火力分配的应用
💻 CPP
字号:
// AllocationAnt.cpp: implementation of the CAllocationAnt class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "genetest.h"
#include "AllocationAnt.h"
#include "GenetestView.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAllocationAnt::CAllocationAnt()
{
	//m_bSearchFinished = FALSE;
	//SetAllocArray();
	m_fFitness = 0.0;
}

CAllocationAnt::~CAllocationAnt()
{

}
void CAllocationAnt::SetAllocArray()
{
	int i,j;
	for(i=0;i<maxTarget;i++)
	{
		m_nTargetAllocated[i] = 0;
		m_nSortArray[i] = i;
		for(j=0;j<maxWeapon;j++)
			m_nArray[i][j]=0;
	}
}

void CAllocationAnt::SearchPath()
{
	//SetAllocArray();
		
	//得到武器数
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nWeapon = pView->m_nweapon;
	int nTarget = pView->m_ntarget;
	for(int n=0;n<nWeapon;n++)
	{
		//初始时让蚂蚁随机的位于一个武器点上
		//然后根据迹来选择一个与之匹配的目标点。
		//首先判断该点是否已被分配,即判断m_nArray所代表矩阵的第randpos列是否有值为1,
		//若已经为1,则重新找武器点
		BOOL flag = TRUE;
		int i;
		int randpos;
		
		while(flag == TRUE)//已被分配
		{
			int r = rand();
			randpos = r%nWeapon;
			for(i=0;i<nTarget;i++)
			{
				int c = m_nArray[i][randpos];
				if(c == 1)
				{
					flag = TRUE;
					break;
				}
			}
			if(i==nTarget)//找到的武器点还没有被分配,因为若是分配了,for循环会终止,i不能增长到nTarget
				flag = FALSE;
		}
		//--------计算转移概率-------------------------
		float TransferProp;
		float maxPheromone,Sum;
		//定义与randpos点相连边的迹最大的目标点的索引
		int TransferTarget;
		int nMaxTarget;
		//寻找最大的迹,并计算迹的和
				
		Sum = 0;
		SortTargetIndexByPheromone(randpos);
		int j = 0;
		while(!AnalysisTarget(m_nSortArray[j])&&j<nTarget)
		{
			j++;
		}
		if(j==nTarget)
			pView->WriteLog("出现错误");
		nMaxTarget = m_nSortArray[j];
		maxPheromone = pView->m_PheromoneArray[nMaxTarget][randpos];
		for(i=0;i<nTarget;i++)
		{
			Sum += pView->m_PheromoneArray[i][randpos];
		}
		
		
		//转移概率的定义本来还考虑了“路径可见度”的影响,此处没有涉及,只是考虑了迹
		TransferProp = maxPheromone/Sum;//用迹最大的边定义转移概率
		//判断转移概率是否小于设定P0值,若小于,则将TransferTarger点分配给randpos点
		if(TransferProp <= TransferP0)
		{
			TransferTarget = nMaxTarget;
			m_nArray[TransferTarget][randpos] = 1;
			m_nTargetAllocated[TransferTarget]++;
		}
		else//若大于p0,则选择迹小的边
		{
			TransferTarget = rand()%nTarget;
			while(TransferTarget==nMaxTarget)
			{
				TransferTarget = rand()%nTarget;
			}
			m_nArray[TransferTarget][randpos] = 1;
			m_nTargetAllocated[TransferTarget]++;
		}
	}
	//-------------------计算转移概率及找分配点的代码,在此函数中可能无用,移至别处--------
}
//计算路径长度,在MMAS算法中,是只有路径最短的蚂蚁才进行迹的更新,迹更新函数在View类中定义,
//此处,计算路径长度实际上是计算适应度函数,应该是适应度函数最大的蚂蚁才进行迹的更新
//在Run函数中调用ComputePathLength()还是在View类中调用合适呢????
float CAllocationAnt::ComputePathLength()
{
	//得到武器数和目标数
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nWeapon = pView->m_nweapon;
	int nTarget = pView->m_ntarget;
	float Sum = 0.0;
	float mul;
	for(int i = 0;i < nTarget;i++)
	{
		mul = 1.0;
		for(int j = 0;j < nWeapon;j++)
		{
			if(m_nArray[i][j]==1)//Weapon J被分配给了Target I
			{
				mul = mul*(1 - pView->m_SuccessArray[i][j]);//计算失败的概率
			}
		}
		mul = 1 - mul;//得到成功的概率
		Sum = Sum + pView->m_Worthiness[i]*mul; //得到对目标打击成功的概率和
			
	}
	return Sum;
}

void CAllocationAnt::ReadTargetLimit()
{
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nTarget = pView->m_ntarget;
	POSITION pos = pView->m_WeaponList.GetHeadPosition();
	int i = 0;
	while(pos != NULL)
	{
		m_nTargetLimit[i] = pView->m_WeaponList.GetAt(pos)->m_nMaxWeapon;
		i++;
		pView->m_WeaponList.GetNext(pos);
	}
}
//根据传进来的目标索引,分析该目标分配的武器是否已经达到允许分配最多武器数的限制,若没达到
//返回TRUE,否则返回FALSE
BOOL CAllocationAnt::AnalysisTarget(int TargetIndex)
{
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nTarget = pView->m_ntarget;
	BOOL flag = FALSE;
	if(m_nTargetLimit[TargetIndex] > m_nTargetAllocated[TargetIndex])
		flag = TRUE;
	return flag;
}
//针对某一武器,将各目标按照该武器与目标之间的迹的大小,从大到小排序,将排序结果放在m_nSortArray中
void CAllocationAnt::SortTargetIndexByPheromone(int nWeapon)
{
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nTarget = pView->m_ntarget;
	float maxPheromone = 0.0;
	int nMaxTarget = -1;
	CString str,str1;
	str.Format("武器%d",nWeapon+1);
	pView->WriteLog(str);
	//str = "";
	for(int i=0;i<nTarget;i++)
	{
		for(int j = 0;j<nTarget;j++)
		{
			//去除已经排过序的值
			if(i!=0)
			{
				BOOL flag = FALSE;
				for(int k=0;k<i;k++)
				{
					if(j==m_nSortArray[k]){
						flag = TRUE;
						break;
					}
				}
				if(flag) continue;
			}
			if(pView->m_PheromoneArray[j][nWeapon]>maxPheromone)
			{
				nMaxTarget = j;//与点randpos相连边的迹最大的点
				maxPheromone = pView->m_PheromoneArray[j][nWeapon];
			}
		}
		m_nSortArray[i] = nMaxTarget;
		maxPheromone = 0.0;
		//str1.Format("%d ",nMaxTarget+1);
		//str += str1;
	}
	//pView->WriteLog(str);
}
//将分配结果输出到文件
void CAllocationAnt::WriteResult()
{
	CGenetestView *pView;
	pView = (CGenetestView *)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView();
	int nTarget = pView->m_ntarget;
	int nWeapon = pView->m_nweapon;
	CString str,str1;
	for(int i = 0; i < nTarget;i++)
	{
		str = "";
		str1 = "";
		for(int j = 0;j < nWeapon;j++)
		{
			if(m_nArray[i][j]==1)
			{
				str1.Format("第%d个、",j+1);
				str += str1;
			}
		}
		if(str1!="")
		{
			str1.Format("武器被分配到%d号目标",i+1);
			str = str.Left(str.GetLength()-2);
			str += str1;
		}
		else
			str.Format("没有武器分配到第%d号目标",i+1);
		pView->WriteLog(str);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -