【问题标题】:How to find all possible solutions in backtracking如何在回溯中找到所有可能的解决方案
【发布时间】:2016-01-21 11:04:01
【问题描述】:

我正在尝试实现回溯算法(它应该遍历给定数量的人并检查所有可能的配对,每对都有一定的分数,目标是找出“最大”分数出现的次数; 所以我需要检查所有可能的解决方案)。

问题是我无法理解如何让我的函数真正“回溯”......当它找到解决方案时,它会一直回到根目录。我如何回到可以尝试不同路径的点,并让它走这条路,而不是再次走同样的路?

这是我的代码,虽然我知道我的想法可能是错误的......只是我试图以多种方式思考它,而我完全迷失在这里。 感谢您的帮助!

void allPairs (int x, int pref[], bool teamed[], int* max, int score, int numWorkers) {
    for (int i=1; i < numWorkers; i++) {
        int count = 0;
        pairTwo(x, i, pref, teamed, max, score, numWorkers, &count);
    }
}

int pairTwo (int x, int y, int pref[], bool teamed[], int* max, int score, int numWorkers, int* howMany) {
        if (x >= numWorkers) {
            arrToZero(teamed, numWorkers);
            return score;
        }
        else if (x==y) {
            if(y < numWorkers-1) {
                y = findUnteamed(teamed, y+1, numWorkers);
            }
            else {
                arrToZero(teamed, numWorkers);
                return score;
            }
        }

        int pairScore = sumPair(pref, x, y, teamed, numWorkers);
        x = findUnteamed(teamed, x, numWorkers);
        y = findUnteamed(teamed, 0, numWorkers);
        int temp = pairTwo(x, y, pref, teamed, max, score + pairScore, numWorkers, howMany);
        teamed[x] = 0; // here I tried to "erase" the last move but it's useless
        teamed[y] = 0;
        if (temp >= *max) {
            max = &temp;
            *howMany++;
            printf("There are %d optimal pairings:, with a total score of: %d\n", *howMany, *max);
            return *max;
        }
        else {
        return -1;
        }
}

【问题讨论】:

  • 您对 pairTwo 的递归调用必须在循环中检查所有可能性,xy 必须遍历所有 unteamed,而不仅仅是第一个找到了。

标签: c backtracking


【解决方案1】:

如果您不遵循它所遵循的确切算法,回溯会令人困惑。回溯算法中方法的非官方名称已被广泛接受,有助于更轻松地调试代码。

标准递归回溯算法由solve()、getSuccessors()、isGoal() 和isValid() 组成。使用一个被操纵以求解的整数数组的示例,solve() 函数如下所示:

int[] solve(int[] list) {
    if ( isGoal( list ) ) {
        return list;
    }
    int[][] successors = getSuccessors( list )
    for (int[] successor : successors) {
        if ( isValid( successor ) ) {
            if ( sizeof( solve( successor ) ) != 0 ) {
                return successor;
            }
        }
    }
    return [];
}

getSuccessors() 返回当前数组的深层副本列表,这些副本已被修改以探索新的解决方案,isGoal() 检查是否已找到解决方案,isValid() 检查如果有可能找到沿着当前路径继续前进的目标。这三个函数专门针对您要解决的问题。

另外,solve() 的迭代版本存在于其中初始状态被放置到空堆栈中,尽管您首先需要构建一个堆栈。查看有关迭代回溯的 Wikipedia 页面,了解该求解方法的工作原理。

【讨论】:

    猜你喜欢
    • 2020-04-06
    • 1970-01-01
    • 2018-11-12
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多