Реализация глобального поиска для задачи оптимального размещения многоугольников

Предикатное представление условий непересечения многоугольников. Алгоритм непересечения многоугольника и полосы. Определение направления обхода вершин многоугольника. Решение систем линейных алгебраических уравнений. Построение интерактивной оболочки.

Рубрика Математика
Вид дипломная работа
Язык украинский
Дата добавления 10.11.2012
Размер файла 800,2 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

/// добавление уравнения

/// </summary>

public void Add(Equation eq)

{

//добавление уравнения в общий массив уравнений

num_eq++;

data.Add(eq);

//добавление номера уравнения в соответствующий список

int i;

for(i = 0;i<eq.Dimension()+1;i++)

if (eq[i] != 0)

((ArrayList)arrayOfNumbers[i]).Add(data.Count-1);

}

/// <summary>

/// тестовый метод для консольного вывода множества уравнений

/// </summary>

public void Output()

{

Console.WriteLine("Вывод множества уравнений");

Console.WriteLine("Всего уравнений = {0}",num_eq.ToString());

Console.WriteLine("Размерность уравений = {0}",(arrayOfNumbers.Count-1).ToString());

int count;

for(int i = 0;i<arrayOfNumbers.Count;i++)

{

Console.WriteLine("Уравнения содержащие ненулевой коэффициент при {0}-ой переменной",i+1);

count = ((ArrayList)arrayOfNumbers[i]).Count;

if ( count == 0 )

Console.WriteLine("Пусто");

else for(int j = 0;j<count;j++)

((Equation)data[((int)((ArrayList)arrayOfNumbers[i])[j])]).Output();

}

}

/// <summary>

/// добавление множества уравнений, уравнения должны быть одной размерности

/// </summary>

public void AddSOF(SetOfEquations sof)

{

foreach(Equation eq in sof.data)

this.Add(eq);

}

/// <summary>

/// возвращает общее число уравнений,работает некорректно!!!!

/// </summary>

public int Size()

{

return num_eq;

}

/// <summary>

/// возвращает количество типов уравнений

/// </summary>

public int Dimension()

{

return arrayOfNumbers.Count-1;

}

/// <summary>

/// возвращает множество уравнений, где коэффициент при i-ой переменной ненулевой;

/// </summary>

public SetOfEquations GetSOF(int ind)

{

SetOfEquations result = new SetOfEquations(arrayOfNumbers.Count);

foreach(int number in ((ArrayList)arrayOfNumbers[ind-1]))

result.Add( (Equation)data[number] );

return result;

}

/// <summary>

/// возвращает первое уравнение, где коэффициент при i-ой переменной ненулевой

/// </summary>

public Equation GetI(int i)

{

if ( (i > 0) && (i <= this.Dimension()+1) )

return (Equation)data[ (int)((ArrayList)arrayOfNumbers[i-1])[0] ];

else return new Equation(this.Dimension());

}

/// <summary>

/// возвращает номер первого уравнения, где коэффициент при i-ой переменной ненулевой

/// </summary>

public int GetNumberI(int i)

{

if ( (i > 0) && (i <= this.Dimension()+1) && (((ArrayList)arrayOfNumbers[i-1]).Count != 0) )

return (int)((ArrayList)arrayOfNumbers[i-1])[0];

else return -1;

}

/// <summary>

/// удаляет первое уравнение, где коэффициент при i-ой переменной ненулевой

/// </summary>

public void DeleteI(int i)

{

if ( (i > 0) && (i <= this.Dimension()+1) && (((ArrayList)arrayOfNumbers[i-1]).Count != 0) )

{

//data.RemoveAt( (int)((ArrayList)arrayOfNumbers[i-1])[0] );

((ArrayList)arrayOfNumbers[i-1]).RemoveAt(0);

num_eq--;

}

}

/// <summary>

/// количество уравнений во множестве

/// </summary>

private int num_eq;

/// <summary>

/// возвращает ураврение по его номеру

/// </summary>

public Equation GetEquationByNumber(int i)

{

if ( (i > -1) /*&& (i < num_eq)*/ )

return (Equation)data[i];

else return null;

}

}

}

Polygon.cs

using System;

using System.Collections;

namespace Diplom

