智能在空间信息中的应用,比如遗传算法、蚁群算法、免疫算法等等。
鸟群算法是其中一种,以下程序模拟了一部分特点,还在改进。
namespace BirdIntelligence
{
public partial class FlyIntelligence : Form
{
private ArrayList _BirdPoint = new ArrayList();
public ArrayList BirdPoint
{
get { return _BirdPoint; }
set { _BirdPoint = value; }
}
private ArrayList _ChangeBird = new ArrayList();
public ArrayList ChangeBird
{
get { return _ChangeBird; }
set { _ChangeBird = value; }
}
public FlyIntelligence()
{
InitializeComponent();
}
private void 生成鸟群ToolStripMenuItem_Click(object sender, EventArgs e)
{
BirdPoint.Clear();
ArrayList tempArrayA = new ArrayList();
ArrayList tempArrayB = new ArrayList();
ArrayList birdpoint = new ArrayList();
Random temp = new Random();
for (int i = 0; i < 10; i++)
{
tempArrayA.Add(i);
}
int total = tempArrayA.Count;
tempArrayB = (ArrayList)tempArrayA.Clone();
for (int j = 0; j < total; j++)
{
int x = temp.Next(0, tempArrayA.Count);
int y = temp.Next(0, tempArrayB.Count);
birdpoint.Add(new Point((int)tempArrayA[x] * 50, (int)tempArrayB[y] * 50));
tempArrayA.Remove(tempArrayA[x]);
tempArrayB.Remove(tempArrayB[y]);
}
BirdPoint = birdpoint;
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
if (BirdPoint.Count != 0)
{
foreach (object obj in BirdPoint)
{
Point point = (Point)obj;
Pen pen = new Pen(Color.Red, 3);
e.Graphics.DrawEllipse(pen, point.X, point.Y, 50, 50);
}
}
if (ChangeBird.Count != 0)
{
foreach (object obj in ChangeBird)
{
Point point = (Point)obj;
Pen pen = new Pen(Color.Green, 2);
e.Graphics.DrawEllipse(pen, point.X, point.Y, 40, 40);
}
for (int i = 0; i < ChangeBird.Count - 1; i++)
{
Pen pen = new Pen(Color.Blue, 4);
e.Graphics.DrawLine(pen, (Point)ChangeBird[i], (Point)ChangeBird[i + 1]);
}
}
base.OnPaint(e);
}
private void 鸟群排队ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (BirdPoint.Count != 0)
{
BirdPoint = Sort(BirdPoint);
BirdPoint = Line(BirdPoint);
Refresh();
//MessageBox.Show("ok!");
}
}
private ArrayList Sort(ArrayList array)
{
ArrayList LargeToSmall = new ArrayList();
object temp = new object();
for (int i = 0; i < array.Count; i++)
{
for (int j = 0; j < array.Count - i - 1; j++)
{
if (((Point)array[j]).X < ((Point)array[j + 1]).X)
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
LargeToSmall = array;
return LargeToSmall;
}
private ArrayList Line(ArrayList array)
{
Point ShortPoint = (Point)array[0];
ChangeBird.Add(ShortPoint);
int total = array.Count;
for (int i = 0; i < total - 1; i++)
{
if (i == 0)
{
array.Remove(array[0]);
}
else
{
ShortPoint = ShortestPoint(array, ShortPoint);
ChangeBird.Add(ShortPoint);
array.Remove(ShortPoint);
}
}
ChangeBird.Add(array[0]);
return ChangeBird;
}
private Point ShortestPoint(ArrayList array, Point point)
{
for (int i = 0; i < array.Count; i++)
{
if (IsShortest(array, i, point))
{
return (Point)array[i];
}
}
return point;
}
private ArrayList SortDistance(ArrayList array)
{
double temp;
for (int i = 0; i < array.Count; i++)
{
for (int j = 0; j < array.Count - i - 1; j++)
{
if ((double)array[j] < (double)array[j + 1])
{
temp = (double)array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
return array;
}
private bool IsShortest(ArrayList array, int i, Point point)
{
double dis = Distance((Point)array[i], point);
bool large = true;
for (int j = 0; j < array.Count; j++)
{
if (Distance((Point)array[j], point) < dis)
{
large = false;
}
}
return large;
}
private double Distance(Point a, Point b)
{
double dis = Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2);
return dis;
}
private void 鸟群调整ToolStripMenuItem_Click(object sender, EventArgs e)
{
for (int i = 0; i < ChangeBird.Count; i++)
{
if (i == 0)
{
//首领不变化
}
else
{
if (i == 1)
{
ChangeBird[1] = ChangePosition((Point)ChangeBird[1], (Point)ChangeBird[0], (Point)ChangeBird[0]);
}
else
{
ChangeBird[i] = ChangePosition((Point)ChangeBird[i], (Point)ChangeBird[i - 1], (Point)ChangeBird[i - 2]);
}
}
}
Refresh();
}
private Point ChangePosition(Point a, Point b, Point c)
{
if (b == c)
{
int temp = 0;
if (a.Y >= b.Y)
{
temp = (int)(a.Y - (Math.Sin(Math.PI * (Math.Acos((a.X - b.X) / Distance(a, b)) / 180.0))) * 100);
a.Y = temp;
}
else
{
temp = (int)(a.Y + (Math.Sin(Math.PI * (Math.Acos((a.X - b.X) / Distance(a, b)) / 180.0))) * 100);
a.Y = temp;
}
return a;
}
else
{
double angle = CreateAngle(a, b, c);
int temp = 0;
if (a.Y >= b.Y)
{
temp = (int)(a.Y - Math.Sin(angle) * 400);
a.Y = temp;
}
else
{
temp = (int)(a.Y + Math.Sin(angle) * 400);
a.Y = temp;
}
return a;
}
}
private double CreateAngle(Point a, Point b, Point c)
{
double cos = ((a.X - b.X) * (c.X - b.X) + (a.Y - b.Y) * (c.Y - b.Y)) / (Distance(a, b) * Distance(b, c));
double angle = Math.Acos(cos);
return Math.PI * angle / 180.0;
}
}
}