Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Региональный поиск метод квадрантного дерева / doc / Региональный поиск. Метод квадрантного дерева.doc
Скачиваний:
27
Добавлен:
01.05.2014
Размер:
168.45 Кб
Скачать

4. Описание программы.

4.1 Классы.

Квадрантное дерево представлено в программе классом QTree:

class QTree {

private:

QTreeNode *m_root; //корень дерева

Rect m_domain; //область поиска

//осуществляет построение дерева

QTreeNode *BuildQTree(Grid &G,int M,int D,int level,int,int,int,int);

public:

//конструкторы

QTree(void);

QTree(Grid &G,int M,int D);

//деструктор

~QTree();

//создание новой структуры дерева

void Create(Grid &G,int M,int D);

//запрос по области

List *RangeQuery(Rect &range);

//отображение сетки построенного дерева

void DrawQTree(CDC*);

};

Узлы дерева представляются в виде объектов класса QTreeNode:

class QTreeNode {

private:

QTreeNode *child[4]; //дочерние поддеревья

List *pts; //указатель на список точек, покрываемых

//данным квадрантом

int m_size; //размер данного квадранта

//запрос по области

List *RangeQuery(Rect &range,Rect &quadrant);

//вычисление квадранта, накрываемого данным узлом

Rect Quadrant(Rect &s,int i);

//является ли текущий узел внешним

int isExternal();

//отображение квадранта, накрываемого данным узлом

void Draw(Rect&,CDC*);

public:

//конструкторы

QTreeNode(List*);

QTreeNode(void);

//деструктор

~QTreeNode(void);

friend class QTree;

};

Конструктор QTree(void) создает пустое дерево. Конструктору QTree(Grid& G,int M,int D) передается сетка G, коэффициент заполняемости ячеек M и предельная глубина D. Данный конструктор формирует квадрантное дерево по точкам в сетке G, обеспечивая ограничения, налагаемые значениями M и D. Предполагается, что количество ячеек вдоль каждой стороны сетки G равно степени 2.

QTree::QTree(Grid &G,int M,int D):

m_root(BuildQTree(G,M,D,0,0,G.m-1,0,G.m-1)),

m_domain(Rect(ELEMENT(0,0),ELEMENT(G.m*G.m_cellSize,G.m*G.m_cellSize)))

{

}

Компонентная функция BuildQTree строит квадрантное дерево по сетке G снизу вверх, от уровня отдельной ячейки сетки до нулевого уровня, при котором домен D рассматривается как единая ячейка. На самом нижнем уровне – уровне k, когда сетка имеет размер 2k2k – каждая ячейка сетки представлена своим собственным одноузловым квадрантным деревом. Узел содержит список тех точек из набора S, которые попадают в его ячейку. Для построения квадрантного дерева, корни которого лежат на уровне h, будем компоновать группы из 4-х квадрантных деревьев, корни которых лежат на следующем более низком уровне h+1. Когда достигнем уровня 0, самого верхнего уровня, то получим единое квадрантное дерево, которое накрывает весь домен D целиком. Каждый из внешних узлов дерева будет содержать список всех точек набора S, которые он накрывает.

В компонентную функцию BuildQTree передается сетка G, коэффициент заполняемости ячеек M и предельная глубина D. Она формирует квадрантное дерево для подсетки G[imin..imax,jmin..jmax] и возвращает его корневой узел. Параметр level указывает уровень, на котором расположен этот корневой узел внутри основного квадрантного дерева верхнего уровня.

QTreeNode *QTree::BuildQTree(Grid &G,int M,int D,int level,int imin,int imax,int jmin,int jmax)