{

public class Polygon : Diplom.GeomObj, IDraw, IChange, IOperations

{

public enum round {CLOCKWISE,COUNTER_CLOCKWISE,UNDEFINE};

public Polygon()

{

points = new ArrayList();

pole = new Point();

pole.X = 0;

pole.Y = 0;

}

void IDraw.Draw()

{

Console.WriteLine("Drawings polygon");

foreach(Point p in points)

((IDraw)p).Draw();

}

//methods IChange interface

void IChange.Add(GeomObj data)

{

points.Add(data);

}

void IChange.SetI(GeomObj data, int ind)

{

if (ind < points.Count)

points[ind] = data;

}

void IChange.DeleteI(int ind)

{

if (ind < points.Count)

points.RemoveAt(ind);

}

void IChange.Insert(GeomObj data,int ind)

{

if (ind < points.Count)

points.Insert(ind,data);

}

//methods IOperations interface

void IOperations.Shift(Point to)

{

foreach(Point p in points)

((IOperations)p).Shift(to);

}

void IOperations.Rotate(Point center,double angel)

{

foreach(Point p in points)

((IOperations)p).Rotate(center,angel);

}

//collection of points

public ArrayList points;

/// <summary>

/// количество точек

/// </summary>

public int NumPoints

{

get

{

return points.Count;

}

}

/// <summary>

/// получение i-ой точки

/// </summary>

public Point GetI(int ind)

{

if (ind < points.Count)

return ((Point)points[ind]);

else return null;

}

/// <summary>

/// полюс

/// </summary>

private Point pole;

/// <summary>

/// свойство - полюс многоугольника

/// </summary>

public Point Pole

{

get

{

return pole;

}

set

{

pole = value;

}

}

/// <summary>

/// определяет направление обхода вершин

/// </summary>

public round Round()

{

if (this.NumPoints < 3) return round.UNDEFINE;

else

{

//центр масс

Point middle = new Point();

middle.X = (((Point)points[0]).X+((Point)points[1]).X+((Point)points[2]).X)/3.0;

middle.Y = (((Point)points[0]).Y+((Point)points[1]).Y+((Point)points[2]).Y)/3.0;

Point p1 = new Point();

Point p2 = new Point();

Point p3 = new Point();

p1.X = ((Point)points[0]).X - middle.X;

p1.Y = ((Point)points[0]).Y - middle.Y;

p2.X = ((Point)points[1]).X - middle.X;

p2.Y = ((Point)points[1]).Y - middle.Y;

p3.X = ((Point)points[2]).X - middle.X;

p3.Y = ((Point)points[2]).Y - middle.Y;

double ang1;

if (p1.X != 0)

ang1 = Math.Atan(p1.Y/p1.X);

else

{

if (p1.Y>0) ang1 = Math.PI/2;

else ang1 = 3*Math.PI/2;

}

//вторая четверть

if ( (p1.X < 0) && (p1.Y >= 0) ) ang1 += Math.PI;

//третья четверть

if ( (p1.X < 0) && (p1.Y < 0) ) ang1 += Math.PI;

double ang2;

if (p2.X != 0) ang2 = Math.Atan(p2.Y/p2.X);

else

{

if (p2.Y>0) ang2 = Math.PI/2;

else ang2 = 3*Math.PI/2;

}

//вторая четверть

if ( (p2.X < 0) && (p2.Y > 0) ) ang2 += Math.PI;

//третья четверть

if ( (p2.X < 0) && (p2.Y < 0) ) ang2 += Math.PI;

double ang3;

if (p3.X != 0) ang3 = Math.Atan(p3.Y/p3.X);

else

{

if (p3.Y>0) ang3 = Math.PI/2;

else ang3 = 3*Math.PI/2;

}

//вторая четверть

if ( (p3.X < 0) && (p3.Y > 0) ) ang3 += Math.PI;

//третья четверть

if ( (p3.X < 0) && (p3.Y < 0) ) ang3 += Math.PI;

bool b1 = (ang1<=ang2) && (ang2<=ang3);

bool b2 = (ang3<=ang1) && (ang1<=ang2);

bool b3 = (ang2<=ang3) && (ang3<=ang1);

if ( b1 || b2 || b3 ) return round.COUNTER_CLOCKWISE;

else return round.CLOCKWISE;

}

}

/// <summary>

/// формирует множество уравнений по непересечению с полосой s, возвращает множество уравнений;

/// n - размерность уравнений

/// i - номер многоугольника,нумерация с единицы

/// </summary>

public SetOfEquations FormingEquations(Strip s,int n,int i)

{

SetOfEquations sof = new SetOfEquations(n);

double xmax = 0,xmin = 100000000000,ymax = 0,ymin = 1000000000000;

double x;

double y;

foreach(Point p in points)

{

x = ((Point)p).X;

y = ((Point)p).Y;

if ( x<xmin ) xmin = x;

if ( y<ymin ) ymin = y;

if ( x>xmax ) xmax = x;

if ( y>ymax ) ymax = y;

}

Equation eq1 = new Equation(n);

eq1[2*(i-1)] = -1;

eq1[n] = -xmin; //xmin

sof.Add(eq1);

Equation eq2 = new Equation(n);

eq2[2*(i-1)] = 1;

eq2[n-1] = -1;

eq2[n] = xmax;

sof.Add(eq2);

Equation eq3 = new Equation(n);

eq3[2*i-1] = -1; //1

eq3[n] = -ymin; //ymin

sof.Add(eq3);

Equation eq4 = new Equation(n);

eq4[2*i-1] = 1;

eq4[n] = ymax-s.Width;

sof.Add(eq4);

return sof;

}

/// <summary>

/// формирует множество уравнений по непересечению с другим многоугольником pol,

/// возвращает множество уравнений;

/// n - размерность уравнений

/// i - номер текущего многоугольника

/// j - номер многоугольника pol,нумерация с единицы

/// </summary>

public SetOfEquations FormingEquations(Polygon pol,int n,int i,int j)

{

if (this.Round() == round.CLOCKWISE)

{

points.Reverse();

}

if (pol.Round() == round.CLOCKWISE)

{

pol.points.Reverse();

}

SetOfEquations sof = new SetOfEquations(n);

double x1 = 0;

double y1 = 0;

double x2 = 0;

double y2 = 0;

double x = 0;

double y = 0;

double a = 0;

double b = 0;

double c = 0;

double dmin = 0;

double d = 0;

for(int k = 0;k<points.Count;k++)

{

x1 = ((Point)points[k]).X;

y1 = ((Point)points[k]).Y;

if (k == points.Count-1)

{

x2 = ((Point)points[0]).X;

y2 = ((Point)points[0]).Y;

}

else

{

x2 = ((Point)points[k+1]).X;

y2 = ((Point)points[k+1]).Y;

}

a = y2 - y1;

b = x1 - x2;

c = -x1*y2 + x2*y1;

dmin = 1e+100;

foreach(Point p in pol.points)

{

x = p.X;

y = p.Y;

d = (a*x+b*y+c)/Math.Sqrt(a*a+b*b);

if (d<dmin) dmin = d;

}

Equation eq = new Equation(n);

eq[2*j-2] = a;

eq[2*j-1] = b;

eq[2*i-2] = -a;

eq[2*i-1] = -b;

eq[n] = -dmin;//+

sof.Add(eq);

}

return sof;

}

/// <summary>

/// копирование объекта

/// </summary>

public void Copy(Polygon pol)

{

this.points.Clear();

foreach(Point p in pol.points)

{

Point point = new Point();

point.Copy(p);

this.points.Add(point);

}

pole.Copy(pol.pole);

}

//ширина по Х

public double MaxLengthX()

{

double xmin = 1000000000000;

double xmax = 0;

foreach(Point p in points)

{

if (p.X<xmin) xmin = p.X;

if (p.X>xmax) xmax = p.X;

}

return (xmax-xmin);

}

/// <summary>

/// проверка на принадлежность точки многоугольнику

/// </summary>

public bool IsPointIn(Point p)

{

int num = 0; //количество пересечений гор. линии с многоугольником

int i;

double y1,y2,ymed;

double x1,x2,xmed,xx;

xmed = p.X;

ymed = p.Y;

for(i = 0;i < this.NumPoints-1;i++)

{

y1 = ((Point)points[i]).Y;

y2 = ((Point)points[i+1]).Y;

x1 = ((Point)points[i]).X;

x2 = ((Point)points[i+1]).X;

if ((y2-y1) == 0) xx = 1000; //особоый случай-сторона горизонтальная

else xx = ((x2-x1)/(y2-y1))*(ymed-y1)+x1;

if ( (ymed > y1) && (ymed < y2) && (xmed < xx) ) num++;

if ( (ymed > y2) && (ymed < y1) && (xmed < xx) ) num++;

}

y1 = ((Point)points[this.NumPoints-1]).Y;

y2 = ((Point)points[0]).Y;

x1 = ((Point)points[this.NumPoints-1]).X;

x2 = ((Point)points[0]).X;

if ((y2-y1) == 0) xx = 1000;

else xx = ((x2-x1)/(y2-y1))*(ymed-y1)+x1;

if ( (ymed > y1) && (ymed < y2) && (xmed < xx) ) num++;

if ( (ymed > y2) && (ymed < y1) && (xmed < xx) ) num++;

if ( (num % 2) == 0 ) return false;

else return true;

}

//пересекаются ли многоугольники

public bool IntersectPolygons(Polygon pol)

{

int i,j;

Point p1,p2,p3,p4;

p1 = new Point();

p2 = new Point();

p3 = new Point();

p4 = new Point();

bool flag_a,flag_b;

double ua,ub,chisl_a,chisl_b,znam_a,znam_b;

//этот алгоритм в некоторых случаях не работает, например случай звезда давида

bool result = false;

for(i = 0;i<pol.NumPoints;i++)

result = result || ( this.IsPointIn(pol.GetI(i)) );

for(i = 0;i<this.NumPoints;i++)

result = result || ( pol.IsPointIn(this.GetI(i)) );

if (result) return true;

//проверка на непересение сторон многоугольников

for(i = 0;i<this.NumPoints-1;i++)

{

p1.Copy(this.GetI(i));

p2.Copy(this.GetI(i+1));

for(j = 0;j<pol.NumPoints-1;j++)

{

p3.Copy(pol.GetI(j));

p4.Copy(pol.GetI(j+1));

chisl_a = (p4.X-p3.X)*(p1.Y-p3.Y)-(p4.Y-p3.Y)*(p1.X-p3.X);

chisl_b = (p2.X-p1.X)*(p1.Y-p3.Y)-(p2.Y-p1.Y)*(p1.X-p3.X);

znam_a = (p4.Y-p3.Y)*(p2.X-p1.X)-(p4.X-p3.X)*(p2.Y-p1.Y);

znam_b = znam_a;

if (znam_a != 0)

{

ua = chisl_a/znam_a;

ub = chisl_b/znam_b;

//ua = Math.Abs(ua);

//ub = Math.Abs(ub);

flag_a = (ua>=0) && (ua<=1);

flag_b = (ub>=0) && (ub<=1);

if (flag_a && flag_b) return true;

}

p3.Copy(pol.GetI(pol.NumPoints-1));

p4.Copy(pol.GetI(0));

chisl_a = (p4.X-p3.X)*(p1.Y-p3.Y)-(p4.Y-p3.Y)*(p1.X-p3.X);

chisl_b = (p2.X-p1.X)*(p1.Y-p3.Y)-(p2.Y-p1.Y)*(p1.X-p3.X);

znam_a = (p4.Y-p3.Y)*(p2.X-p1.X)-(p4.X-p3.X)*(p2.Y-p1.Y);

znam_b = znam_a;

if (znam_a != 0)

{

ua = chisl_a/znam_a;

ub = chisl_b/znam_b;

//ua = Math.Abs(ua);

//ub = Math.Abs(ub);

flag_a = (ua>=0) && (ua<=1);

flag_b = (ub>=0) && (ub<=1);

if (flag_a && flag_b) return true;

}

}

}

p1.Copy(this.GetI(this.NumPoints-1));

p2.Copy(this.GetI(0));

for(j = 0;j<pol.NumPoints-1;j++)

{

p3.Copy(pol.GetI(j));

p4.Copy(pol.GetI(j+1));

chisl_a = (p4.X-p3.X)*(p1.Y-p3.Y)-(p4.Y-p3.Y)*(p1.X-p3.X);

chisl_b = (p2.X-p1.X)*(p1.Y-p3.Y)-(p2.Y-p1.Y)*(p1.X-p3.X);

znam_a = (p4.Y-p3.Y)*(p2.X-p1.X)-(p4.X-p3.X)*(p2.Y-p1.Y);

znam_b = znam_a;

if (znam_a != 0)

{

ua = chisl_a/znam_a;

ub = chisl_b/znam_b;

//ua = Math.Abs(ua);

//ub = Math.Abs(ub);

flag_a = (ua>=0) && (ua<=1);

flag_b = (ub>=0) && (ub<=1);

if (flag_a && flag_b) return true;

}

p3.Copy(pol.GetI(pol.NumPoints-1));

p4.Copy(pol.GetI(0));

chisl_a = (p4.X-p3.X)*(p1.Y-p3.Y)-(p4.Y-p3.Y)*(p1.X-p3.X);

chisl_b = (p2.X-p1.X)*(p1.Y-p3.Y)-(p2.Y-p1.Y)*(p1.X-p3.X);

znam_a = (p4.Y-p3.Y)*(p2.X-p1.X)-(p4.X-p3.X)*(p2.Y-p1.Y);

znam_b = znam_a;

if (znam_a != 0)

{

ua = chisl_a/znam_a;

ub = chisl_b/znam_b;

//ua = Math.Abs(ua);

//ub = Math.Abs(ub);

flag_a = (ua>=0) && (ua<=1);

flag_b = (ub>=0) && (ub<=1);

if (flag_a && flag_b) return true;

}

}

return false;

}

}

}

