MAC5711 Análise de Algoritmos
I make mistakes. I always have, and I probably always will. But I like
to think that I learn something, every time I go astray.
D.E. Knuth
"Literate Programming"
Para irmos aquecendo os motores. Esta primeira tarefa é um exercício simples, tipicamente dado aos alunos do primeiro ano de cursos de Ciência da Computação.
xl + xl+1 +...+ xrseja máxima. Por exemplo, dada a seqüência
Para tornar o desafio de fazer seu programa mais interessante, será fornecido a você um programa executável que, além de resolver o problema acima, imprime o tempo gasto (em segundos).
Você pode, em C, cronometrar o tempo de execução do seu programa da seguinte maneira:
clock_t t0, tf; double tempo_gasto; ... /* Leitura de dados */ ... t0 = clock(); ... /* ache um segmento de soma máxima */ ... tf = clock(); tempo_gasto = ( (double) (tf - t0) ) / CLOCKS_PER_SEC; ... printf("Tempo gasto: %lf s\n", tempo_gasto);
O tipo clock_t
e a constante CLOCKS_PER_SEC
já estão definidos na biblioteca time.h
.
Desse modo, você pode comparar o desempenho do seu programa com o que vamos fornecer. A eficiência do seu programa NÃO será levada em conta na nota. Apesar disto, tente fazer algo além do trivial.
O seu programa deve ler a seqüência de números a partir de um arquivo cujo nome é fornecido pelo usuário através da linha de comando. O arquivo é binário, e na primeira posição contém o número de elementos da seqüência e depois a seqüência propriamente dita:
A propósito, devido as diferentes arquiteturas de memória das máquinas.
Para gerar os dados você pode usar o programa gera.c, mas sugiro que antes você teste seu programa com arquivos textos de seqüências pequenas de números.
O programa deve aceitar valores de n entre 1 e 10000000 (10 milhões ...
arquivos de 40Mb ... é pouco ? é muito ?).
Para a leitura de arquivos binários você pode usar as funções
fopen e
fread disponíveis na biblioteca de funções do C (veja a utilização
dessas funções no programa gera.c
e no exemplo abaixo).
Como saída, seu programa deve imprimir:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <limits.h> /*#define MAX 10000000 */ int main(int argc, char *argv[]) { FILE *fp; /* int sequencia[MAX], n=0; É melhor fazer como está abaixo */ int *sequencbia; int n; int l, r, soma; clock_t start, end; double elapsed; if (argc < 2) { fprintf(stdout," \n%s: este programa recebe uma" " sequencia de n numeros" " inteiros\n" " x[1], x[2], x[3], ... , x[n-1], x[n],\n" " e devolve l e r tais que a soma\n" " x[l] + x[l+1] + ... + x[r-1] + x[r]\n" " seja maxima.\n\n" " Uso: segmax.\n\n" " O arquivo deve ser binario e ter formato\n" " n x[1] x[2] ... x[n-1] x[n]\n" " onde n >= 1.\n\n", argv[0]); return -1; } if (!(fp = fopen(argv[1],"rb"))) { fprintf(stderr,"%s: erro na abertura do" " arquivo %s.\n", argv[0], argv[1]); return -2; } /* leitura do tamanho da sequencia */ if (!(fread(&n, sizeof(int), 1, fp))) { fprintf(stderr,"%s: erro na leitura do" " arquivo %s.\n", argv[0], argv[1]); return -3; } if (n <= 0) { fprintf(stderr,"%s: valor de n nao permitido.\n", argv[0]); return -4; } /* aloca um vetor de n posicoes */ if ((sequencia = (int *) malloc(n * sizeof(int))) == NULL) { fprintf(stderr,"%s: espaco insuficiente.\n", argv[0]); return -5; } /* leitura de sequencia */ if (fread(sequencia, sizeof(int), n, fp) < n) { fprintf(stderr,"%s: arquivo %s nao esta" " completo.\n", argv[0], argv[1]); return -6; } fclose(fp); start = clock(); /* ENCONTRAR O SEGMENTO DE SOMA MAXIMA */ [...] end = clock(); elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; fprintf(stdout," O arquivo de entrada \"%s\" contem %d numeros.\n" " Foi encontrada uma subsequencia de soma maxima com\n" " Inicio: %d\n" " Final: %d\n" " Soma: %d\n" " Tempo: %f s\n\n", argv[1], n, l, r, soma, elapsed); return 0; }
jaca:/home/mac/coelho> segmax seq1.dat O arquivo de entrada "seq1.dat" contem 100 numeros. Foi encontrada uma subsequencia de soma maxima com Inicio: 30 Final: 56 Soma: 3916 Tempo: 0.000000 se com o arquivo seq2.dat pode ser algo como
kama:/home/mac/coelho> segmax seq2.dat O arquivo de entrada "seq2.dat" contem 10000000 numeros. Foi encontrada uma subsequencia de soma maxima com Inicio: 7050879 Final: 8425274 Soma: 1717434 Tempo: 0.100000 s (nao incluido tempo com leitura)Teste seu programa com os arquivos de dados seq1.dat e seq2.dat. Mas antes teste com arquivos menores (arquivos textos de preferência).
segmax
resolve o problema acima. Compare os resultados obtidos com o resultado
do segmax
.
Plágio é um comportamento que contraria as regras de nossa disciplina e o
Código
de Ética da USP. Destacamos o seguinte artigo:
Artigo 23 - É vedado aos membros do corpo discente e demais alunos da Universidade:
[...]
II. lançar mão de meios e artifícios que possam fraudar a avaliação do
desempenho, seu ou de outrem, em atividades acadêmicas, culturais, artísticas,
desportivas e sociais, no âmbito da Universidade, e acobertar a eventual
utilização desses meios.