function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
这是来自AIMA的回溯递归algorythm伪代码。但是,我不明白它是否返回所有可能的解决方案或只找到第一个解决方案。如果它是最后一个选项,你可以帮我修改它以返回一个可能的解决方案列表(或者至少更新一些全局列表)。
编辑:我用Java实现了这个算法。但是,有一个问题:如果我没有返回赋值,而是将其保存在结果中,则递归停止条件失败(即它不再存在)。我怎样才能实现另一个停止条件?也许我最后应该返回 true ?
这是我的代码:
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* @param line
* @param onePossibleSituation
* @param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
答案 0 :(得分:1)
此代码检查是否找到解决方案,如果找到,则返回解决方案。否则,继续回溯。这意味着,它返回找到的第一个解决方案。
if result ̸= failure then
return result
remove {var = value} from assignment
你可以这样修改:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
或者,更好的是,修改此部分:
if assignment is complete then
print assignment
return assignment // print it and return
关于已修改的问题:
首先,在第一个true
中返回if
,因此递归将知道它找到了解决方案。第二步,有一个错误,可能是:
if(!isPossibleToPlaceIt){
return(false);
}
应该是
if(isPossibleToPlaceIt){
return(true);
}
因为如果您的回溯找到了某些内容,它会返回true
,这意味着您不必再检查其他任何内容了。
编辑#2 :如果您想继续回溯以找到所有解决方案,只需使用if
删除整个上一个return
部分:
//if(isPossibleToPlaceIt){
// return(true);
//}
所以我们将以任何方式继续搜索。