Point.cs

using System;

namespace Diplom

{

/// <summary>

///

/// </summary>

public class Point : Diplom.GeomObj, IOperations, IDraw

{

//constructor

public Point()

{

x = 0;

y = 0;

}

//methods IDraw interface

void IDraw.Draw()

{

Console.WriteLine("Drawing point");

Console.WriteLine("X={0}",x.ToString());

Console.WriteLine("Y={0}",y.ToString());

Console.WriteLine("");

}

//methods IOperations interface

//shift point along vector determinate point "to"

void IOperations.Shift(Point to)

{

x += to.X;

y += to.Y;

}

//rotate point around "center" on positiv "angel"

void IOperations.Rotate(Point center,double angel)

{

double rx = Math.Abs(x-center.X);

double ry = Math.Abs(y-center.Y);

double curr_angel = Math.Atan(ry/rx);

double r = Math.Sqrt(rx*rx+ry*ry);

if (ry < 0) curr_angel += Math.PI;

x = center.X + r * Math.Cos(curr_angel+angel);

y = center.Y + r * Math.Sin(curr_angel+angel);

}

//operator =,copy p to this

public void Copy(Point p)

{

x = p.X;

y = p.Y;

focus = p.focus;

}

//operator ==

new public bool Equals(Object p)

{

return ( (x == ((Point)p).X) && (y == ((Point)p).Y) );

}

/// <summary>

/// property ordinate X

/// </summary>

public double X

{

get

{

return x;

}

set

{

x = value;

}

}

/// <summary>

/// ordinate x

/// </summary>

private double x;

/// <summary>

/// ordinate y

/// </summary>

private double y;

/// <summary>

/// property ordinate Y

/// </summary>

public double Y

{

get

{

return y;

}

set

{

y = value;

}

}

}

}

