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.