自主迷宫解决机器人和故障路径排序

时间:2015-05-11 18:24:47

标签: algorithm sorting maze robot

简介

我正在构建一个迷宫跑步者机器人,其目标是能够在从给定起点到给定终点的迷宫中导航。我自己设计了算法 - 在查看以前的工作之前,我坚持让自己的实现工作。

问题

算法的一部分涉及对方向进行排序(使用插入排序,因为数组太小) - 转发向后向上 down 就它们的前景而言。

我在排序方面遇到了一些问题,它根据三个因素对方向进行排序

  1. 状态:如果已探索 d 方向的路径?
  2. 距离:路径 p 末端的方块到端点的距离 - x y的最小值不同
  3. 长度:路径实际有多长。
  4. 排序时,我要比较因子1.如果它们相等,我比较因子2.如果因子2相等,我继续3.如果任何两个因素小于或< em>超过,我回复了。 出于某种原因,有时候状态较低的路径会被推到后面。我对路径的排序出了点问题。

    enter code here
    

    有什么想法吗?

    代码

        /*------------( Getting the best direction to go in )----------------    */
        /*
         * 0: North
         * 1: East
         * 2: South
         * 3: West
         */
        int  bestDirection(Point _curr_pos){
        Vec4 statuses/*1 for unexplored(better), 2 for explored(worse)*/,
            distances ,
            lengths = collectDistancesToWalls(),
            availablities = {POINT_REACHABLE, POINT_REACHABLE, POINT_REACHABLE, POINT_REACHABLE},
            directions = {0,1,2,3};
    
        //Give directions a length rating and distance rating and then sorts the directions, leaving the best direction in the front.
    
        //If we discover that we have already been in a location, we should block off the passage behind us leading to that location because it must be a loop.
        //Collecting the distance and length data. 
          for (int i=0; i < 4; i++) {
            Point direction_translated = translateOnAxisInDirection(_curr_pos, i, 1);
    
         //Converts the point to a reachable square - unnecessary to describe here. There is a domain specific problem which necessitates this function to be used. 
            Point heading_direction = pointToReachableSquare(direction_translated , i);
    
            //Distance from end of path to "headinglocation", the goal
            Point vec_to_end = subVec(heading_direction, headingLocation);
            distances[i]    =  min(absv(vec_to_end.x), absv(vec_to_end.y));
            statuses[i]     =  history[heading_direction.x][heading_direction.y].status;
    
            //If path is unreachable because of wall or something, then mark it as unreachable. 
            if (cmpVec(heading_direction, _curr_pos) || history[heading_direction.x][heading_direction.y].classification == WALL || !pointInIndBounds(direction_translated)) {
                availablities[i] = POINT_UNREACHABLE;
            }
        }
    
        //Insertion sort the distances.
        for (int i = 1; i < 4; i++) {
            int j = i - 1;
            while (
                comparePathOptions(
                statuses[i],
                distances[i],
                lengths[i],
                statuses[j],
                distances[j],
                lengths[j]
                   ) == LESS_THAN && (j >= 0)) {
                    int temp = directions[i];
                    directions[i] = directions[j];
                    directions[j] = temp;
                    j--;
            }
        }
    
        //Return the first reachable direction. 
        int ind = 0;
    
        int dir = directions[ind];
    
        while (availablities[ directions[ind] ] == POINT_UNREACHABLE && (ind<4)) {
            dir = directions[ind+1];
            ind++;
        }
    
        return dir;
    }
    

    比较功能:

    int relationship(int a, int b){
        if (a < b) return LESS_THAN;
        if (a > b) return MORE_THAN;
        return EQUAL;
    }
    
    //Edit this function
    //TODO: Edit comparePathOptions.
    //NOTE: Something
    int comparePathOptions(int n_explored, int n_closeness, int n_length,
                     int b_explored, int b_closeness, int b_length){
    
        int objs[][3] = {
            {n_explored, n_closeness, n_length},
            {b_explored, b_closeness, b_length}
        };
    
        for (int i = 0; i < 3; i++){
            int rel = relationship(objs[1][i],objs[0][i]);
            if (rel!= EQUAL ) return rel;
    
        }
        return EQUAL;
    }
    

    解决

    感谢@Kittsil我已经让算法运行了! 不是statuseslengths distancesji,而是directions[i or j]i j在更改方向数组时停止引用当前方向。

    已修改的代码:

       while ( (j >= 0) &&
            comparePathOptions(
            statuses[  directions[i] ],
            distances[ directions[i] ],
            lengths[   directions[i] ],
            statuses[  directions[j] ],
            distances[ directions[j] ],
            lengths[   directions[j] ]
               ) == MORE_THAN ) {
                int temp = directions[i];
                directions[i] = directions[j];
                directions[j] = temp;
                j--;
        }
    

    解决的迷宫:

    x: 0, y: 0
    H: 5, W:5, Ss:1
    4|#####|
    3|#####|
    2|#####|
    1|#####|
    0|*::::|
      01234 
    4|#####|
    3|#####|
    2|#####|
    1|#####|
    0| *:::|
      01234 
    4|#####|
    3|#####|
    2|#####|
    1|#####|
    0|  *::|
      01234 
    4|#####|
    3|#####|
    2|#####|
    1|#####|
    0|   *:|
      01234 
    4|#####|
    3|#####|
    2|####:|
    1|####:|
    0|    *|
      01234 
    4|#####|
    3|#####|
    2|####:|
    1|####*|
    0|     |
      01234 
    4|#####|
    3|#####|
    2|::::*|
    1|#### |
    0|     |
      01234 
    4|#####|
    3|#####|
    2|:::* |
    1|#### |
    0|     |
      01234 
    4|#####|
    3|#####|
    2|::*  |
    1|#### |
    0|     |
      01234 
    4|#####|
    3|#####|
    2|:*   |
    1|#### |
    0|     |
      01234 
    4|:####|
    3|:####|
    2|*    |
    1|#### |
    0|     |
      01234 
    4|:####|
    3|*####|
    2|     |
    1|#### |
    0|     |
      01234 
    4|*####|
    3| ####|
    2|     |
    1|#### |
    0|     |
      01234 
    