MyTask.cs

using System;

using System.Collections;

using solveSLAU_SVD;

namespace Diplom

{

public class MyTask

{

public MyTask(ref MainForm _mainForm)

{

cp = new CollectionsPolygons();

sof = null;

sof_strip = null;

matr = new ArrayList();

system = new ArrayList();

ar_sof_pol = new ArrayList();

mf = _mainForm;

begin = new DateTime();

begin = DateTime.Now;

current = new DateTime();

}

//окно

MainForm mf;

// набор многоугольников

private CollectionsPolygons cp;

// возвращает количество многоугольников

public int CountPolygons()

{

return cp.NumPolygons;

}

// доступ к набору многоугольников

public CollectionsPolygons Cp

{

get

{

CollectionsPolygons result = new CollectionsPolygons();

result.Copy(cp);

return result;

}

set

{

cp = value;

}

}

// полоса

private Strip strip;

// полоса

public Strip _Strip

{

get

{

Strip new_strip = new Strip();

new_strip.Copy(strip);

return new_strip;

}

set

{

strip = value;

}

}

// создание множества уравнений

public void CreateSOF()

{

int i,j;

if (cp.NumPolygons == 0) return;

else

{

max_length = 0;

for(i = 0;i<cp.NumPolygons;i++)

if (cp.GetI(i).MaxLengthX()>max_length)

max_length = cp.GetI(i).MaxLengthX();

//количество переменных в уравнениях

int n = cp.NumPolygons * 2 + 1;

sof = new SetOfEquations(n);

sof_strip = new SetOfEquations(n);

for(i = 0;i<cp.NumPolygons;i++)

{

sof.AddSOF( cp.GetI(i).FormingEquations(strip,n,i+1) );

sof_strip.AddSOF( cp.GetI(i).FormingEquations(strip,n,i+1) );

for(j = i+1;j<cp.NumPolygons;j++)

{

sof.AddSOF( cp.GetI(i).FormingEquations(cp.GetI(j),n,i+1,j+1) );

sof.AddSOF( cp.GetI(j).FormingEquations(cp.GetI(i),n,j+1,i+1) );

ar_sof_pol.Add( cp.GetI(i).FormingEquations(cp.GetI(j),n,i+1,j+1) );

ar_sof_pol.Add( cp.GetI(j).FormingEquations(cp.GetI(i),n,j+1,i+1) );

}

}

}

/*for(int i = 0;i<sof.Size();i++)

sof.GetEquationByNumber(i).Output();*/

}

//матрица коэффициентов ситемы уравнений

double[,] a;

//промежуточное решение

double[,] sol;

//максимальная ширина многоугольников

double max_length = 0;

// множество всех уравнений

public SetOfEquations sof;

//множество уравнений на принадлежность полосе

private SetOfEquations sof_strip;

//массив множеств уравнений

private ArrayList ar_sof_pol;

// получение матрицы номеров уравнений расположенных в множестве уравнений

private void ConvertSOFToMatrix()

{

//количество переменных в уравнениях

int n = cp.NumPolygons * 2 + 1;

a = new double[n+1,n+2];

//промежуточное решение

sol = new double[n+1,n+2];

//инициализация массива решений

result = new ArrayList();

int i;

for(i = 0;i<n+1;i++)

for(int j = 0;j<n+2;j++)

{

a[i,j] = 0;

sol[i,j] = 0;

}

for(i = 0;i<n-1;i++)

result.Add(0);

result.Add(strip.Length+1);

SetOfEquations sof_tmp = new SetOfEquations(n);

sof_tmp.AddSOF(sof);

for(i = 1;i<=sof_tmp.Dimension()/*+1*/;i++)

{

ArrayList ar = new ArrayList();

while (sof_tmp.GetNumberI(i) != -1)

{

ar.Add(sof_tmp.GetNumberI(i));

sof_tmp.DeleteI(i);

}

matr.Add(ar);

}

}

//-----------------------------

//-----------------------------

//-----------------------------

//далее методы генерирования дерева

//матрица номеров уравнений

private ArrayList matr;

//массив номеров уравнений входящих в систему уравнений

private ArrayList system;

//таблица коэффициентов уравнений

private double[,] koef;

//счетчик систем уравнений

public int num_system;

//счетчик полученных допустимых точек

public int num_points;

//счетчик отбраковок

public int num_brak;

private long chit;

//массив-решение

ArrayList result;

//время

public DateTime begin;

public DateTime current;

//-----------------

//копирование массивов

ArrayList CopyArray(ArrayList ar)

{

ArrayList res = new ArrayList();

foreach(int num in ar)

res.Add(num);

return res;

}

//-----------------

//генерация систем уравнений и их решение

private void Generations()

{

int n = cp.NumPolygons*2+1;

int layer = 0;

int i,l;

int[] ind = new int[n];

for(i = 0;i<n;i++)

ind[i] = -1;

ind[0] = 0;

system.Add(((ArrayList)matr[0])[0]);

int sec;

int flag_min = 0;

int __min = 1;

while( !((layer<=0) && (ind[0]==-1)) )

{

//дополнительная точка окончания расчета

if ((double)result[2*cp.NumPolygons]<=max_length+5e-10)

{

return;

}

chit++;

if (layer<(n-1))

{

layer++;

ind[layer]++;

system.Add( ((ArrayList)matr[layer])[ind[layer]] );

}

else

{

ind[layer]++;

if (ind[layer] <= ((ArrayList)matr[layer]).Count-1)

system[layer] = ((ArrayList)matr[layer])[ind[layer]];

}

l = layer;

for(i = l;i>=0;i--)

{

if (ind[i] > ((ArrayList)matr[i]).Count-1)

{

ind[i] = -1;

layer = i-1;

system.RemoveAt(system.Count-1);

if ((i-1)>=0)

{

ind[i-1]++;

if (ind[i-1] <= ((ArrayList)matr[i-1]).Count-1)

system[layer] = ((ArrayList)matr[layer])[ind[layer]];

}

}

}

//тест

while ( (layer != -1) && (Test(system,layer)) )

{

chit++;

num_brak++;

mf.textBox_num_brak.Text = num_brak.ToString();

mf.textBox_num_brak.Refresh();

ind[layer]++;

if (ind[layer] <= ((ArrayList)matr[layer]).Count-1)

system[layer] = ((ArrayList)matr[layer])[ind[layer]];

l = layer;

for(i = l;i>=0;i--)

{

if (ind[i] > ((ArrayList)matr[i]).Count-1)

{

ind[i] = -1;

layer = i-1;

system.RemoveAt(system.Count-1);

if ((i-1)>=0)

{

ind[i-1]++;

if (ind[i-1] <= ((ArrayList)matr[i-1]).Count-1)

system[layer] = ((ArrayList)matr[layer])[ind[layer]];

}

}

}

}

if (layer == (n-1))

{

//далее решение

//здесь происходит решение полученное системы

//Output(system);

//далее решение системы уравнений

//Console.WriteLine(num_system.ToString());

//if (num_system == 76548) while(true) {};

SolveSystem(system);

}

}

}

//------------

//отладочная функция для вывода системы уравнений в виде номеров

private void Output(ArrayList ar)

{

Console.WriteLine("Вывод системы № {0}:",num_system.ToString());

String str;

str = "";

foreach(int num in ar)

str = str + num.ToString() + " ";

Console.WriteLine(str);

}

/// <summary>

/// проверка на совместимость входящих уравнений

/// если набор уравнений некорректен то результат true

/// </summary>

private bool Test(ArrayList ar,int i)

{

bool result = false;

//проверка на повторяемость уравнений

if (FindIEquation(ar,(int)ar[i])) return true;

//правила отсечения

int j,k;

//счетчик повторений

int s = 0;

double val;

int n = cp.NumPolygons*2+1;

for(j = 0;j<=i;j++)

{

val = koef[(int)ar[j],n-1];

if (val == -1) s++;

}

if (s>1) return true;

//отсечение 9+5

//if ((chit % 10) == 0) return true;

return result;

}

/// <summary>

/// построение дерева решения и собственное поиск решения

/// </summary>

public ArrayList Solve()

{

ConvertSOFToMatrix();

ConvertSOFToTable();

/*//отладка - вывод таблицы коэффициентов

for(int i = 0;i<sof.Size();i++)

{

for(int j = 0;j<2*cp.NumPolygons+2;j++)

Console.Write("{0} ",koef[i,j]);

Console.WriteLine();

}*/

Generations();

/*for(int i = 0;i<sof.Size();i++)

sof.GetEquationByNumber(i).Output();*/

current = DateTime.Now;

return result;

}

/// <summary>

/// проверка на вхождение i-ого уравнения более одного раза

/// </summary>

private bool FindIEquation(ArrayList ar,int i)

{

int k = 0;

foreach(int num in ar)

if (num == i) k++;

return (k > 1);

}

/// <summary>

/// решение системы уравнений

/// </summary>

private void SolveSystem(ArrayList ar)

{

//номер системы

num_system++;

mf.textBox_NumSystems.Text = num_system.ToString();

mf.textBox_NumSystems.Refresh();

//количество уравнений

int m = 2*cp.NumPolygons+1;

//число неизвестных

int n = m;

/*

A - массив с нумерацией элементов [1..M, 1..N+1].

В столбцах от 1 до N содержится матрица системы,

В столбце N+1 содержится правая часть b.

*/

//double[,] a = new double[m+1,n+2];

//заполнение массива а

int i,j;

for(i = 1;i<=m;i++)

for(j = 1;j<=n+1;j++)

a[i,j] = koef[(int)(ar[i-1]),j-1];

//класс решающий систему уравнений

solveSLAU s = new solveSLAU();

//промежуточное решение

//double[,] sol;

//размерность решения

int dim;

s.svdsolvefundamental(ref a,m,n,ref sol,out dim);

/*

Solutions - массив с нумерацией элементов [1..N, 0..Dimension].

Фундаментальная система решений.

Столбец с номером 0 содержит частное решение системы уравнений (или решение с минимальной невязкой, если система несовместна).

Столбцы с номерами с 1 по Dimension содержат ортогональный набор векторов, являющихся базисом пространства решений однородной системы.

*/

bool flag;

if (dim == 0)

{

//if (num_system == 200) while (true) {};

flag = TestSolution(sol);

if (flag) num_points++;

if ( (sol[n,0] < (double)result[n-1]) && flag )

{

mf.progressBar.Value += mf.progressBar.Step;

if (mf.progressBar.Value == mf.progressBar.Maximum)

mf.progressBar.Value = 0;

mf.textBox_num_points.Text = num_points.ToString();

mf.textBox_num_points.Refresh();

for(i = 0;i<n;i++)

result[i] = sol[i+1,0];

}

/// <summary>

/// коэффициенты множества уравнений представляются в виде таблицы

/// </summary>

private void ConvertSOFToTable()

{

int num_koef = 2*cp.NumPolygons+2;

koef = new double[sof.Size(),num_koef];

Equation eq;

int i,j;

for(i = 0;i<sof.Size();i++)

{

eq = sof.GetEquationByNumber(i);

for(j = 0;j<num_koef-1;j++)

koef[i,j] = eq[j];

koef[i,j] = -eq[j];

}

}

//-----------------------------

//-----------------------------

//-----------------------------

//тестирование промежуточного решения на допустимость

//результат true, если решение допустимо

//в массиве sol нумерация [1..N, 0..0]

private bool TestSolution(double[,] sol)

{

//проверка неравенств на допустимость (принадлежность полосе)

int i,j,k,l;

double a = 0;

double eps = 5e-15;

Equation eq;

bool res = true;

for(i = 0;i<sof_strip.Size();i++)

{

eq = sof_strip.GetEquationByNumber(i);

for(j = 0;j<eq.Dimension();j++)

a += eq[j]*sol[j+1,0];

a += eq[eq.Dimension()];

if ( a > eps) return false;

a = 0;

}

//проверка неравенств на допустимость (взаимное непересечение многоугольников)

CollectionsPolygons cp_tmp = new CollectionsPolygons();

cp_tmp.Copy(cp);

Point p = new Point();

for(i = 0;i<cp_tmp.NumPolygons;i++)

{

p.X = sol[2*i+1,0];

p.Y = sol[2*i+2,0];

Polygon pol = new Polygon();

pol.Copy(cp_tmp.GetI(i));

((IOperations)pol).Shift(p);

((IChange)cp_tmp).SetI(pol,i);

}

for(i = 0;i<cp_tmp.NumPolygons-1;i++)

for(j = i+1;j<cp_tmp.NumPolygons;j++)

if ( cp_tmp.GetI(i).IntersectPolygons(cp_tmp.GetI(j)) )

return false;

return true;

}

}

}

Equation.cs

using System;

using System.Collections;

namespace Diplom

{

/// <summary>

/// класс-уравнение

/// </summary>

public class Equation

{

public Equation(int n)

{

data = new ArrayList(n+1);

for(int i = 0;i<n+1;i++)

data.Add(0.0);

}

/// <summary>

/// массив коэффициентов уравнения

/// </summary>

private ArrayList data;

/// <summary>

/// доступ к коэффициентам по индексу,начиная с 0

/// </summary>

public double this[int ind]

{

get

{

if ((ind > -1) && (ind < data.Count))

return ((double)data[ind]);

else return 0.0;

}

set

{

if ((ind > -1) && (ind < data.Count))

data[ind] = value;

}

}

/// <summary>

/// тестовый метод для вывода коэффициентов

/// </summary>

public void Output()

{

Console.WriteLine("Коэффициенты уравнения");

foreach(double koef in data)

Console.Write(koef.ToString()+" ");

Console.WriteLine("");

}

/// <summary>

/// возвращает количество переменных в уравнении

/// </summary>

public int Dimension()

{

return data.Count-1;

}

/// <summary>

/// проверка на равенство уравнений

/// </summary>

new public bool Equals(Object eq)

{

bool flag = true;

for(int i = 0;i<data.Count;i++)

if ((double)data[i] != ((Equation)eq)[i]) flag = false;

return flag;

}

/// <summary>

/// копирование объекта

/// </summary>

public void Copy(Equation eq)

{

for(int i = 0;i<data.Count;i++)

data[i] = eq[i];

}

}

}

Размещено на Allbest.ru


Подобные документы

