Автор работы: Пользователь скрыл имя, 17 Декабря 2013 в 11:14, курсовая работа
Появление компьютеров стало прорывом для всего человечества. В настоящее время с помощью них возможно производить расчёты с огромной скоростью. Они позволяют решать разнообразные задачи, одной из которых является поиск и составление путей от пункта А в пункт Б. Для таких задач наиболее применима теория графов.
Целью данной курсовой работы является разработка программного продукта для поиска максимально удалённых вершин в графе. Программный продукт должен иметь графический интерфейс и поддерживать любые типы графов.
1. Введение 3
2. Теория графов 4
2.1 Ориентированный граф 5
2.2 Смешанный граф 5
2.3 Изоморфные графы 6
2.4 Прочие связанные определения 6
2.5 Дополнительные характеристики графов 7
2.6 Обобщение понятия графа 8
2.7 Способы представления графа в информатике 9
3. Техническая реализация 11
3.1 Алгоритм поиска пути 11
3.2 Классы и диаграмма классов 11
3.3 Методы класса GraphEdge 13
3.4 Методы класса GraphNode 13
3.5 Функции класса Graph 14
3.6 Методы класса GraphMaxDistanceFinder 18
}3.7 Графический интерфейс 22
4. Заключение 25
5. Список литературы 26
Для поиска кратчайшего пути
между двумя вершинами в графе
был использован следующий
Поиск пути начинается с первой вершины. Данная вершина заносится в список, а затем, производится цикличный перебор вершин из списка. В этом цикле соседние с вершинами из списка вершины нумеруются в соответствии со степенью удаленности от начальной вершины (из которой идет поиск пути). Если вершина уже имеет такой номер, то новый номер ей назначен не будет, что фактически означает что вершина будет пропущена. Затем, вершины, пронумерованные в текущей итерации цикла добавляются в список (перед этим список очищается), а затем, происходит новая итерация цикла. Цикл будет выполнятся до тех пор, пока не будут пронумерованы все вершины. После нумерации вершин таким образом, начинает выполнятся следующий цикл. В этом цикле в список вершин с найденными точками пути заносятся вершины, начиная от конечной точки пути. Следующая вершина для занесения в список определяется минимальным номером соседней вершины с той вершиной, которая была занесена в список последней. Таким образом, цикл будет выполнятся пока не будет достигнута начальная вершина. Найденный маршрут будет являться кратчайшим маршрутом между двумя вершинами.
При разработке программного продукта, были реализованы следующие классы:
Диаграмма классов:
1. В конструктор класса передаются индексы вершин, связанных данным ребром:
public GraphEdge(int n1, int n2)
{
node1 = n1;
node2 = n2;
}
2. GetLinkedNodes - устанавливает значения переданных в метод параметров, в соответствии с индексами вершин, связанных данным ребром:
public void GetLinkedNodes(out int n1, out int n2)
{
n1 = node1;
n2 = node2;
}
1. В конструктор класса передаются координаты вершины, по которым данная вершина будет отображаться на форме, а также, необязательный параметр, отвечающий за видимость вершины на форме (по умолчанию, вершина будет видимой):
public GraphNode(int _x, int _y, bool _isValide = true)
{
x = _x;
y = _y;
isValide = _isValide;
}
2. Методы GetPostionX и GetPositionY возвращают X и Y координаты вершины соответственно:
public int GetPositionX()
{
return x;
}
public int GetPositionY()
{
return y;
}
3. Метод IsExists возвращает видимость вершины:
public bool isExists()
{
return isValide;
}
4. Метод Remove удаляет вершину (устанавливает координаты равными -1, а также устанавливает видимость вершины в false):
public void Remove()
{
x = -1;
y = -1;
isValide = false;
}
1. В конструктор класса
передаются имена файлов
public Graph(string nodeImage, string nodeOkImage)
{
nodes = new List<GraphNode>();
edges = new List<GraphEdge>();
LoadResources(nodeImage, nodeOkImage);
}
2. Метод Clear отвечает за очистку списков ребер и вершин:
public void Clear()
{
nodes.Clear();
edges.Clear();
}
3. Метод Draw отвечает за графическое отображение графа на переданном в функцию графическом контексте:
public void Draw(ref Graphics g)
{
Pen pen = new Pen(Color.Black, 5);
for (int i = 0; i < edges.Count; i++)
{
Point xFrom, xTo;
int node1, node2;
edges[i].GetLinkedNodes(out node1, out node2);
xFrom = new Point(nodes[node1].
xTo = new Point(nodes[node2].
g.DrawLine(pen, xFrom, xTo);
}
for (int i = 0; i < nodes.Count; i++)
{
GraphNode node = nodes[i];
if (node.isExists())
{
bool isOkNode = false;
foreach (GraphEdge edge in edges)
{
int node1, node2;
edge.GetLinkedNodes(out node1, out node2);
if (node1 == i || node2 == i)
{
isOkNode = true;
break;
}
}
if (isOkNode)
g.DrawImage(imgOkNode, node.GetPositionX() - imageCenter, node.GetPositionY() - imageCenter);
else
g.DrawImage(imgNode, node.GetPositionX() - imageCenter, node.GetPositionY() - imageCenter);
g.DrawString((i + 1).ToString(), font, Brushes.Black, node.GetPositionX() - 12, node.GetPositionY() - 12);
}
}
}
4. Метод EdgeAdd связывает вершины, имеющие указанные индексы (переданные в метод в качестве параметров), если вершины до этого еще не были связаны:
public int EdgeAdd(int node1, int node2)
{
bool canLink = true;
foreach (GraphEdge edge in edges)
{
int n1, n2;
edge.GetLinkedNodes(out n1, out n2);
if ((n1 == node1 || n1 == node2) && (n2 == node1 || n2 == node2))
{
canLink = false;
break;
}
}
if (canLink)
{
edges.Add(new GraphEdge(node1, node2));
return edges.Count - 1;
}
return -1;
}
5. Метод EdgeRemove удаляет ребро с заданным индексом:
public bool EdgeRemove(int id)
{
if (edges.Count > id && edges.Count > -1)
{
edges.RemoveAt(id);
}
return false;
}
6. Метод Load служит для загрузки графа из файла с заданным именем, передающимся в качестве параметра:
public bool Load(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
string sign = r.ReadString();
if (sign.Equals(signature, StringComparison.
{
Clear();
int nodeCount = r.ReadInt32();
int edgeCount = r.ReadInt32();
for (int i = 0; i < nodeCount; i++)
{
bool isValide = r.ReadBoolean();
NodeAdd(r.ReadInt32(), r.ReadInt32(), isValide);
}
for (int i = 0; i < edgeCount; i++)
{
EdgeAdd(r.ReadInt32(), r.ReadInt32());
}
r.Close();
return true;
}
r.Close();
return false;
}
7. Метод LoadResources загружает изображения вершин из заданных файлов картинок формата "png":
public void LoadResources(string nodeImage, string nodeOkImage)
{
imgNode = Image.FromFile(nodeImage);
imgOkNode = Image.FromFile(nodeOkImage);
imageCenter = (int)Math.Round((float)
font = new Font("Times New Roman", 14, FontStyle.Bold);
}
8. Метод NodeAdd добавляет вершину с указанными координатами и видимостью в граф:
public int NodeAdd(int x, int y, bool isValide = true)
{
nodes.Add(new GraphNode(x, y, isValide));
return nodes.Count - 1;
}
9. Метод NodeGetID возвращает индекс вершины, находящейся под курсором мыши, либо -1, если под курсором нет вершин:
public int NodeGetID(int mouseX, int mouseY)
{
for (int i = 0; i < nodes.Count; i++)
{
int nX = nodes[i].GetPositionX() - 16;
int nY = nodes[i].GetPositionY() - 16;
if (mouseX >= nX && mouseX <= nX + imgOkNode.Width)
if (mouseY >= nY && mouseY <= nY + imgOkNode.Height)
return i;
}
return -1;
}
10. Методы NodeGetX и NodeGetY возвращает x и y координаты указанной вершины соответственно:
public int NodeGetX(int id)
{
if (id < nodes.Count && nodes.Count > -1)
{
return nodes[id].GetPositionX();
}
return -1;
}
public int NodeGetY(int id)
{
if (id < nodes.Count && nodes.Count > -1)
{
return nodes[id].GetPositionY();
}
return -1;
}
11. Метод NodeRemove удаляет указанную вершину из графа (также, удаляет все ребра, связанные с вершиной):
public bool NodeRemove(int id)
{
if (nodes.Count > id && nodes.Count > -1)
{
List<int> toRemove = new List<int>();
for (int i = 0; i < edges.Count; i++)
{
int node1, node2;
edges[i].GetLinkedNodes(out node1, out node2);
if (node1 == id || node2 == id)
toRemove.Add(i);
}
while (toRemove.Count > 0)
{
EdgeRemove(toRemove[0]);
toRemove.RemoveAt(0);
for (int i = 0; i < toRemove.Count; i++)
{
toRemove[i] -= 1;
}
}
nodes[id].Remove();
return true;
}
return false;
}
10. Метод NodeSetPosition устанавливает координаты заданной вершины:
public bool NodeSetPosition(int id, int x, int y)
{
if (id < nodes.Count && nodes.Count > -1)
{
nodes[id].SetPosition(x, y);
return true;
}
return false;
}
10. Метод Save сохраняет граф в файл с заданным именем:
public void Save(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
BinaryWriter w = new BinaryWriter(fs);
w.Write(signature);
w.Write(nodes.Count);
w.Write(edges.Count);
for (int i = 0; i < nodes.Count; i++)
{
w.Write(nodes[i].isExists());
w.Write(nodes[i].GetPositionX(
w.Write(nodes[i].GetPositionY(
}
for (int i = 0; i < edges.Count; i++)
{
int node1, node2;
edges[i].GetLinkedNodes(out node1, out node2);
w.Write(node1);
w.Write(node2);
}
w.Flush();
w.Close();
}
1. В конструктор класса
передается ссылка на граф, в
котором необходимо проводить
поиск пути, а также, имя файла,
хранящего изображение вершины,
public GraphPathFinder(ref Graph _graph, string pathNodeImage)
{
graph = _graph;
imgPathNode = Image.FromFile(pathNodeImage);
}
2. Метод Draw служит для графического отображения графа с найденным маршрутом на заданном графическом контексте (Данный метод используется вместо метода Draw класса Graph:
public void Draw(ref Graphics g)
{
Pen pen;
Pen normalPen = new Pen(Color.Black, 5);
Pen linkedPen = new Pen(Color.Red, 5);
for (int i = 0; i < graph.edges.Count; i++)
{
Point xFrom, xTo;
int node1, node2;
graph.edges[i].GetLinkedNodes(
xFrom = new Point(graph.nodes[node1].
xTo = new Point(graph.nodes[node2].
pen = normalPen;
if (pathNodes.Contains(node1) && pathNodes.Contains(node2))
pen = linkedPen;
g.DrawLine(pen, xFrom, xTo);
}
for (int i = 0; i < graph.nodes.Count; i++)
{
GraphNode node = graph.nodes[i];
if (node.isExists())
{
NODE_TYPE nodeType = NODE_TYPE.NOT_CONNECTED; //0 - Not connected, 1 - OK node, 2 - Path node
if (!pathNodes.Contains(i))
foreach (GraphEdge edge in graph.edges)
{
int node1, node2;
edge.GetLinkedNodes(out node1, out node2);
if (node1 == i || node2 == i)
{
}
}
else
nodeType = NODE_TYPE.PATH;
switch (nodeType)
{
case NODE_TYPE.NOT_CONNECTED:
g.DrawImage(graph.imgNode, node.GetPositionX() - graph.imageCenter, node.GetPositionY() - graph.imageCenter);
break;
case NODE_TYPE.OK:
g.DrawImage(graph.imgOkNode, node.GetPositionX() - graph.imageCenter, node.GetPositionY() - graph.imageCenter);
break;
case NODE_TYPE.PATH:
g.DrawImage(imgPathNode, node.GetPositionX() - graph.imageCenter, node.GetPositionY() - graph.imageCenter);
Информация о работе Разработка приложения для поиска максимально удалённых вершин в графе