1 个答案:

答案 0 :(得分:2)

您正在对directions数组进行排序,但是您无法对其他数组进行排序;只要您进行第一次互换,statusesdistanceslengths就不再与directions相关联。

说明:问题在于您对比较功能的调用。在这段代码中:

while (
  comparePathOptions(statuses[i],
                     distances[i],
                     lengths[i],
                     statuses[j],
                     distances[j],
                     lengths[j]) 
    == LESS_THAN && 
  (j >= 0)
) {
    int temp = directions[i];
    directions[i] = directions[j];
    directions[j] = temp;
    j--;
}

您正在使用ij来访问包含排序信息的数组。只要ijdirections[i]directions[j]不同,就不会出现您的预期。您有两种选择: 一,将您的通话更改为comparePathOptions(.)

  comparePathOptions(statuses[directions[i]], 
                     distances[directions[i]], 
                     lengths[directions[i]],
                     statuses[directions[j]],
                     distances[directions[j]],
                     lengths[directions[j]]) 

OR ,按照惯例,将您关注的信息存储在(非常小的)对象中,并对这些对象的矢量进行排序。

此外,当您j=-1时,您会在循环中超出范围并进行比较。您应该将(j>=0)移动到AND的左侧。

说明:在几乎所有语言中,&amp;&amp;和||是short-circuiting。如果&&的左侧是false(或||的左侧是true),则该语言甚至不会评估右侧;它已经知道布尔函数的结果。在您的实例中,您不希望在comparePathOptions(.)时评估j<0,因为这会使您超出范围。因此,在使用j作为索引之前,您应该将0j 进行比较。