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