首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归回溯多个解决方案

递归回溯多个解决方案
EN

Stack Overflow用户
提问于 2013-03-24 18:26:36
回答 1查看 2.7K关注 0票数 1
代码语言:javascript
复制
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的回溯递归算法。但是,我不明白它是返回了所有可能的解决方案,还是只返回了第一个找到的解决方案。如果这是最后一个选项,请您帮助我修改它以返回一个可能的解决方案列表(或者至少更新一些全局列表)。

编辑:我用Java实现了这个算法。然而,有一个问题:

如果我不返回赋值,但将其保存在结果中,则递归停止条件将失败(即不再存在)。如何实现另一个停止条件?也许我应该最终还回

这是我的代码:

代码语言:javascript
复制
/**
 * 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);

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-24 19:39:49

此代码检查是否找到解决方案,如果找到,则返回解决方案。否则,继续回溯。这意味着,它返回找到的第一个解决方案。

代码语言:javascript
复制
if result ̸= failure then 
    return result
remove {var = value} from assignment 

您可以这样修改它:

代码语言:javascript
复制
if result ̸= failure then 
    PRINT result // do not return, just save the result
remove {var = value} from assignment 

或者,更好的是,修改这一部分:

代码语言:javascript
复制
if assignment is complete then 
    print assignment
    return assignment // print it and return

关于编辑的问题:

首先,在第一个true中返回if,这样递归就知道它找到了一个解决方案。第二步,有一个错误,可能是:

代码语言:javascript
复制
if(!isPossibleToPlaceIt){
    return(false);
}

应该是

代码语言:javascript
复制
if(isPossibleToPlaceIt){
    return(true);
}

因为如果您的回溯找到了什么,它将返回true,这意味着您不必再检查任何其他内容。

EDIT#2:如果您想继续回溯以找到ALL解决方案,只需用return删除前面的if部分

代码语言:javascript
复制
//if(isPossibleToPlaceIt){
//    return(true);
//}

所以我们会以任何方式继续搜索。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15602295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档