时间测量使用时钟()在n皇后回溯

时间:2017-10-09 13:53:26

标签: c time n-queens recursive-backtracking

在打印出它找到的第一个解决方案后,我想打印下面找到第一个解决方案的时间。

输入N:4

1 3 0 2

时间:0.001秒

然而,当我输入30作为输入时,它会花费异常长时间,就好像它处于无限循环中一样。此外,当我输入31作为输入时,我花了将近15秒,但打印出的时间仅为0.002秒。我想我应该改变时钟函数的位置,但由于代码在打印出第一个解决方案后退出程序,因此我决定将它们放在哪里变得非常棘手。

非常感谢任何帮助。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int put_queens(int column, int size, int* array);
int check_safe(int column, int row, int* array);
void print_sol(int size, int* array);

int main (void){
    int size, flag;
    int* array;
    clock_t t;
    printf("Input N: ");
    scanf("%d",&size);

    array = (int*) calloc(size, sizeof(int));

    t = clock();
    flag = put_queens(0,size, array);
    if(flag){
        printf("No solution");
        t = clock() - t;
        printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
        free(array);
    }

    return 0;
}

int put_queens(int column, int size, int* array){
    clock_t t;
    t = clock();
    int row, flag;
    for( row = 0; row < size; row++ ){
        if( check_safe(column, row, array) ){
            array[column] = row;
            if(column == size - 1){
                print_sol(size, array);
                t = clock()-t;
                printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
                free(array);
                exit (0);
            }
            else{
                put_queens(column + 1, size, array);
            }
        }
    }
    if(row == size && column == size - 1){
        flag = 1;
    }
    return flag;
}

int check_safe(int column, int row, int* array){
    int index;
    for(index = 0; index < column; index++){
        if((array[index] == row ) || (abs(array[index]-row)==abs(column - index))){
            return 0;
        }
    }
    return 1;
}

void print_sol(int size, int* array){
    int column;
    for(column = 0; column < size; column++ ){
        printf("%3d", array[column]);
    }
}

1 个答案:

答案 0 :(得分:0)

请参阅以下两个条件和你的for循环:

for( row = 0; row < size; row++ ){
    if( check_safe(column, row, array) ){
        array[column] = row;
        if(column == size - 1){
            print_sol(size, array);
            t = clock()-t;
            printf("\nTime: %.3fsec",((float)t)/CLOCKS_PER_SEC);
            free(array);
            exit (0);
        }
        else{
            put_queens(column + 1, size, array);
        }
    }
}

这里在上面,当第一个if条件满足时,它将检查第二个条件if(column == size -1)。如果第一个条件满足但'column'值已经大于'size',则第二个条件将永远不会满足(例如column = 31和size = 30),递归将继续进行,这是长期采用的原因之一在某些情况下的时间。将第二个if条件更正为if(列&gt;大小)。同样来自for循环,你正在递归地调用函数,对于满足第二个if条件和递归几乎无法控制也变得更加关键,因为对于每个递归它有一个for循环而for循环再次递归地调用该方法。想象一下这里发生了什么。由于存在递归调用的限制,操作系统会突然终止该进程,因为您没有看到该程序的任何输出。关于你的时钟,请用一些打印声明来检查它是否正确得到时间。更改逻辑,以便递归不应该永远持续。再见,你想在这里实现什么?