我试图实现Dijkstra算法,以找到从起始节点到250px乘200px原始图像文件的最后一个节点的最短路径(例如,起始节点= [0] [0],结束节点= [250] [200])。原始文件的作用类似于地形图,其中每个字节代表一个高程,从一个节点到其相邻节点的距离成本是两个节点的高程差加1,用于从一个节点移动到其节点的能量邻居(运动只能水平和垂直发生)。
我在C ++中使用优先级队列跟踪了算法的伪代码,但我正在努力调试以确定我是否已成功正确地实现了算法以及实现算法以实现这种独特且相对具有挑战性的情况。此外,我的目标是在原始文件中输出最短路径,然后在Photoshop中查看它以查看它是否正确显示,但在此任务中完全失败。
毕竟,我的问题是......
1。在解决上述问题的实现中是否存在任何可见/明显的逻辑错误?
2。任何人都可以提出一些关于如何尝试输出原始文件中的最短路径或类似行的东西的想法吗?
感谢您的帮助。
P.S。我知道我已经使用C表示法而不是C ++的流操作来使用文件读写操作,因此无需告诉我如何更改它。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <queue>
#define INFINITY 99999
#define MAP_SIZE 50000 // 250px by 200px
void dijkstra(int, int, unsigned int []);
// The terminology 'Node' and 'Vertex' are used interchangeably
// throughout the program.
struct Node
{
int index; // index of node in graph
unsigned int distance; // distance from source (only allow positive distances)
};
// A simple class to compare the distances of two Node structures.
class CompareDist
{
public:
bool operator()(Node& n1, Node& n2)
{
if (n1.distance < n2.distance)
return true;
else
return false;
}
};
int main()
{
FILE *fr = fopen("map.raw","rb");
FILE *fw1 = fopen("path.raw","w+");
int i;
unsigned char read[MAP_SIZE];
unsigned int original[MAP_SIZE]; //2D array implemented in 1D array
unsigned char path[MAP_SIZE];
if(!fr){
std::cout<<"Error: Can't open raw file!"<<std::endl;
return 0;
}
fread(read, sizeof(char), MAP_SIZE, fr);
fclose(fr);
//convert to int for calculation
for (i = 0; i < MAP_SIZE; i++) {
original[i] = (int)((unsigned short)read[i]);
}
dijkstra(0, MAP_SIZE, original);
for (i = 0; i < MAP_SIZE; i++) {
path[i] = (unsigned char)original[i]; // output path array
}
fwrite(&path,sizeof(char),MAP_SIZE,fw1);
fclose(fw1);
return 0;
}
// Implementation of dijkstra's algorithm using a priority queue
// Inputs: int s --> source node
// int size --> the total number of vertices in graph
// unsigned int graph[] --> your graph
// Outputs: nothing
void dijkstra(int source, int size, unsigned int graph[MAP_SIZE])
{
bool *visited = new bool [size]; // array to check which vertices have already been visited
unsigned int *distance = new unsigned int [size]; // table to hold the distances of each vertex from the source vertex
// initialize the distance of each node to infinity and visited as false
for (int i = 0; i < size; i++)
{
distance[i] = INFINITY;
visited[i] = false;
}
// the distance of the source to itself is obviously 0
distance[source] = 0;
// create priority queue structure
std::priority_queue< Node, std::vector< Node >, CompareDist> priorityQ;
// Create the first node as the source and put it into the queue
Node first = { source, 0 };
priorityQ.push(first);
// Pick the top node of priority queue.
// Update the queue with next visited vertex after checking
// which non-visited vertex has the minimum distance from
// the source vertex.
while(!priorityQ.empty())
{
Node tempNode = priorityQ.top();
priorityQ.pop();
int nodeIndex = tempNode.index;
visited[nodeIndex] = true;
for(int i = 0;i < size; i++)
{
if(graph[i] != 0 && !visited[i])
{
// Update the distance if it is smaller than the current distance
int tempDist = distance[nodeIndex] + graph[i] + 1;
if(distance[i] > tempDist)
{
distance[i] = tempDist;
Node newNode;
newNode.index = i;
newNode.distance = distance[i];
priorityQ.push(newNode);
}
}
}
}
// DEBUG TEST FOR CORRECT OUTPUT
std::cout << "The shortest distance from " << source << " to all other nodes is" << std::endl;
for(int i = 0; i < size; i++)
{
std::cout << i << " : " << distance[i] << std::endl;
graph[i] = distance [i];
}
std::cout << std::endl << std::endl;
}