首先是个体类:
public class GAObject
{
public Vector3 mPosition;
public float mfitness
{
get
{
return Evaluate ();
}
}
public bool[] mbitbunch
{
set
{
mbitbunch = new bool[value.Length];
for (int i = 0; i < mbitbunch.Length; i++)
mbitbunch [i] = value [i];
}
get
{
return mbitbunch;
}
}
public List<int> mBreakPoint = new List<int>();
public virtual void Encode ()
{
}
public virtual void Decode ()
{
}
public virtual void RandomData()
{
}
public virtual float Evaluate()
{
return 1.0f;
}
};
用Bool[]来保存基因的编码,用float来确定一个适应度,并用重载后的评价函数来计算他。
同时还要提供编码函数、解码函数的虚函数,在派生类里,可以申明性状的属性,并在解码、编码函数中对应起来。
接着,出于选择策略、重组策略、变异策略多为底层实现,我们把遗传算法的这三个过程申明成了委托。
public delegate GAObject[] GASelector(GAObject[] pObjects,float pDyingRate);
public delegate GAObject[] GABreedor(GAObject[] pObjects,float pIncreaseRate);
public delegate GAObject[] GAMutator(GAObject[] pObjects,float pMutatorRate);
底层中几个简单实现:
public static GAObject[] RouletteSelector(GAObject[] pGAObject,float pDyingRate)
{
int nowLength = (int)(pGAObject.Length * pDyingRate);
GAObject[] nowObject = new GAObject[nowLength];
int index = 0;
int RSIndex = 0;
float maxfitness = -1.0f;
for (int i = 0; i < pGAObject.Length; i++)
{
if (pGAObject [i].mfitness > maxfitness)
{
maxfitness = pGAObject [i].mfitness;
}
}
List<int> succeedIndex = new List<int> ();
while (index < nowLength)
{
if (succeedIndex.Contains (RSIndex))
{
RSIndex++;
RSIndex = RSIndex % pGAObject.Length;
continue;
}
float trate = pGAObject [RSIndex].mfitness / maxfitness;
if (UnityEngine.Random.Range (0.0f, 1.0f) < trate)
{
nowObject [index++] = pGAObject [RSIndex];
succeedIndex.Add (RSIndex);
RSIndex++;
RSIndex = RSIndex % pGAObject.Length;
}
else
{
RSIndex++;
RSIndex = RSIndex % pGAObject.Length;
}
}
return nowObject;
}
public static GAObject[] SinglePointInsertBreedor(GAObject[] pGAObject,float pIncreseseRate)
{
int nowLength = (int)(pGAObject.Length * pIncreseseRate);
if (nowLength % 2 == 1)
nowLength++;
GAObject[] nowObject = new GAObject[nowLength];
int index = 0;
while (index < nowLength)
{
GAObject mother = pGAObject[UnityEngine.Random.Range(0,pGAObject.Length)];
GAObject father = pGAObject[UnityEngine.Random.Range(0,pGAObject.Length)];
bool[] bitbunch1 = new bool[mother.mbitbunch.Length];
bool[] bitbunch2 = new bool[mother.mbitbunch.Length];
for (int i = 0; i < bitbunch1.Length; i++)
{
if (i < bitbunch1.Length / 2)
{
bitbunch1 [i] = mother.mbitbunch [i];
bitbunch2 [i] = father.mbitbunch [i];
}
else
{
bitbunch1 [i] = father.mbitbunch [i];
bitbunch2 [i] = mother.mbitbunch [i];
}
}
nowObject [index].mbitbunch = bitbunch1;
nowObject [index + 1].mbitbunch = bitbunch2;
index = index + 2;
}
return nowObject;
}
public static GAObject[] SimpleMutator(GAObject[] pGAObject,float pMutatoRate)
{
for (int i = 0; i < pGAObject.Length; i++)
{
if (UnityEngine.Random.Range (0.0f, 1.0f) < Mathf.Pow(pMutatoRate,0.5f))
{
for (int j = 0; j < pGAObject[i].mbitbunch.Length; j++)
{
if (UnityEngine.Random.Range (0.0f, 1.0f) < Mathf.Pow (pMutatoRate, 0.5f))
{
pGAObject [i].mbitbunch [j] = !pGAObject [i].mbitbunch [j];
}
}
}
}
return pGAObject;
}
最后还有种群和种群管理者的类:
public class GAPopulation
{
public Type mObjectType;
public string mRTType;
public SimpleAIRunner mRTObjectRunner;
public SimpleAIStateJudger mRTObjectJudger;
public GameObject mPrefab;
public GameObject mPlayer;
public int mMaxCount;
public float mBreedCycle;
public float mBreedTimer = 0.0f;
public float mMutatorRate;
public float mIncreaseRate;
public float mDyingRate;
public GASelector mSelector;
public GABreedor mBreedor;
public GAMutator mMutator;
private GAObject[] mGAObjectSet;
private SimpleAI[] mRTObjectSet;
public float lifeRate
{
get
{
return (float)mGAObjectSet.Length / (float)mMaxCount;
}
}
public static Dictionary<string,GAPopulation> allDic;
public static void GlobalInit()
{
allDic = new Dictionary<string, GAPopulation> ();
}
public GAPopulation()
{
GAPopulationManager.getInstance ().Add (this);
}
public void Init()
{
mGAObjectSet = new GAObject[mMaxCount];
allDic.Add (mRTType,this);
for (int i = 0; i < mGAObjectSet.Length; i++)
{
mGAObjectSet [i].RandomData ();
mGAObjectSet [i].Encode ();
}
RePairRTObject ();
}
public void Generate()
{
mGAObjectSet = mSelector (mGAObjectSet,mDyingRate);
mGAObjectSet = mBreedor (mGAObjectSet,mIncreaseRate);
mGAObjectSet = mMutator (mGAObjectSet,mMutatorRate);
for (int i = 0; i < mGAObjectSet.Length; i++)
{
mGAObjectSet [i].Decode ();
}
RePairRTObject ();
}
public void RePairRTObject()
{
for (int i = 0; i < mRTObjectSet.Length; i++)
{
GameObject.Destroy (mRTObjectSet[i].mAIRT);
SimpleAISetSingleton.getInstance ().GetComponent<SimpleAISet> ().Delete (mRTObjectSet[i]);
}
mRTObjectSet = new SimpleAI[mGAObjectSet.Length];
for (int i = 0; i < mRTObjectSet.Length; i++)
{
mRTObjectSet [i] = new SimpleAI ();
mRTObjectSet [i].Init (mRTObjectRunner,mRTObjectJudger,mPrefab,mPlayer,mGAObjectSet[i].mPosition);
mRTObjectSet [i].mType = mRTType;
mRTObjectSet [i].mCharacter = mGAObjectSet [i];
}
}
public void Delete(SimpleAI pSimpleAI)
{
GAObject[] tGAObjects = new GAObject[mGAObjectSet.Length-1];
SimpleAI[] tSimpleAIs = new SimpleAI[mRTObjectSet.Length-1];
int index = 0;
for (int i = 0; i < mGAObjectSet.Length; i++)
{
if (mRTObjectSet [i] == pSimpleAI)
continue;
tGAObjects [index] = mGAObjectSet [i];
tSimpleAIs [index] = mRTObjectSet [i];
index++;
}
mGAObjectSet = tGAObjects;
mRTObjectSet = tSimpleAIs;
}
};
种群类主要是为了将选择策略、重组策略、变异策略、基因遗传因子、和具体的SimpleAI统一的联系起来,并组织出遗传算法的核心代码。
public class GAPopulationManager
{
private static GAPopulationManager mGAPoputionManager;
public static GAPopulationManager getInstance()
{
if (mGAPoputionManager == null)
mGAPoputionManager = new GAPopulationManager ();
return mGAPoputionManager;
}
public void Add(GAPopulation pGAPopulation)
{
mGAPopulationSet [mCount] = pGAPopulation;
mGAPopulationThreadSet [mCount] = new Thread (ThreadDo);
mCount++;
}
public void Init()
{
mGAPopulationSet = new GAPopulation[100];
mGAPopulationThreadSet = new Thread[100];
}
public void Start()
{
for (int i = 0; i < mCount; i++)
{
mGAPopulationThreadSet [i].Start (mGAPopulationSet[i]);
}
}
private void ThreadDo(object pGAPopulation)
{
GAPopulation tGAPopulation = (GAPopulation)pGAPopulation;
while (true)
{
Thread.Sleep (50);
tGAPopulation.mBreedTimer += 0.05f;
if (tGAPopulation.mBreedTimer >= tGAPopulation.mBreedCycle)
{
tGAPopulation.Generate ();
tGAPopulation.mBreedTimer = 0.0f;
}
}
}
private GAPopulation[] mGAPopulationSet;
private Thread[] mGAPopulationThreadSet;
public int mCount = 0;
}
种群管理类将种群记录在数组里,并一一和线程关联,在游戏初始化时,把所有的线程打开。