C语言中的路径查找算法

C语言中的路径查找算法,c,algorithm,graph,C,Algorithm,Graph,好的,我有一个董事会,我需要找到所有可能的解决方案。它从电路板的左上角开始,通过水平或垂直,它必须访问电路板的每个元素。为了成功移动到另一个元素,第一个字母或第二个字母必须与前一个字母匹配。它只能访问每个元素一次,而且只能访问一次,但它可以跳过它。如果我有一个这样的董事会: XY-YX-XX XX YY XY YX-XY-XX 示例解决方案路径为:XY->XX->YX->XX->XY->YY->YX->XX->XY 我曾想过使用BFS,但我还没有学会排队,所以我能在没有排队的情况下使用它吗?顺便

好的,我有一个董事会,我需要找到所有可能的解决方案。它从电路板的左上角开始,通过水平或垂直,它必须访问电路板的每个元素。为了成功移动到另一个元素,第一个字母或第二个字母必须与前一个字母匹配。它只能访问每个元素一次,而且只能访问一次,但它可以跳过它。如果我有一个这样的董事会:

XY-YX-XX

XX YY XY

YX-XY-XX

示例解决方案路径为:XY->XX->YX->XX->XY->YY->YX->XX->XY


我曾想过使用BFS,但我还没有学会排队,所以我能在没有排队的情况下使用它吗?顺便说一句,这是在C语言中,原因是我正在学习的编程课程只涉及C语言。

你可以尝试回溯和修剪。它使用递归而不是队列


您可以尝试回溯和修剪。它使用递归而不是队列


请注意,即使找到一个解决方案,也不是所有的解决方案都是问题,因为
约束只访问每个元素一次。您的问题实际上是网格上的变量

因此,没有已知的多项式解确定这样一条路径是否存在,更不用说找到所有路径了

@Doct0rz建议使用回溯可能是解决此问题的最佳方法。具体地说,我会选择一些只为相关分支维护
访问的
集的变体

伪代码:

specialDFS(v,visited):
  if (visited.size == |V|):
      print this path by following the "father" field up to the root.
  for each edge (v,u):
     if (u is in visited): //do not check vertices that are already on the path
          continue
     visited.add(u)
     u.father <- v
     specialDFS(u,visited) //recursive call
     visited.remove(u) //clean the work environment, we maintain visited set only for the same path
specialDFS(v,已访问):
如果(visited.size==| V |):
按照“父”字段一直到根打印此路径。
对于每个边(v,u):
如果(u处于已访问状态)://不要检查路径上已经存在的顶点
持续
已访问。添加(u)

u、 父注意,即使找到一个解决方案,而不是所有的解决方案都是问题,因为
对每个元素只访问一次
约束。您的问题实际上是网格上的变量

因此,没有已知的多项式解确定这样一条路径是否存在,更不用说找到所有路径了

@Doct0rz建议使用回溯可能是解决此问题的最佳方法。具体地说,我会选择一些只为相关分支维护
访问的
集的变体

伪代码:

specialDFS(v,visited):
  if (visited.size == |V|):
      print this path by following the "father" field up to the root.
  for each edge (v,u):
     if (u is in visited): //do not check vertices that are already on the path
          continue
     visited.add(u)
     u.father <- v
     specialDFS(u,visited) //recursive call
     visited.remove(u) //clean the work environment, we maintain visited set only for the same path
