1
)
Dijkstras alg를 처음부터 사용하는 차트 컨트롤을 작성합니다. 나는이 알고리즘을 이해하려고 인터넷을 샅샅이 조사했다. 나는 그것을 마침내 이해한다고 생각하지만 내 코드가 제대로 작동하지 않습니다. 누군가를 바라보며 이것에 대해 엿볼 수있을 것입니다. 그리고 그들이 그 거래가 무엇인지 알 수 있는지 알게 될 것입니다 ...Dijkstras 알고리즘 (C#
나는 이것이 모든 것이 필요할 것 같은 3 가지 방법으로 붙여 넣을 것입니다.
처음에는 내 자신의 버텍스 데이터 유형을 만들었다 고 말할 것입니다. 노드의 ID, X와 Y, 상태 문자열, 그리고 정점 데이터 유형 인 부모와 정수의 거리를 포함합니다.
//function to populate lists with all the vertices on the graph
private List<Vertex> getNodes()
{
myVertices.Clear();
//get all non-dg nodes in list
for (int i = 0; i < chtGraph.Series[0].Points.Count; i++)
{
Vertex vertice = new Vertex(chtGraph.Series[0].Points[i]["ID"], (float)chtGraph.Series[0].Points[i].XValue, (float)chtGraph.Series[0].Points[i].YValues[0], "UNVISITED", Convert.ToInt32(chtGraph.Series[0].Points[i].Label), double.PositiveInfinity, null);
myVertices.Insert(i, vertice);
}
//get all dg nodes in list
for (int i = 0; i < chtGraph.Series[1].Points.Count; i++)
{
Vertex vertice = new Vertex(chtGraph.Series[1].Points[i]["ID"], (float)chtGraph.Series[1].Points[i].XValue, (float)chtGraph.Series[1].Points[i].YValues[0], "UNVISITED", Convert.ToInt32(chtGraph.Series[1].Points[i].Label), double.PositiveInfinity, null);
myVertices.Insert(i, vertice);
}
return myVertices;
}
//function to return to a list all the adjacents for a specified node. Excludes parent node
private List<Vertex> checkAdjacents(Vertex node, int intTransPower)
{
List<Vertex> Adjacents = new List<Vertex>();
int distance;
for (int i = 0; i < myVertices.Count; i++)
{
if (node.id != myVertices[i].id)
{
distance = calcDistance(node.x, node.y, myVertices[i].x, myVertices[i].y);
if (distance <= intTransPower)
{
if (rdbTotalLength.Checked)
{
myVertices[i].distance = distance;
}
else if (rdbPathEnergy.Checked)
{
myVertices[i].distance = getCost(node, myVertices[i]);
}
else
{
myVertices[i].distance = 1;
}
myVertices[i].parent = node;
Adjacents.Add(myVertices[i]);
foreach (Vertex p in openList)
{
if (myVertices[i].id == p.id)
{
p.distance = myVertices[i].distance;
p.parent = myVertices[i].parent;
}
}
}
}
}
return Adjacents;
}
여기 dijkstras ....입니다. 현재 제대로 작동하지 않고 있으며 그 사실을 알 수 없습니다.
private void dijkstra(Vertex start, Vertex end)
{
openList.Clear();
//populate two lists with all the nodes in the graph
openList = getNodes();
myVertices = getNodes();
//adjacents list for each vertex visited
List<Vertex> adjacents = new List<Vertex>();
//final list that is populated with the final path of vertices
List<Edge> shortestPath = new List<Edge>();
//used in calculating adjacent nodes. If distance is greater than transpower, then nodes are not connected
int intTransPower = Convert.ToInt32(txtTransPower.Text);
//set current vertex as the starting node
Vertex current = start;
//set initially to false
bool pathFound = false;
//find the starting node from the list of all vertices. Set it's distance to 0
foreach (Vertex p in openList)
{
if (p.id == current.id)
{
p.status = current.status;
p.distance = 0;
}
}
foreach (Vertex p in myVertices)
{
if (p.id == current.id)
{
p.status = current.status;
p.distance = 0;
}
}
//reorder the list to bring the starting node to the first element
openList = openList.OrderBy(h => h.distance).ToList();
//openList.Add(current);
//this.insert(openList, current, true);
// Repeat while the openlist is not empty and you haven't reached the end
while (openList.Count > 0)
{
//remove node at element 0. Sorted by smallest distance so it always gets removed first
current = openList[0];
openList.RemoveAt(0);
//if the current node = the ending node, then we have found the path. Break loop and build the final path.
if (current.id == end.id)
{
pathFound = true;
break;
}
//collect up all the adjacent nodes for the current vertex
//does NOT include the current vertex we are on
adjacents = checkAdjacents(current, intTransPower);
foreach (Vertex v in adjacents)
{
float alt = (float)current.distance + calcDistance(current.x, current.y, v.x, v.y);
Convert.ToInt32(alt);
if (alt < v.distance)
{
v.distance = alt;
v.parent = current;
for (int i = 0; i < openList.Count; i++)
{
if (v.id == openList[i].id)
{
openList[i].distance = alt;
openList[i].parent = current;
}
}
}
}
openList = openList.OrderBy(h => h.distance).ToList();
}
if (pathFound)
{
// collect path
this.foundPath.Clear();
Vertex last = current;
while (current != start && current != null)
{
this.foundPath.Add(current);
if (current.parent == last)
break;
last = current;
current = current.parent;
}
this.foundPath.Add(current);
}
}
수동 디버깅을위한 그래프 :) – NickD
"현재 작동하지 않습니다."더 구체적으로 할 수 있습니까? – Magnus
최종 노드를 찾고 최종 경로를 만들기 시작할 때까지 작동하는 것처럼 보입니다. 아이디어는 끝 노드를 가져다가 묶인 부모 노드를보고 그 노드를 선택하고 부모를 식별하는 것입니다. 마침내 부모 노드가없는 시작으로 돌아갈 때까지. 그런 다음 경로에 저장해야합니다. 거기에서 경로를 보여줄 선을 그릴 수 있습니다. 그러나 이것은하지 않습니다. 마지막 경로를 계산하기 시작하면 Node1, node2, node3, node3, node3, node4와 같은 노드 ID를 갖습니다. 따라서 실제로 올바른 경로를 생성 할 수 없습니다. – dvsoukup