{

if (imin==imax)

{

QTreeNode *q=new QTreeNode(G.m_pGrid[imin][jmin]);

G.m_pGrid[imin][jmin]=new List;

return q;

}

else

{

QTreeNode *p=new QTreeNode;

int imid=(imin+imax)/2;

int jmid=(jmin+jmax)/2;

p->child[0]=BuildQTree(G,M,D,level+1,imid+1,imax,jmid+1,jmax);

p->child[1]=BuildQTree(G,M,D,level+1,imid+1,imax,jmin,jmid);

p->child[2]=BuildQTree(G,M,D,level+1,imin,imid,jmin,jmid);

p->child[3]=BuildQTree(G,M,D,level+1,imin,imid,jmid+1,jmax);

for(int i=0;i<4;i++) p->m_size+=p->child[i]->m_size;

if ((p->m_size<=M)||(level>=D))

{

p->pts=new List;

for(int j=0;j<4;j++)

{

for(p->child[j]->pts->First();

!p->child[j]->pts->isHead();

p->child[j]->pts->Next())

p->pts->Append(new ELEMENT(*(p->child[j]->pts->Val())));

delete p->child[j];

p->child[j]=NULL;

}

};

return p; }}

В общем случае функция BuildQTree рекурсивно образует корень p для четырех его потомков и связывает их с узлом p.

Первый конструктор QTreeNode инициализирует свои элементы данных класса при передачи ему списка точек:

QTreeNode::QTreeNode(List *_pts):

pts(_pts),m_size(_pts->Lenght())

{

for(int i=0;i<4;i++)

child[i]=NULL;

}

Конструктор QTreeNode, не имеющий аргументов, используется при формировании списка точек внутреннего узла внутри компонентной функции BuildQTree.

QTreeNode::QTreeNode(void):

pts(NULL),m_size(0)

{

for(int i=0;i<4;i++)

child[i]=NULL;

}

Для осуществления запроса по заданной области R выполняется запрос к корневому узлу квадрантного дерева:

List *QTree::RangeQuery(Rect &r)

{

return m_root->RangeQuery(r,m_domain);

}

Для запроса по области R, начинающейся с узла n, необходимо:

1. Проверить, пересекается ли область R с областью (n). Если нет, то выполнить возврат.

{

List *result=new List;

if (!Intersect(r,span))

return result;

else if (isExternal())

for(pts->First();!pts->isHead();pts->Next())

{

ELEMENT *p=pts->Val();

if ((p->x<=r.ne.x)&&(p->x>=r.sw.x) &&

(p->y<=r.ne.y)&&(p->y>=r.sw.y))

result->Append(new ELEMENT(*p));

}

else

for(int i=0;i<4;i++)

{

List *l=child[i]->RangeQuery(r,Quadrant(span,i));

for(l->First();!l->isHead();l->Next())

result->Append(new ELEMENT(*(l->Val())));

}

return result;

}

Параметр span определяет квадрант, накрываемый текущим узлом.

4.2 Интерфейс.

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

  2. Дерево строится автоматически при изменении набора точек.

  3. Определение области поиска можно произвести нажатием правой кнопки мыши, ее удерживанием и перемещением курсора мыши в новую точку экрана.

  4. Сам поиск внутри выделенной области происходит по команде “Поиск”.

  5. Результаты поиска можно наблюдать непосредственно на экране: найденные точки будут выделяться более светлым цветом, чем все остальные.

  6. Предусмотрена возможность просмотра процедуры построения дерева по шагам (режимы просмотра вперед и назад, а также режим ускоренного просмотра: текущий узел дерева отображается на экране квадратной областью желтого цвета).

  7. Предусмотрена возможность просмотра процедуры поиска по области по шагам (режимы просмотра вперед и назад, а также режим ускоренного просмотра: текущая область, которая проверяется на пересечение с областью поиска отображается на экране квадратной областью желтого цвета, а текущая точка, проверяемая на попадание в область поиска – более крупными размерами).

  8. В главном окне приложения также можно менять следующие параметры:

а) минимальное количество точек в квадранте («Минимальное наполнение»)

г) Максимальная глубина дерева («Максимальная глубина»).

  1. Программа позволяет создавать новый документ (Файл/Создать), сохранять текущий (Файл/Сохранить, Файл/Сохранить как), загружать ранее сохраненный (Файл/Открыть), а также сохранять в графическом файле текущий вид рабочей области (Файл/Сохранить скриншот).

4.3 Внешний вид программы

Соседние файлы в папке doc