specialDFS(v,已访问):
如果(visited.size==| V |):
按照“父”字段一直到根打印此路径。
对于每个边(v,u):
如果(u处于已访问状态)://不要检查路径上已经存在的顶点
持续
已访问。添加(u)
u、 父亲
#包括
typedef结构数据{
常量字符*元素;
国际访问;
}数据;
#定义尺寸3
数据板[尺寸][尺寸]={
{{“XY”,0},{“YX”,0},{“XX”,0},
{{“XX”,0},{“YY”,0},{“XY”,0},
{{“YX”,0},{“XY”,0},{“XX”,0}
};
#定义路径(大小*大小)
int路径[PathLen];
数据*位置(整数*x,整数*y){
如果(*x<0)*x+=尺寸;
如果(*x>=尺寸)*x-=尺寸;
如果(*y<0)*y+=尺寸;
如果(*y>=尺寸)*y-=尺寸;
返回和板[*y][*x];
}
无效邻居(int x,int y,int wx,int wy,int level);
无效搜索路径(整数x、整数y、整数级别){
路径[级别]=大小*y+x;
如果(级别==路径-1){
int i;
对于(i=0;我离开了)
邻居(x,y,x+1,y,level);//原点->右侧
邻居(x,y,x,y-1,等级);//原点->向上
邻居(x,y,x,y+1,级别);//原点->向下
}
}
//子程序
//原点(x,y)->近邻(wx,wy)
无效邻居(整数x,整数y,整数wx,整数wy,整数级别){
数据*wk;
wk=位置(&wx,&wy);
如果(工作->访问==0&&
(板[y][x]。元素[0]==板[wy][wx]。元素[0]||
板[y][x]。元素[1]==板[wy][wx]。元素[1])){
wk->visted=1;
搜索路径(wx,wy,级别+1);
wk->visted=0;
}
}
内部主(空){
int x=0,y=0,level=0;
单板[0][0]。访问次数=1;
搜索路径(x,y,level);
返回0;
}
/*
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->XY->XX->YX
XY->XX->XY->XX->YX->XX->XY->YY->YX
XY->XX->XY->XX->YX->YY->XY->XX->YX
XY->XX->YX->XX->XY->YY->XY->XX->YX
XY->XX->YX->XX->XY->YY->YX->XX->XY
XY->XX->YX->XX->XY->XX->YX->YY->XY
*/
#包括
typedef结构数据{
常量字符*元素;
国际访问;
}数据;
#定义尺寸3
数据板[尺寸][尺寸]={
{{“XY”,0},{“YX”,0},{“XX”,0},
{{“XX”,0},{“YY”,0},{“XY”,0},
{{“YX”,0},{“XY”,0},{“XX”,0}
};
#定义路径(大小*大小)
int路径[PathLen];
数据*位置(整数*x,整数*y){
如果(*x<0)*x+=尺寸;
如果(*x>=尺寸)*x-=尺寸;
如果(*y<0)*y+=尺寸;
如果(*y>=尺寸)*y-=尺寸;
返回和板[*y][*x];
}
无效邻居(int x,int y,int wx,int wy,int level);
无效搜索路径(整数x、整数y、整数级别){
路径[级别]=大小*y+x;
如果(级别==路径-1){
int i;
对于(i=0;我离开了)
邻居(x,y,x+1,y,level);//原点->右侧
邻居(x,y,x,y-1,等级);//原点->向上
邻居(x,y,x,y+1,级别);//原点->向下
}
}
//子程序
//原点(x,y)->近邻(wx,wy)
无效邻居(整数x,整数y,整数wx,整数wy,整数级别){
数据*wk;
wk=位置(&wx,&wy);
如果(工作->访问==0&&
(板[y][x]。元素[0]==板[wy][wx]。元素[0]||
板[y][x]。元素[1]==板[wy][wx]。元素[1])){
wk->visted=1;
搜索路径(wx,wy,级别+1);
wk->visted=0;
}
}
内部主(空){
int x=0,y=0,level=0;
单板[0][0]。访问次数=1;
搜索路径(x,y,level);
返回0;
}
/*
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->XY->XX->YX
XY->XX->XY->XX->YX->X
#include <stdio.h>

typedef struct data {
  const char *element;
  int  visited;
} Data;

#define Size 3

Data Board[Size][Size] = {
    {{ "XY", 0 }, { "YX", 0 },{ "XX", 0 }},
    {{ "XX", 0 }, { "YY", 0 },{ "XY", 0 }},
    {{ "YX", 0 }, { "XY", 0 },{ "XX", 0 }}
};

#define PathLen (Size*Size)

int Path[PathLen];

Data *pos(int *x, int *y){
    if(*x < 0)     *x += Size;
    if(*x >= Size) *x -= Size;
    if(*y < 0)     *y += Size;
    if(*y >= Size) *y -= Size;
    return &Board[*y][*x];
}

void neighbor(int x, int y, int wx, int wy, int level);

void search_path(int x, int y, int level){
    Path[level] = Size * y + x;
    if(level == PathLen - 1){
        int i;
        for(i=0;i<PathLen;++i){
            int x = Path[i] % Size;
            int y = Path[i] / Size;
            if(i == PathLen - 1)
                printf("%s\n", Board[y][x].element);
            else
                printf("%s->", Board[y][x].element);
        }
    } else {
        neighbor(x, y, x - 1, y, level);//origin -> left
        neighbor(x, y, x + 1, y, level);//origin -> right
        neighbor(x, y, x, y - 1, level);//origin -> up
        neighbor(x, y, x, y + 1, level);//origin -> down
    }
}
//subroutine
//origin(x,y) -> neighbor(wx,wy)
void neighbor(int x, int y, int wx, int wy, int level){
    Data *wk;
    wk = pos(&wx,&wy);
    if(wk->visited == 0 &&
       (Board[y][x].element[0] == Board[wy][wx].element[0] ||
        Board[y][x].element[1] == Board[wy][wx].element[1])){
        wk->visited = 1;
        search_path(wx, wy, level + 1);
        wk->visited = 0;
    }
}

int main(void){
    int x = 0, y = 0, level = 0;
    Board[0][0].visited = 1;
    search_path(x, y, level);
    return 0;
}
/*
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->YX->XX->XY
XY->XX->YX->YY->XY->XX->XY->XX->YX
XY->XX->XY->XX->YX->XX->XY->YY->YX
XY->XX->XY->XX->YX->YY->XY->XX->YX
XY->XX->YX->XX->XY->YY->XY->XX->YX
XY->XX->YX->XX->XY->YY->YX->XX->XY
XY->XX->YX->XX->XY->XX->YX->YY->XY
*/