  • Теоретические основы изучения площадей многоугольников. Вычисление площадей в древности. Различные подходы к изучению понятий "площадь", "многоугольник", "площадь многоугольника". Вычисление площади многоугольника по координатам его вершин. Формула Пика.

    дипломная работа [1,1 M], добавлен 24.02.2010

  • Задачи вычислительной линейной алгебры. Математическое моделирование разнообразных процессов. Решение систем линейных алгебраических уравнений большой размерности. Метод обратной матрицы и метод Гаусса. Критерии совместности и определенности системы.

    курсовая работа [220,0 K], добавлен 21.10.2011

  • Рассмотрение систем линейных алгебраических уравнений общего вида. Сущность теорем и их доказательство. Особенность трапецеидальной матрицы. Решение однородных и неоднородных линейных алгебраических уравнений, их отличия и применение метода Гаусса.

    реферат [66,4 K], добавлен 14.08.2009

  • Задачи на элементы теории вероятности и математической статистики. Решение систем линейных уравнений методом Крамера; методом Гаусса. Закон распределения дискретной случайной величены. Построение выпуклого многоугольника, заданного системой неравенств.

    контрольная работа [96,1 K], добавлен 12.09.2008

  • Решение задач систем линейных алгебраических уравнений, матричных уравнений, методы Гаусса и Кремера. Нахождение длины и координат вектора и исчисление его скалярного произведения. Уравнение прямой и определение координат точек неравенства; пределы.

