回溯功能

Function for Backtracking

本文关键字:功能 回溯      更新时间:2023-10-16

我正在尝试为单一链接的列表骑士的旅行问题创建回溯。我必须将链接列表作为堆栈实现,并能够弹出上一个动作,并使用它来跟踪/尝试另一个动作。我知道该程序有效,直到我必须开始回溯。我也知道列表推送/流行功能正常工作。我的回溯逻辑有问题。它跳过了一些值,或者更确切地说尝试它们,然后如果它们不起作用,则将其删除,但是即使我正在减少它,移动号码也会不断上升。我缺少逻辑上有明显的错误吗?

#include "stdafx.h"
#include "Header.h"
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <iomanip>

llist list;
Move m;
int board[8][8];
int cx[] = {-2,-1, 1, 2, 2, 1, -2, -1 };
int cy[] = { 1, 2, 2, 1, -1, -2, -1, -2 };
int movenum = 1;
int backtrack = 0;
Move first;

/*Check to see if move is within the constraints of the board*/
bool constraints(int k, int b) {
    if ((k < 0) || (b < 0) || (k > 7) || (b > 7) || (board[k][b] != -1)) {
        return true;
    }
    else {
        return false;
    }
}
/* Initialization of 8x8 board, fill the array with -1 */
void initboard() {
    for (int x = 0; x < 8; x++) {
        for (int y = 0; y < 8; y++) {
            board[x][y] = -1;
        }
    }
}

/* Output the current board array */
void printboard(int arr[8][8]) {
    for (int x = 0; x < 8; x++) {
        for (int y = 0; y < 8; y++) {
            cout << std::setw(2) << arr[x][y] << " ";
        }
        cout << endl;
    }
}
void updateboard(int k, int b) {
    board[k][b] = movenum;
    movenum++;
}
void calcmove(int x, int y, int i) {
    for (i; i < 9; i++) {
        int a0 = x + cx[i];
        int a1 = y + cy[i];
        if (constraints(a0, a1) == false) {
            updateboard(a0, a1);
            m.x = a0;
            m.y = a1;
            m.index = i;
            list.push(m);
            printboard(board);
            backtrack = 0;
            cout << "move is" << movenum << endl;
            if (movenum < 64) {
                return calcmove(m.x, m.y, 0);
            }
            else { return; }
        }
    }

    board[m.x][m.y] = -1;
    m = list.pop();
    m.index = m.index + 1;
    if (backtrack > 0) {
        movenum--;
        board[m.x][m.y] = -1;
    }
    cout << "move is" << movenum << "after pop" << endl;
    backtrack +=1;
    printboard(board);
    if (movenum < 64) {
        return calcmove(m.y, m.y, m.index);
    }
    else { return; }
}

int main()
{
    int m1 = 1;
    int m2 = 2; //random 
    first.x = m1;
    first.y = m2;
    first.index = 0;
    list.push(first); //push first node on to stack
    initboard();
    updateboard(m1, m2); //update board
    calcmove(first.x, first.y, 0);
    printboard(board);
}

回溯发生在CalcMove功能中,如果它不在板上,则已经采取了一个空间,并且已经检查了可用的每一步。

此SOL的最坏情况是O(N^(N^2))。在最坏的情况下,将检查8^64组合。

由于如此高的复杂性代码需要大量时间运行,并且很难在如此复杂的情况下找到错误。

for-loop中您的calcmove函数中存在的一个错误,该函数正在运行 9 times而不是 8 times。
第二个是

中的 91
if (movenum < 64) {
        return calcmove(m.y, m.y, m.index);
    }

其中m.y作为第一个参数而不是m.x

传递

为了更好地理解回溯这是类似的问题。
这里。