#include #include #include #include #include #include #define DEBUG #define VAR(t) (( (t)-(t)%2 ) / 2 ) #define NEG(t) ((t)%2==0 ? ' ' : '~') #define TERMO(v,d) (2*(v)+(d)) int num_var; /* Numero de variaveis no problema */ int num_claus; /* Numero de clausulas no problema */ int num_term; /* Numero de termos por clausula */ int **clausulas; /* Vetor apontando para cada uma das clausulas */ /* 2*x indica variavel, +1 indica negado */ int *aparece; /* Indica quantas vezes cada termo aparece */ int **satisfaz; /* Indica quais clausulas sao satisfeitas por cada termo */ int *next; int *solucao; /* Solucao ateh o momento, valor de cada variavel */ int *feitas; /* Indica quantas vezes cada clausula foi satisfeita */ int *niveis; /* Indica ateh qual clausula vai a capacidade do nivel */ void cria_clausula( int n, int t, int *termos) { int i, j, aux; for( i=0; i= 500 ) ++termos[i]; /* variavel aparece negada */ } for( i=0; i termos[j] ) { aux = termos[i]; termos[i] = termos[j]; termos[j] = aux; } } int calcula( void) { int nivel_atual, i, j; int termo; int *ptr; int quantos; nivel_atual = 0; while( nivel_atual >= 0 && nivel_atual < num_var ) { #ifdef DEBUG printf("\n!!!!!!!! Solucao\n"); for( i=0; i< num_var; ++i) printf("(%d)=%d ",i,solucao[i]); printf("\nFeitas\n"); for( i=0; i< num_claus; ++i) printf("(%d)=%d ",i,feitas[i]); printf("\n\n"); printf("!!!! inicio do loop !!!! Nivel_atual %d,", nivel_atual); printf("solucao atual neste nivel %d\n", solucao[nivel_atual] ); #endif if( solucao[nivel_atual] == 1 ) { /*** Backtrack ***/ #ifdef DEBUG printf("Backtrack pois esgotou tentativas no nivel\n"); #endif --nivel_atual; if( nivel_atual == -1 ) continue; /* sem solucao */ termo = TERMO( nivel_atual, solucao[nivel_atual]); ptr = satisfaz[termo]; quantos = aparece[termo]; for( i=0; i \n"); exit(1); } num_var = atoi( argv[1] ); if( num_var < 3 || num_var > 250 ) { printf("Numero invalido de variaveis: %d\n", num_var); exit(1); } opcao = argv[2][0]; if( opcao!='p' && opcao != 'n' ) { printf("Opcao deve ser 'p' ou 'n'\n"); exit(1); } /*** Define tamanho do problema ***/ num_term = 3; num_claus = (int) (4.25 * num_var); /*** Cria cada uma das clausulas ***/ clausulas = calloc( num_claus, sizeof(int *) ); if( clausulas == NULL ) { printf("Erro na alocacao de memoria \n"); exit(1); } for( i=0; i\n",i); exit(1); } /*** Ordena as clausulas em funcao do ultimo termo ***/ for( i=0; i clausulas[j][num_term-1] ) { aux = clausulas[i]; clausulas[i] = clausulas[j]; clausulas[j] = aux; } /*** Determina quantas vezes cada termo aparece ***/ aparece = calloc( num_var * 2, sizeof(int) ); if( aparece == NULL ) { printf("Erro na alocacao de memoria \n"); exit(1); } for( i=0; i\n"); exit(1); } next = calloc( num_var * 2, sizeof(int) ); if( next == NULL ) { printf("Erro na alocacao de memoria \n"); exit(1); } for( i=0; i < 2*num_var; ++i) { satisfaz[i] = calloc( aparece[i], sizeof(int) ); next[i] = 0; } for( i=0; i<2*num_var; ++i) if( satisfaz[i] == NULL && aparece[i] != 0 ) { printf("Erro na alocacao de memoria \n",i); exit(1); } /*** Completa a tabela satisfaz ***/ for( i=0; i\n"); exit(1); } for( i=0; i\n"); exit(1); } /*** Aloca e inicializa vetor de niveis ***/ niveis = calloc( num_var, sizeof(int) ); if( niveis == NULL ) { printf("Erro na alocacao de memoria \n"); exit(1); } for( i=0; i