    контрольная работа [220,9 K], добавлен 06.01.2011

  • Метод Зейделя как модификация метода простой итерации. Особенности решения систем линейных алгебраических уравнений. Анализ способов построения графика функций. Основное назначение формул Симпсона. Характеристика модифицированного метода Эйлера.

    контрольная работа [191,3 K], добавлен 30.01.2014

  • Сущность итерационного метода решения задачи, оценка его главных преимуществ и недостатков. Разновидности итерационных методов решения систем линейных алгебраических уравнений: Якоби, Хорецкого и верхней релаксации, их отличия и возможности применения.

    курсовая работа [39,2 K], добавлен 01.12.2009

  • Анализ метода простой итерации для решения систем линейных алгебраических уравнений и реализация его в виде двух программ, каждая из которых использует свой собственный способ перехода от системы одного вида к другому. Программные и технические средства.

    курсовая работа [497,8 K], добавлен 27.03.2011

  • Сущность и содержание метода Крамера как способа решения квадратных систем линейных алгебраических уравнений с ненулевым определителем основной матрицы. Содержание основных правил Крамера, сферы и особенности их практического применения в математике.

    презентация [987,7 K], добавлен 22.11.2014

  • Изучение основ линейных алгебраических уравнений. Нахождение решения систем данных уравнений методом Гаусса с выбором ведущего элемента в строке, в столбце и в матрице. Выведение исходной матрицы. Основные правила применения метода факторизации.

    лабораторная работа [489,3 K], добавлен 28.10.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.