当前位置: 首页 > 知识库问答 >
问题:

骑士之旅

赵锐
2023-03-14

我正在尝试编写骑士之旅递归算法

int mov[8][2] = {{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{-1,2},{1,-2},{-1,-2}};

typedef struct element {
    int x;
    int y;
    struct element *prev, *next;
} node; 

//adding pool to list
void dEnd(node **root, int x,int y)
{
    node *pos;
    pos = *root;
    while(pos->next!= NULL)
    pos = pos->next;
    pos->next = (node *)malloc(sizeof(node));
    pos->next->x=x;
    pos->next->y=y;
    pos->next->prev=pos;
    pos->next->next=NULL;
}

void uEnd(node **root,int x,int y)
{
    node *pos;
    pos = *root;
    while(pos->x!= x && pos->y !=y)
    {
        pos = pos->next;
    }
    pos->prev->next=NULL;
    free(pos);
}

void printAll(node **root)
{
    node *pos = *root;
    while(pos->next)
    {
        printf("%d %d\n", pos->x,pos->y);
        pos = pos->next;
    }
}

int contains(int x,int y)
{
    return(((x >= 0 ) && (x <= 7)) && ((y >= 0) && (y <= 7)));
}
//find move
int searchForMove(int x, int y, int **tab, node **list, int *number)
{

    int i ;
    for(i = 0; i < 8; i++)
    {
        int nx, ny;
        nx = x + mov[i][0];
        ny = y + mov[i][1];
        if(contains(nx, ny) && !tab[nx][ny])
        {
            dEnd(list, nx, ny);
            tab[nx][ny] = 1;
            *number++;
            if(!searchForMove(nx,ny,tab,list,number))
            {
                uEnd(list,nx,ny);
                tab[nx][ny]=0;
                *number--;
            }
        }
    }
    if(i == 7 && *number <64)
        return 0;
    if(*number == 64)
        return 1;
}

谁能告诉我哪里出错了?我已经一步一步地检查了什么池算法正在添加到列表中。什么是大惊奇算法在添加4,3池和6,4池后,应该用6,4作为实际位置来称呼它自己,但我不知道为什么它用4,3作为实际位置来称呼自己。

共有1个答案

昌和悦
2023-03-14

OP大部分都有。除了一些次要的代码之外,在两个地方错误的是*数字增量/减量。

int searchForMove(int x, int y, int **tab, node **list, int *number) {
  ...
  // *number++;  // This increase the pointer to the next pointer.
  (*number)++; // This dereferences number and increases it.
  ...
    // *number--;
    (*number)--; // CD

工作示例。“CD”意味着我的改变

// CD
#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int mov[8][2] = { { 2, 1 }, { 2, -1 }, { -2, 1 }, { -2, -1 }, { 1, 2 },
        { -1, 2 }, { 1, -2 }, { -1, -2 } };

typedef struct element {
  int x;
  int y;
  struct element *prev, *next;
} node;

//adding pool to list
void dEnd(node **root, int x, int y) {
  node *pos;
  pos = *root;
  assert(pos); // CD
  while (pos->next != NULL)
    pos = pos->next;
  pos->next = (node *) malloc(sizeof(node));
  pos->next->x = x;
  pos->next->y = y;
  pos->next->prev = pos;
  pos->next->next = NULL;
}

void uEnd(node **root, int x, int y) {
  node *pos;
  pos = *root;
  while (pos->x != x && pos->y != y) {
    pos = pos->next;
  }
  pos->prev->next = NULL;
  free(pos);
}

void printAll(node **root) {
  node *pos = *root;
  unsigned i = 0; // CD
  uint64_t mask = 0; // CD
  while (pos->next) {
    // printf("%d %d\n", pos->x, pos->y);
    printf("%2u %d %d\n", i++, pos->x, pos->y); // CD prepend visit index.
    mask |= 1llu << (pos->x + 8*pos->y); // CD accumulate visited squares
    pos = pos->next;
  }
  printf("Mask %016" PRIX64 "\n", mask); // CD Show all locations visited
}

int contains(int x, int y) {
  return (((x >= 0) && (x <= 7)) && ((y >= 0) && (y <= 7)));
}

//find move
int searchForMove(int x, int y, int **tab, node **list, int *number) {
  int i;
  for (i = 0; i < 8; i++) {
    int nx, ny;
    nx = x + mov[i][0];
    ny = y + mov[i][1];
    if (contains(nx, ny) && !tab[nx][ny]) {
      dEnd(list, nx, ny);
      tab[nx][ny] = 1;

      // *number++;
      (*number)++; // CD

      if (!searchForMove(nx, ny, tab, list, number)) {
        uEnd(list, nx, ny);
        tab[nx][ny] = 0;

        // *number--;
        (*number)--; // CD

      }
    }
  }
  if (i == 7 && *number < 64)
    return 0;
  if (*number == 64)
    return 1;
  return 2;  // CD added
}

// All added by CD
int main(int argc, char *argv[]) {
  int tab0[8] = {0,0,0,0,0,0,0,0};
  int tab1[8] = {0,0,0,0,0,0,0,0};
  int tab2[8] = {0,0,0,0,0,0,0,0};
  int tab3[8] = {0,0,0,0,0,0,0,0};
  int tab4[8] = {0,0,0,0,0,0,0,0};
  int tab5[8] = {0,0,0,0,0,0,0,0};
  int tab6[8] = {0,0,0,0,0,0,0,0};
  int tab7[8] = {0,0,0,0,0,0,0,0};
  int *tab[8] = {tab0, tab1, tab2, tab3, tab4, tab5, tab6, tab7 };
  node HeadNode = { 0, 0, NULL, NULL };
  node *pHeadNode = &HeadNode;
  int number = 0;
  int result;
  result = searchForMove(0, 0, tab, &pHeadNode, &number);
  printAll(&pHeadNode);
  return result;
}
 类似资料:
  • 另一个经典问题,我们可以用来说明第二个通用图算法称为 “骑士之旅”。骑士之旅图是在一个棋盘上用一个棋子当骑士玩。图的目的是找到一系列的动作,让骑士访问板上的每格一次。一个这样的序列被称为“旅游”。骑士的旅游难题已经吸引了象棋玩家,数学家和计算机科学家多年。一个 $$8 \times 8$$ 棋盘的可能的游览次数的上限为 $$1.305 \times 10^{35}$$ ;然而,还有更多可能的死胡同

  • 有最后关于骑士之旅一个有趣的话题,然后我们将继续到深度优先搜索的通用版本。主题是性能。特别是,knightTour 对于你选择下一个要访问的顶点的方法非常敏感。例如,在一个5乘5的板上,你可以在快速计算机上处理路径花费大约1.5秒。但是如果你尝试一个 $$8 \times 8$$ 的板,会发生什么?在这种情况下,根据计算机的速度,你可能需要等待半小时才能获得结果!这样做的原因是我们到目前为止所实现

  • 我们将用来解决骑士旅游问题的搜索算法称为 深度优先搜索(DFS)。尽管在前面部分中讨论的广度优先搜索算法一次建立一个搜索树,但是深度优先搜索通过尽可能深地探索树的一个分支来创建搜索树。在本节中,我们将介绍实现深度优先搜索的两种算法。我们将看到的第一个算法通过明确地禁止一个节点被访问多次来直接解决骑士的旅行问题。第二种实现是更通用的,但是允许在构建树时多次访问节点。第二个版本在后续部分中用于开发其他

  • 为了将骑士的旅游问题表示为图,我们将使用以下两个点:棋盘上的每个正方形可以表示为图形中的一个节点。 骑士的每个合法移动可以表示为图形中的边。 Figure 1 展示了骑士的移动以及图中的对应边。 Figure 1 要构建一个 n*n 的完整图,我们可以使用 Listing 1 中所示的 Python 函数。knightGraph 函数在整个板上进行一次遍历。 在板上的每个方块上,knightGra

  • 当我运行程序而不是找到骑士之旅时,我收到了一个StackOverflow错误。任何想法是什么导致了这一点,以及我如何改变我的代码,实际上找到骑士之旅,并摆脱这个错误。项目是为我的CS280课程,并在周五到期,请帮助。谢谢!!

  • 我正在尝试编写一个骑士之旅算法,它有两个数组,访问和板。ACCESS是我用来判断下一步是什么的数组,board是用户将看到的最终结果的数组。我的算法通过检查找到可用移动次数最少的正方形,然后到达那里。如果恰好有两个可能的移动,并且可用的移动次数相同,我会找到哪一个离中心最远(离边界最近),然后移动到该点。这个算法应该会一直提供一个完美的64步骑士巡演程序,但我通常只得到大约60步,有人能告诉我为什