Commit bc871090 authored by Vytor Calixto's avatar Vytor Calixto 👾

Merge branch 'altura' into develop

 Conflicts:
	libs/jogador.c
	libs/jogador.h
	tests/runTests.sh
parents 906c4423 ba184bf2
......@@ -8,3 +8,5 @@ tests/*.txt
tests/*.png
massif.out*
*.out
!tests/tabuleiros.out
!tests/tabuleiros2.out
......@@ -5,18 +5,134 @@ before_script:
- apt-get update
- apt-get -y install build-essential make autoconf gcc gnuplot
- make
- mv tests/runTests.sh.example tests/runTests.sh
- chmod +x tests/runTests.sh
- chmod +x tests/verifica
- gcc -std=c99 -o tests/test tests/geraMapa.c
test:
h1:
stage: test
script:
- make test
- cd tests
- sed -i -e 's/tams=()/tams=(4 8 16 32 64)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(3 4 6 8 10)/g' runTests.sh
- ./runTests.sh -h "./floodit_h1"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros.txt
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
- tests/tempos.png
- tests/medias.png
- tests/piores.png
tags:
- ubuntu
h2:
stage: test
script:
- cd tests
- sed -i -e 's/tams=()/tams=(4 8 16 32 64)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(3 4 6 8 10)/g' runTests.sh
- ./runTests.sh -h "./floodit_h2"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
- tests/tempos.png
- tests/medias.png
- tests/piores.png
tags:
- ubuntu
h4-min:
stage: test
script:
- cd tests
- sed -i -e 's/tams=()/tams=(4 8 16 32)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(3 4 8 10)/g' runTests.sh
- ./runTests.sh -h "./floodit_h4"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
- tests/tempos.png
- tests/medias.png
- tests/piores.png
tags:
- ubuntu
h4-max:
stage: test
script:
- cd tests
- sed -i -e 's/tams=()/tams=(64 100)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(10)/g' runTests.sh
- sed -i -e 's/N_TESTES=100/N_TESTES=50/g' runTests.sh
- ./runTests.sh -h "./floodit_h4"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
- tests/tempos.png
- tests/medias.png
- tests/piores.png
tags:
- ubuntu
h6-min:
stage: test
script:
- cd tests
- sed -i -e 's/tams=()/tams=(4 8 16 32)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(3 4 8 10)/g' runTests.sh
- ./runTests.sh -h "./floodit_h6"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
- tests/tempos.png
- tests/medias.png
- tests/piores.png
tags:
- ubuntu
h6-max:
stage: test
script:
- cd tests
- sed -i -e 's/tams=()/tams=(64 100)/g' runTests.sh
- sed -i -e 's/cores=()/cores=(10)/g' runTests.sh
- sed -i -e 's/N_TESTES=100/N_TESTES=50/g' runTests.sh
- ./runTests.sh -h "./floodit_h6"
- gnuplot "tempos.plot"
- gnuplot "medias.plot"
- gnuplot "piores.plot"
artifacts:
paths:
- tests/tabuleiros*.txt
- tests/tempos.txt
- tests/medias.txt
- tests/piores.txt
......
CFLAGS = -std=c99 -O2 -W -Wall -g
CFLAGS = -std=c99 -O2 -W -Wall -g
.PHONY: all clean
all: main
test: main
cd tests; \
$(CC) -std=c99 -o test geraMapa.c; \
chmod +x runTests.sh; \
./runTests.sh
main: main.c libs/jogador.o libs/tabuleiro.o libs/grafo.o libs/vertice.o libs/filha.o libs/lista.o libs/no.o
$(CC) $(CFLAGS) -o $@ $^ -lm
......
......@@ -26,6 +26,7 @@ No primeiroNoFilha(Filha f) {
}
No n = f->primeiro;
f->primeiro = getSucessorNo(f->primeiro);
--f->tamanho;
setSucessorNo(n, NULL);
setAntecessorNo(n, NULL);
return n;
......@@ -37,6 +38,7 @@ No ultimoNoFilha(Filha f) {
}
No n = f->ultimo;
f->ultimo = getAntecessorNo(f->ultimo);
--f->tamanho;
setSucessorNo(n, NULL);
setAntecessorNo(n, NULL);
return n;
......@@ -48,7 +50,14 @@ No insereFilha(void *conteudo, Filha f) {
if(!novo) return NULL;
setConteudo(novo, conteudo);
if(f->tamanho == 0) {
f->primeiro = novo;
}
setAntecessorNo(novo, f->ultimo);
setSucessorNo(f->ultimo, novo);
++f->tamanho;
return f->ultimo = novo;
}
......
#include <stdlib.h>
#include "grafo.h"
#include "lista.h"
#include "filha.h"
#include "vertice.h"
#include "tabuleiro.h"
#include <stdio.h>
......@@ -42,6 +43,9 @@ Floodfill(celula, vertice)
*/
void tabuleiroParaGrafo(Tblr t, Grafo g) {
g->x = t->x;
g->y = t->y;
g->cores = t->cores;
//Para cada celula do tabuleiro
for(int i=0; i < t->x; ++i) {
for(int j=0; j < t->y; ++j) {
......@@ -127,6 +131,42 @@ void floodFill(Tblr t, Vertice v, int i, int j){
return;
}
int calculaAltura(Grafo g, Lista raiz) {
int alturaMax = 0;
for(No n = primeiroNoLista(g->vertices); n; n = getSucessorNo(n)) {
Vertice v = (Vertice) getConteudo(n);
v->altura = -1;
}
Filha fila = constroiFilha();
for(No n = primeiroNoLista(raiz); n; n = getSucessorNo(n)) {
Vertice v = (Vertice) getConteudo(n);
v->altura = 0;
insereFilha(v, fila);
}
while(tamanhoFilha(fila) > 0) {
No n = primeiroNoFilha(fila);
if(!n) {
continue;
};
Vertice v = (Vertice) getConteudo(n);
for(No m = primeiroNoLista(v->filhos); m; m = getSucessorNo(m)) {
Vertice filho = (Vertice) getConteudo(m);
if(filho->altura == -1) {
filho->altura = v->altura+1;
if(filho->altura > alturaMax) {
alturaMax = filho->altura;
}
insereFilha(filho, fila);
}
}
free(n);
}
destroiFilha(fila, NULL);
return alturaMax;
}
void destroiGrafo(Grafo g) {
destroiLista(g->vertices, destroiVertice);
free(g);
......@@ -144,10 +184,10 @@ void grafoParaDot(Grafo g, Lista grupo, FILE* fp) {
// Imprime o grafo
for(No n = primeiroNoLista(g->vertices); n; n = getSucessorNo(n)) {
Vertice pai = (Vertice) getConteudo(n);
fprintf(fp, "\t\"%p\" [label=\"cor=%d,peso=%d\"];\n", pai, pai->cor, pai->peso);
fprintf(fp, "\t\"%p\" [label=\"cor=%d\npeso=%d\nbonus=%d\naltura=%d\"];\n", pai, pai->cor, pai->peso, pai->bonus, pai->altura);
for(No m = primeiroNoLista(pai->filhos); m; m = getSucessorNo(m)) {
Vertice filho = (Vertice) getConteudo(m);
fprintf(fp, "\t\"%p\" [label=\"cor=%d,peso=%d\"];\n", filho, filho->cor, filho->peso);
fprintf(fp, "\t\"%p\" [label=\"cor=%d\npeso=%d\nbonus=%d\naltura=%d\"];\n", filho, filho->cor, filho->peso, filho->bonus, filho->altura);
fprintf(fp, "\t\"%p\" -- \"%p\";\n", pai, filho);
}
}
......
......@@ -4,6 +4,7 @@
#include <stdio.h>
struct Grafo {
int x, y, cores;
Lista vertices;
};
......@@ -19,6 +20,8 @@ void tabuleiroParaGrafo(Tblr t, Grafo g);
void floodFill(Tblr t, Vertice v, int i, int j);
int calculaAltura(Grafo g, Lista raiz);
void destroiGrafo(Grafo g);
void grafoParaDot(Grafo g, Lista grupo, FILE* fp);
......
This diff is collapsed.
......@@ -13,7 +13,7 @@ Lista Joga(Grafo g, Lista grupo);
Lista filhosGrupo(Lista grupoPai);
// Retorna uma lista de vértices com as cores e pesos agrupadas a partir de l
Lista agrupaCores(Lista filhos, Grafo g);
Lista agrupaCores(Lista vertices);
int calculaBonus(Vertice v, Lista filhos);
void calculaBonus(Lista grupo, Grafo g, int profundidade);
#endif
......@@ -20,7 +20,13 @@ unsigned int tamanhoLista(Lista l) { return l->tamanho; }
// devolve o primeiro nó da Lista l,
// ou NULL, se l é vazia
No primeiroNoLista(Lista l) { return l->primeiro; }
No primeiroNoLista(Lista l) {
if(!l) return NULL;
if(l->tamanho == 0) {
return NULL;
}
return l->primeiro;
}
//---------------------------------------------------------------------------
// cria uma Lista vazia e a devolve
......
......@@ -15,18 +15,22 @@ No criaNo() {
}
No getSucessorNo(No n) {
if(!n) return NULL;
return n->proximo;
}
void setSucessorNo(No n, No p) {
if(!n) return;
n->proximo = p;
}
No getAntecessorNo(No n) {
if(!n) return NULL;
return n->anterior;
}
void setAntecessorNo(No n, No p) {
if(!n) return;
n->anterior = p;
}
......
......@@ -9,7 +9,9 @@ Vertice criaVertice() {
v->cor = -1;
v->peso = 0;
v->bonus = 0;
v->altura = -1;
v->grupo = false;
v->visitado = false;
v->pais = constroiLista();
v->filhos = constroiLista();
return v;
......
......@@ -6,8 +6,10 @@
struct Vertice {
int cor;
int peso;
int bonus;
unsigned long int bonus;
int altura;
bool grupo;
bool visitado;
Lista pais;
Lista filhos;
};
......
......@@ -17,7 +17,7 @@ int main(int argc, char *argv[]) {
puts("Erro na leitura do tabuleiro");
return -1;
}
// Se colocar UMA e APENAS UMA coisa depois do main
if(argc == 2) {
// Calcula e imprime o número mínimo e máximo de jogadas
......
#!/bin/bash
OPTIND=1
MAIN="../main"
HEUR="./floodit_h6"
while getopts ":m:h:" opt; do
case "$opt" in
m) MAIN=$OPTARG
;;
h) HEUR=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
echo $MAIN
echo $HEUR
# tempo máximo para executar, em milisegundos
tempo_max=10000 #10s
tempo_max=120000 #120s
# tamanhos do tabuleiro
tams=(16 32 64 128)
tams=(64)
# lista de cores
cores=(4 8 10 16)
cores=(10)
#-- Cores do terminal
RED='\033[0;31m'
......@@ -16,7 +35,9 @@ BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # Sem cor
echo -ne "" > tabuleiros.txt
TABULEIROS="tabuleiros_$(basename ${HEUR}).txt"
echo -ne "" > $TABULEIROS
echo -ne "#Tam tabuleiro\t#N cores\t#Tempo médio\n" > tempos.txt
echo -ne "#Tam tabuleiro\t#Tempo médio\n" > medias.txt
echo -ne "#Tam tabuleiro\t#N cores\t#Tempo médio\n" > piores.txt
......@@ -31,19 +52,42 @@ do
echo "Número de cores: ${cor}"
T_soma_cor=0
T_max_cor=0
for j in $(seq 1 $i)
N_TESTES=100
VIT=0
EMP=0
DER=0
for j in $(seq 1 ${N_TESTES})
do
echo -ne "Tabuleiro com ${i} linhas e ${cor} cores: ${i}x${j} (T max: $(($T_max_cor/1000000000))."
printf "%03d" $(($T_max_cor/1000000))
echo -ne ")"\\r
semente=$RANDOM
# echo "Usando semente: ${semente}"
./test $i $j $cor $semente
./test $i $i $cor $semente
T_inicial=$(date +%s%N)
../main < "/tmp/${semente}.in" > /dev/null
eval $MAIN < "/tmp/${semente}.in" > "/tmp/resp${semente}.out"
T_gasto=$(($(date +%s%N) - $T_inicial))
T_soma_cor=$(($T_gasto + $T_soma_cor))
T_soma_total=$(($T_gasto + $T_soma_total))
eval $HEUR < "/tmp/${semente}.in" > "/tmp/heur${semente}.out"
RESP=$(cat "/tmp/resp${semente}.out" | tail -n2 | head -n1)
HRESP=$(cat "/tmp/heur${semente}.out" | tail -n2 | head -n1)
if [ $RESP -gt $HRESP ]; then
echo "${i} ${i} ${cor} ${semente} (${HRESP})" >> ${TABULEIROS}
DER=$(($DER + 1))
fi
if [ $RESP -eq $HRESP ]; then
EMP=$(($EMP + 1))
fi
if [ $RESP -lt $HRESP ]; then
VALIDO=$(cat "/tmp/${semente}.in" "/tmp/resp${semente}.out" | ./verifica)
if [[ $VALIDO -eq 1 ]]; then
echo -ne "${RED}Nossa resposta para ${i} ${i} ${cor} ${semente} não é válida!!!${NC}\n\n"
fi
VIT=$(($VIT + 1))
fi
# tempo em segundos
S=$(($T_gasto/1000000000))
# tempo em milisegundos
......@@ -52,36 +96,37 @@ do
if [ $T_max_cor -lt $T_gasto ]; then
T_max_cor=$T_gasto
fi
if (($M>$tempo_max)); then
echo -e "\n${RED}Tabuleiro ${i} ${j} ${cor} ${semente} levou mais de ${tempo_max} milisegundos: ${S}.${M}s${NC}"
echo "${i} ${j} ${cor} ${semente}" >> tabuleiros.txt
fi
rm "/tmp/${semente}.in"
rm "/tmp/resp${semente}.out"
rm "/tmp/heur${semente}.out"
echo -ne "Tabuleiro ${i}x${i} com ${cor} cores: (${j}/${N_TESTES}) (T max: $(($T_max_cor/1000000000))."
printf "%03d" $(($T_max_cor/1000000%1000))
echo -ne ") (${GREEN}${VIT}${NC}/${BLUE}${EMP}${NC}/${RED}${DER}${NC})"\\r
done
T_medio_cor=$(($T_soma_cor/$i))
T_medio_cor=$(($T_soma_cor/${N_TESTES}))
S_medio_cor=$(($T_medio_cor/1000000000))
M_medio_cor=$(($T_medio_cor/1000000))
echo -ne "\n${CYAN}Tempo médio com ${cor} cores: ${S_medio_cor}."
printf "%03d" ${M_medio_cor}
printf "%03d" $((${M_medio_cor}%1000))
echo -e "s (${T_medio_cor})${NC}\n"
echo -e "${i}\t${cor}\t${M_medio_cor}" >> tempos.txt
echo -e "${i}\t${cor}\t$(($T_max_cor/1000000))" >> piores.txt
done
T_medio_total=$(( $T_soma_total/($i * ${#cores[*]}) ))
T_medio_total=$(( $T_soma_total/(${N_TESTES} * ${#cores[*]}) ))
S_medio_total=$(($T_medio_total/1000000000))
M_medio_total=$(($T_medio_total/1000000))
echo -ne "${BLUE}Tempo médio com tamanho ${i}: ${S_medio_total}."
printf "%03d" ${M_medio_total}
printf "%03d" $((${M_medio_total}%1000))
echo -e "s (${T_medio_total})${NC}\n"
echo -e "${i}\t${M_medio_total}" >> medias.txt
done
fs=$(cat tabuleiros.txt | wc -l)
fs=$(cat "${TABULEIROS}" | wc -l)
if [ ${fs} -gt "1" ]; then
echo -e "${RED}${fs} tabuleiro(s) passou(passaram) do tempo limite de ${tempo_max} milisegundos:${NC}"
cat tabuleiros.txt
exit 1
echo -e "${RED}${fs} tabuleiro(s) perdeu(perderam) para outras heurísticas${NC}"
cat ${TABULEIROS}
else
echo -e "${GREEN}Nenhum tabuleiro passou do tempo limite de ${tempo_max} milisegundos${NC}"
exit 0
echo -e "${GREEN}Nenhum tabuleiro perdeu para as outras heurísticas${NC}"
fi
#!/bin/bash
OPTIND=1
MAIN="../main"
HEUR="./floodit_h6"
while getopts ":m:h:" opt; do
case "$opt" in
m) MAIN=$OPTARG
;;
h) HEUR=$OPTARG
;;
esac
done
shift $((OPTIND-1))
[ "$1" = "--" ] && shift
echo $MAIN
echo $HEUR
# tempo máximo para executar, em milisegundos
tempo_max=120000 #120s
# tamanhos do tabuleiro
tams=()
# lista de cores
cores=()
#-- Cores do terminal
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # Sem cor
TABULEIROS="tabuleiros_$(basename ${HEUR}).txt"
echo -ne "" > $TABULEIROS
echo -ne "#Tam tabuleiro\t#N cores\t#Tempo médio\n" > tempos.txt
echo -ne "#Tam tabuleiro\t#Tempo médio\n" > medias.txt
echo -ne "#Tam tabuleiro\t#N cores\t#Tempo médio\n" > piores.txt
echo "Iniciado testes"
for i in ${tams[*]}
do
echo "Tamanho do tabuleiro: ${i}"
T_soma_total=0
for cor in ${cores[*]}
do
echo "Número de cores: ${cor}"
T_soma_cor=0
T_max_cor=0
N_TESTES=100
VIT=0
EMP=0
DER=0
for j in $(seq 1 ${N_TESTES})
do
semente=$RANDOM
./test $i $i $cor $semente
T_inicial=$(date +%s%N)
eval $MAIN < "/tmp/${semente}.in" > "/tmp/resp${semente}.out"
T_gasto=$(($(date +%s%N) - $T_inicial))
T_soma_cor=$(($T_gasto + $T_soma_cor))
T_soma_total=$(($T_gasto + $T_soma_total))
eval $HEUR < "/tmp/${semente}.in" > "/tmp/heur${semente}.out"
RESP=$(cat "/tmp/resp${semente}.out" | tail -n2 | head -n1)
HRESP=$(cat "/tmp/heur${semente}.out" | tail -n2 | head -n1)
if [ $RESP -gt $HRESP ]; then
echo "${i} ${i} ${cor} ${semente} (${HRESP})" >> ${TABULEIROS}
DER=$(($DER + 1))
fi
if [ $RESP -eq $HRESP ]; then
EMP=$(($EMP + 1))
fi
if [ $RESP -lt $HRESP ]; then
VALIDO=$(cat "/tmp/${semente}.in" "/tmp/resp${semente}.out" | ./verifica)
if [[ $VALIDO -eq 1 ]]; then
echo -ne "${RED}Nossa resposta para ${i} ${i} ${cor} ${semente} não é válida!!!${NC}\n\n"
fi
VIT=$(($VIT + 1))
fi
# tempo em segundos
S=$(($T_gasto/1000000000))
# tempo em milisegundos
M=$(($T_gasto/1000000))
# tempo máximo por cor
if [ $T_max_cor -lt $T_gasto ]; then
T_max_cor=$T_gasto
fi
rm "/tmp/${semente}.in"
rm "/tmp/resp${semente}.out"
rm "/tmp/heur${semente}.out"
echo -ne "Tabuleiro ${i}x${i} com ${cor} cores: (${j}/${N_TESTES}) (T max: $(($T_max_cor/1000000000))."
printf "%03d" $(($T_max_cor/1000000%1000))
echo -ne ") (${GREEN}${VIT}${NC}/${BLUE}${EMP}${NC}/${RED}${DER}${NC})"\\r
done
T_medio_cor=$(($T_soma_cor/${N_TESTES}))
S_medio_cor=$(($T_medio_cor/1000000000))
M_medio_cor=$(($T_medio_cor/1000000))
echo -ne "\n${CYAN}Tempo médio com ${cor} cores: ${S_medio_cor}."
printf "%03d" $((${M_medio_cor}%1000))
echo -e "s (${T_medio_cor})${NC}\n"
echo -e "${i}\t${cor}\t${M_medio_cor}" >> tempos.txt
echo -e "${i}\t${cor}\t$(($T_max_cor/1000000))" >> piores.txt
done
T_medio_total=$(( $T_soma_total/(${N_TESTES} * ${#cores[*]}) ))
S_medio_total=$(($T_medio_total/1000000000))
M_medio_total=$(($T_medio_total/1000000))
echo -ne "${BLUE}Tempo médio com tamanho ${i}: ${S_medio_total}."
printf "%03d" $((${M_medio_total}%1000))
echo -e "s (${T_medio_total})${NC}\n"
echo -e "${i}\t${M_medio_total}" >> medias.txt
done