在C

时间:2015-12-03 18:14:26

标签: loops break dijkstra infinite

我已经实现了dijkstra算法,以处理二维数组。一切都运行得很好,但效率不高,因为当我的**地图被定义为map [10000] [20000]时,让我说我从[0] [0]的起始位置运行dijkstra,我想要知道坐标为[15] [7]的顶点的最短路径,如果我只需要那个特定的顶点,那么计算数千个不必要的顶点是没有意义的。

对于那种情况,我使用POINT类型的参数调用我的Dijkstra函数(它保存我的坐标),但是当计算到目标的最短路径时,我无法打破循环。

这是我的Dijkstra算法:

BLOCK *dijkstra(char **map, int height, int width, POINT start, POINT target) {
int position, i, speed, temp_distance;
BLOCK *blocks;          // all blocks in **mapp graph 
BLOCK block;            // current block
POINT temp;             // POINT is a variable from BLOCK structure, it contains coordinates
POINT *neighbours;      // array of POINT structures, holding coordinates of each neighbour for a specific block

// initializing every block in the **map (visited 0, distance INT_MAX, predecessor UNSET, etc.)
blocks = init(map, height, width);

// setting the starting position for dijkstra
position = start.y * width + start.x;
blocks[position].distance = 0;               // distance to itself is zero

push(blocks[position]);
block = pop();

while (block.distance != UNSET) {
    count = 0;
    block.visited = 1;
    temp.x = block.this.x;
    temp.y = block.this.y;
    neighbours = get_neighbours(map, height, width, temp, &count);

    // for loop for each neighbour of the current block
    for (i = 0; i < count; i++) {
        speed = get_speed(map, neighbours[i].y, neighbours[i].x);   // number of time-units to move through this block
        temp_distance = block.distance + speed;                     // total time (so far)
        position = neighbours[i].y * width + neighbours[i].x;       // position to current neighbour

        // if the distance is not set yet, or I just found a faster path
        if (blocks[position].distance < 0 || temp_distance < blocks[position].distance) {
            blocks[position].distance = temp_distance;              // overwriting distance to this block
            blocks[position].prev = block.this;                     // setting predecessor

            // this is my first time visiting this block
            if (blocks[position].visited == 0) {
                push(blocks[position]);
                blocks[position].visited = 1;
            }
        }
    }
    block = pop();
}
return blocks;

我认为如果当前块(顶点)的坐标相同,我可以通过打破循环来实现这一点,因为我的目标的coordenates和当前顶点的每个邻居的for循环已经完成。为此,我添加了这一行:

if(block.this.x == target.x && block.this.y == target.y) break;

在for循环之后。但是这个程序似乎在这个部分的不同函数中陷入无限循环:

blocks = dijkstra(map, height, width, start, target);       
position = target.y*width + target.x;

while ((blocks[position].this.x != start.x) || (blocks[position].this.y != start.y)) {
    //do stuff
    //...
    //set position to the predecessor of the current block
    position = blocks[position].prev.y*width + nodes[position].prev.x;
}

循环永远不会到达起点。奇怪的是,我运行这个代码块四次(只是使用不同的起始和目标顶点),因为我想得到以下距离:

[0] [0] - &gt;顶点A - >;顶点B - > 顶点C - &gt;顶点D

并且在这种情况下它只会进入无限循环(粗体 - C是开始,D是目标)),除了开始和目标之外几乎没有差异。

非常感谢你的帮助!

0 个答案:

没有答案