假设我有一个行*列网格,并且网格上的每个节点都有一个整数(状态)值。
state[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]
如果值
state[row][0] == state[row][NUMBER_OF_COLUMNS -1]
我想检查一下“路径”是否只包含这两点中的相同状态..
按路径,我的意思是左,右,底或顶的状态与原始状态相同。
我不确定它是否重要,但是让我们说状态是二进制(#或 - )所以如果我正在检查状态路径==“ - ”,我们可以继续路径如果状态为N,E,S,W也是==“ - ”
结束行必须等于起始行。
成功的例子:
|# # # # #|
|# # # # #|
|# # # # #|
|- # # # #|
|- - - - -|
或
|# # # # #|
|# # # - #|
|# - - - #|
|- - # - -|
|# # # - -|
或
|# # # # #|
|# # # - #|
|# # # - #|
|- - - - #|
|- # # - -|
失败的例子:
|# # # # #|
|# # # # #|
|# # # # #|
|- - - - #|
|# # - - -|
或
|# # # # #|
|# # # - #|
|# # # - #|
|# - - - #|
|- # # - #|
或
|# # # # #|
|# # - # #|
|# # # # #|
|# - # - #|
|- # - # -|
会失败。
我该怎么做?我在Objective C中编码,但是伪代码可以帮助我理解这些步骤就足够了。
除了检查BOOL是否存在路径之外,我还想返回路径中所有网格坐标的数组。
这是否易于实施,还是我在脑海中?
答案 0 :(得分:0)
听起来你正在研究一个非常常见的一般编程问题的特定情况。您的网格是特定类型的图形;每个小区是可以连接到相邻节点的节点。首先看一下最简单的graph traversal策略;广度优先或深度优先搜索。这两种算法是您应该熟悉的简单工具,以及解决此特定问题所需的所有问题。 在您的情况下,您可以将搜索限制为仅能够探索包含与当前节点相同值的节点,并查看您是否能够到达目的地。
现在,这些算法中的任何一个都会告诉您路径是否存在。这是一个好的开始,但如果你想找到最短的路径怎么办?为此我们有Dijkstra's Algorithm。
这很不错但我们仍然需要遍历整个图表以找到最短的路径。如果图表很小但是随着它的增长将成为一项昂贵的操作,这不是问题。有没有什么方法可以找到最短路径而无需到处搜索?有:看看A*(“明星”)算法。
答案 1 :(得分:0)
所以这是我的解决方案 - 基于@Floris链接的迷宫解决算法。
可能有一两个错误,它肯定没有优化,但现在可以使用。
非常容易理解,感谢大家的帮助:
-(BoardState)solutionPathExistsForColor {
//create a board copy where the last column equals the first
for (int i = 0; i < BOARD_ROWS+1; i++) {
for (int j = 0; j < BOARD_COLUMNS+1; j++) {
if (j == BOARD_COLUMNS) {
loopedBoard[i][j] = landed[i][0];
} else {
loopedBoard[i][j] = landed[i][j];
}
}
}
for (BoardState state = 1; state < kBoardStateCount; state++) {
//first check if it is possible there is a path
//for each row
for (int row = 0; row < BOARD_ROWS; row++) {
//set solution path to zero
for (int i = 0; i < BOARD_ROWS; i++) {
for (int j = 0; j < BOARD_COLUMNS; j++) {
solutionPath[i][j] = 0;
}
}
BOOL aTest = [self findPathToGoalRow:row //iterate
andGoalColumn:BOARD_COLUMNS //always the same
fromRow:row //iterate
andColumn:0 // always the same
ofState:state]; //iterate
if (aTest) {
CCLOG(@"Success! State %i", (int)state);
//now that you know a path exists, modify the path to contain all correct adjacent cells
[self fixSolutionPathOfColor:state];
return state;
} else {
CCLOG(@"Failure!");
}
}
}
return kBoardStateVOID;
}
-(BOOL)findPathToGoalRow:(int)goalRow
andGoalColumn:(int)goalColumn
fromRow:(int)fromRow
andColumn:(int)fromColumn
ofState:(BoardState)state {
//check to see if we've already seen this row and column
if (solutionPath[fromRow][fromColumn] == 1) {
return NO;
}
// if (x,y outside maze) return false
if (fromRow > BOARD_ROWS -1 || fromColumn > BOARD_COLUMNS || fromRow < 0 || fromColumn < 0) {
return NO;
}
// if (x,y is goal) return true
if (fromRow == goalRow && fromColumn == goalColumn) {
return YES;
}
// if (x,y not open) return false
//if ([self boardStateAtRow:fromRow andColumn:fromColumn] != state) {
if (loopedBoard[fromRow][fromColumn]!=state) {
return NO;
}
// mark x,y as part of solution path
solutionPath[fromRow][fromColumn] = 1;
// if (FIND-PATH(North of x,y) == true) return true
if ([self findPathToGoalRow:goalRow
andGoalColumn:goalColumn
fromRow:fromRow+1
andColumn:fromColumn
ofState:state]) {
return YES;
}
// if (FIND-PATH(East of x,y) == true) return true
if ([self findPathToGoalRow:goalRow
andGoalColumn:goalColumn
fromRow:fromRow
andColumn:fromColumn+1
ofState:state]) {
return YES;
}
// if (FIND-PATH(South of x,y) == true) return true
if ([self findPathToGoalRow:goalRow
andGoalColumn:goalColumn
fromRow:fromRow-1
andColumn:fromColumn
ofState:state]) {
return YES;
}
// if (FIND-PATH(West of x,y) == true) return true
if ([self findPathToGoalRow:goalRow
andGoalColumn:goalColumn
fromRow:fromRow
andColumn:fromColumn-1
ofState:state]) {
return YES;
}
// unmark x,y as part of solution path
solutionPath[fromRow][fromColumn] = 0;
return NO;
}
-(void)fixSolutionPathOfColor:(BoardState)color {
for (int column = 0; column < BOARD_COLUMNS; column++) {
BOOL bottomColumnOfSolutionPathFound = NO;
int checkingRow = 0;
while (!bottomColumnOfSolutionPathFound) {
if ([self solutionCellAtRow:checkingRow andColumn:column] == 1) {
bottomColumnOfSolutionPathFound = YES;
} else {
checkingRow++;
}
}
//you'll start with this bottom row and look below
if (solutionPath[checkingRow][column] == 1) {
int nextRowToCheck = checkingRow-1;
BOOL keepChecking = YES;
while (nextRowToCheck >= 0 && keepChecking) {
if ([self boardStateAtRow:(nextRowToCheck) andColumn:column] == color) {
if ([self solutionCellAtRow:(nextRowToCheck) andColumn:column] != YES) {
solutionPath[nextRowToCheck][column] = 1;
}
nextRowToCheck--;
} else {
keepChecking = NO;
}
}
//now repeat for above
nextRowToCheck = checkingRow+1;
keepChecking = YES;
while (nextRowToCheck < BOARD_ROWS && keepChecking) {
if ([self boardStateAtRow:(nextRowToCheck) andColumn:column] == color) {
if ([self solutionCellAtRow:(nextRowToCheck) andColumn:column] != YES) {
solutionPath[nextRowToCheck][column] = 1;
}
nextRowToCheck++;
} else {
keepChecking = NO;
}
}
}
}
}
谢谢!