[AED] Stuff

Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
This commit is contained in:
Tiago Garcia 2024-02-05 20:31:16 +00:00
parent ba73d322c3
commit d402f1d7ee
Signed by: TiagoRG
GPG Key ID: DFCD48E3F420DB42
11 changed files with 631 additions and 2 deletions

View File

@ -3,8 +3,8 @@
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P ) parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
cd "$parent_path" || exit cd "$parent_path" || exit
if [ $# -ne 1 ]; then if [ $# -lt 1 ] || [ $# -gt 2 ]; then
echo "Usage: $0 <source file>" echo "Usage: $0 <source file> [debug|memcheck]"
exit 1 exit 1
fi fi
@ -13,6 +13,16 @@ if [ ! -f "$1" ]; then
exit 1 exit 1
fi fi
if [ "${1: -2}" != ".c" ]; then
echo "File $1 is not a C source file"
exit 1
fi
if [ ! -x "$(command -v gcc)" ]; then
echo "gcc is not installed"
exit 1
fi
out_dirname=$(dirname "$1") out_dirname=$(dirname "$1")
out_basename=$(basename "$1") out_basename=$(basename "$1")
@ -30,4 +40,30 @@ if [ $? -ne 0 ]; then
exit 1 exit 1
fi fi
if [ ! -f "out/$out_dirname/${out_basename%.*}" ]; then
echo "Compilation failed"
exit 1
fi
if [ $# -eq 2 ]; then
if [ "$2" == "debug" ]; then
if [ ! -x "$(command -v gdb)" ]; then
echo "gdb is not installed"
exit 1
fi
gdb "out/$out_dirname/${out_basename%.*}" "out/$out_dirname/${out_basename%.*}.core" -tui
exit 0
elif [ "$2" == "memcheck" ]; then
if [ ! -x "$(command -v valgrind)" ]; then
echo "valgrind is not installed"
exit 1
fi
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes "out/$out_dirname/${out_basename%.*}"
exit 0
else
echo "Usage: $0 <source file> [debug|memcheck]"
exit 1
fi
fi
out/"$out_dirname"/"${out_basename%.*}" out/"$out_dirname"/"${out_basename%.*}"

View File

@ -17,6 +17,8 @@
| [09](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema09) | Dicionários | | [09](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema09) | Dicionários |
| [10](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema10) | Grafos | | [10](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema10) | Grafos |
| [11](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema11) | C++ | | [11](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema11) | C++ |
| [12](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema12) | Procura Exaustiva |
| [13](https://github.com/TiagoRG/uaveiro-leci/tree/master/2ano/1semestre/aed/teoricas/tema13) | Tópicos Avançados |
--- ---
*Pode conter erros, caso encontre algum, crie um* [*ticket*](https://github.com/TiagoRG/uaveiro-leci/issues/new) *Pode conter erros, caso encontre algum, crie um* [*ticket*](https://github.com/TiagoRG/uaveiro-leci/issues/new)

View File

@ -0,0 +1,50 @@
/* TAD que permite obter todos os subconjuntos de um conjunto de n elementos */
/* Ficheiro de implementacao binarycounter.c J. Madeira --- 2010/06/02 */
#include "binarycounter.h" /* ficheiro de interface do TAD */
#include <stdio.h>
#include <stdlib.h>
int* createBinCounter(int size) { return (int*)calloc(size, sizeof(int)); }
void copyBinCounter(int* original, int* copy, int size) {
int i;
for (i = 0; i < size; i++) {
copy[i] = original[i];
}
}
void destroyBinCounter(int** binCounter) {
free(*binCounter);
*binCounter = NULL;
}
void printBinCounter(int* binCounter, int size) {
int i;
for (i = size - 1; i >= 0; i--) {
printf("%d", binCounter[i]);
}
printf("\n");
}
int increaseBinCounter(int* binCounter, int size) {
int i = 0;
while ((i < size) && (binCounter[i] == 1)) {
binCounter[i] = 0;
i++;
}
if (i < size) {
binCounter[i] = 1;
return 1;
}
/* Overflow */
return 0;
}

View File

@ -0,0 +1,20 @@
/* TAD que permite obter todos os subconjuntos de um conjunto de n elementos */
/* Ficheiro de interface binarycounter.h J. Madeira --- 2010/06/02 */
#include <stdio.h>
#include <stdlib.h>
int* createBinCounter(int size);
/* Cria o contador binário com dimensão size, inicializado a zeros */
void copyBinCounter(int* original, int* copy, int size);
/* Copia o contador actual */
void destroyBinCounter(int** binCounter);
/* Destroi o contador */
void printBinCounter(int* binCounter, int size);
/* Imprime o contador */
int increaseBinCounter(int* binCounter, int size);
/* Incrementa o contador */

View File

@ -0,0 +1,158 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "binarycounter.h" /* ficheiro de interface do TAD */
void solutionKnapsack(int, float*, float*, int, float, int*);
int* knapsackSearch(float*, float*, int, float);
int main(void) {
int n;
float capacidade;
float w[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
float v[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 100,
12, 32, 44, 14, 15, 16, 17, 128, 29, 20};
n = sizeof(w) / sizeof(float);
do {
printf("Capacidade da mochila? ");
scanf("%f", &capacidade);
} while (capacidade <= 0.0);
knapsackSearch(w, v, n, capacidade);
return 0;
}
void solutionKnapsack(int solNumber, float* weight, float* value, int n,
float capacity, int* validIndices) {
int i;
int flag = 0;
float w = 0.0;
float v = 0.0;
printf("Knapsack capacity = %f --- Solution number = %d\n", capacity,
solNumber);
printf("Set of items = ");
for (i = 0; i < n; i++) {
if (validIndices[i]) {
if (flag) {
printf(" + ");
} else {
flag = 1;
}
printf("item[%d]", i);
}
}
printf("\n");
flag = 0;
printf("Total weight = ");
for (i = 0; i < n; i++) {
if (validIndices[i]) {
w += weight[i];
if (flag) {
printf(" + ");
} else {
flag = 1;
}
printf("%.2f", weight[i]);
}
}
printf(" = %.2f\n", w);
flag = 0;
printf("Total value = ");
for (i = 0; i < n; i++) {
if (validIndices[i]) {
v += value[i];
if (flag) {
printf(" + ");
} else {
flag = 1;
}
printf("%.2f", value[i]);
}
}
printf(" = %.2f\n", v);
printf("\n");
}
int* knapsackSearch(float* weight, float* value, int n, float capacity) {
/* Gerar todos os sub-conjuntos dos indices do array de items */
/* Aproveitar a representacao binaria para os gerar ! */
/* Verificar, para cada um, o valor da soma dos pesos e dos valores */
int subSetIndex;
float sumWeights;
float sumValues, maxSumValues = 0.0;
int i;
/* O numero de sub-conjuntos e 2^n */
int numSubSets = (int)pow(2.0, n);
/* Nao se testa o (sub-)conjunto vazio */
int* binaryCounter = createBinCounter(n);
int* currentBestSol = createBinCounter(n);
for (subSetIndex = 1; subSetIndex < numSubSets; subSetIndex++) {
sumWeights = 0;
sumValues = 0;
increaseBinCounter(binaryCounter, n);
for (i = 0; i < n; i++) {
if (binaryCounter[i] && ((sumWeights += weight[i]) > capacity)) {
break; /* EficiEncia --- Testar tambem sem este break !! */
}
if (binaryCounter[i]) {
sumValues += value[i];
}
}
if (sumValues > maxSumValues) {
maxSumValues = sumValues;
copyBinCounter(binaryCounter, currentBestSol, n);
/* Listar as sucessivas melhores solucoes */
solutionKnapsack(subSetIndex, weight, value, n, capacity, binaryCounter);
}
/* Poderia listar tambem eventuais solucoes alternativas !! */
}
destroyBinCounter(&binaryCounter);
return currentBestSol;
}

View File

@ -0,0 +1,138 @@
/* A magic square is a n x n matrix, whose elements are a permutation of the
integers from 1 to n x n, which satisfies the following:
The sum of the n elements in each row is equal to the sum of the n elements
in each colummn, and is also equal to the sum of the n elements of the two
diagonals.
J. Madeira --- 2010/06/02
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "permutation.h"
int isMagicSquare(int*, int);
void printMagicSquare(int*, int);
void magicSquaresSearch(int);
int main(void) {
int n = 9;
magicSquaresSearch(n);
return 0;
}
int isMagicSquare(int* a, int size) {
int i, j;
int sum;
int n = (int)sqrt(size);
int* sumRow = (int*)calloc(n, sizeof(int));
int* sumColumn = (int*)calloc(n, sizeof(int));
int* sumDiag = (int*)calloc(2, sizeof(int));
/* Adding the elements */
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
sumRow[i] += a[j + i * n];
sumColumn[j] += a[j + i * n];
if (i == j) {
/* Main diagonal */
sumDiag[0] += a[j + i * n];
}
if ((i + j) == (n - 1)) {
/* The other diagonal */
sumDiag[1] += a[j + i * n];
}
}
}
/* Checking the diagonals */
if (sumDiag[0] != sumDiag[1]) {
free(sumRow);
free(sumColumn);
free(sumDiag);
return 0;
}
sum = sumDiag[0];
/* Checking the rows */
for (i = 0; i < n; i++) {
if (sumRow[i] != sum) {
free(sumRow);
free(sumColumn);
free(sumDiag);
return 0;
}
}
/* Checking the columns */
for (i = 0; i < n; i++) {
if (sumColumn[i] != sum) {
free(sumRow);
free(sumColumn);
free(sumDiag);
return 0;
}
}
free(sumRow);
free(sumColumn);
free(sumDiag);
return sum;
}
void printMagicSquare(int* a, int size) {
int i, j;
int n = (int)sqrt(size);
printf("\n");
for (i = 0, j = 0; i < size; i++) {
printf("%3d", a[i]);
j++;
if (j == n) {
printf("\n");
j = 0;
}
}
printf("\n");
}
void magicSquaresSearch(int size) {
/* Gerar todas as permutacoes dos elementos do array */
/* Verificar, para cada uma, se se trata de um quadrado magico */
int sum;
int permutationIndex = 1;
int* p;
p = createFirstPermutation(size);
do {
if ((sum = isMagicSquare(p, size))) {
printf(" *** Permutation %d is a magic square of sum %d :\n\n",
permutationIndex, sum);
printMagicSquare(p, size);
}
permutationIndex++;
} while (nextPermutation(p, size));
destroyPermutation(&p);
}

View File

@ -0,0 +1,90 @@
/* TAD que permite obter todas as permutacoes de um conjunto de n elementos */
/* Ficheiro de implementacao permutation.c J. Madeira --- 2010/06/02 */
#include "permutation.h" /* ficheiro de interface do TAD */
#include <stdio.h>
#include <stdlib.h>
static void swapElements(int*, int, int);
int* createFirstPermutation(int n) {
int i;
int* p = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; i++) {
p[i] = i + 1;
}
return p;
}
void copyPermutation(int* original, int* copy, int n) {
int i;
for (i = 0; i < n; i++) {
copy[i] = original[i];
}
}
void destroyPermutation(int** p) {
free(*p);
*p = NULL;
}
void printPermutation(int* p, int n) {
int i;
for (i = 0; i < n; i++) {
printf("%d ", p[i]);
}
printf("\n");
}
int nextPermutation(int* v, int n) {
/* Adapted from
* http://compprog.wordpress.com/2007/10/08/generating-permutations-2/ */
int i, j, k;
/* Find the largest i */
i = n - 2;
while ((i >= 0) && (v[i] > v[i + 1])) {
--i;
}
/* If i is smaller than 0, then there are no more permutations. */
if (i < 0)
{
return 0;
}
/* Find the largest element after vi but not larger than vi */
k = n - 1;
while (v[i] > v[k]) {
--k;
}
swapElements(v, i, k);
/* Swap the last n - i elements. */
k = 0;
for (j = i + 1; j < (n + i) / 2 + 1; ++j, ++k) {
swapElements(v, j, n - k - 1);
}
return 1;
}
/* funcao interna que troca dois elementos do array */
static void swapElements(int* p, int i, int j) {
int aux = p[i];
p[i] = p[j];
p[j] = aux;
}

View File

@ -0,0 +1,21 @@
/* TAD que permite obter todas as permutacoes de um conjunto de n elementos */
/* Ficheiro de interface permutation.h J. Madeira --- 2010/06/02 */
#include <stdio.h>
#include <stdlib.h>
int* createFirstPermutation(int n);
/* Cria o array de permutacoes com dimensao n, sendo a primeira permutacao
* 123456...n */
void copyPermutation(int* original, int* copy, int n);
/* Copia a permutacao actual */
void destroyPermutation(int** p);
/* Destroi o array de permutacoes */
void printPermutation(int* p, int n);
/* Imprime a permutacao actual */
int nextPermutation(int* v, int n);
/* Cria a permutacao seguinte */

View File

@ -0,0 +1,114 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "binarycounter.h" /* ficheiro de interface do TAD */
void solutionFound(int, int*, int, int*);
void subsetSumSearch(int*, int, int);
int main(void) {
int n, soma;
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
n = sizeof(array) / sizeof(int);
printf("Soma? ");
scanf("%d", &soma);
subsetSumSearch(array, n, soma);
return 0;
}
void solutionFound(int sum, int* a, int size, int* validIndices) {
int i;
int flag = 0;
int s = 0;
printf("%d = ", sum);
for (i = 0; i < size; i++) {
if (validIndices[i]) {
s += a[i];
if (flag) {
printf(" + ");
} else {
flag = 1;
}
printf("%d", a[i]);
}
}
printf("\n");
flag = 0;
printf("%d = ", sum);
for (i = 0; i < size; i++) {
if (validIndices[i]) {
if (flag) {
printf(" + ");
} else {
flag = 1;
}
printf("a[%d]", i);
}
}
printf("\n");
if (s != sum) {
printf("ERRO !!!\n");
}
printf("\n");
}
void subsetSumSearch(int* a, int size, int sum) {
// Gerar todos os sub-conjuntos dos indices do array
// Verificar, para cada um, o valor da soma dos elementos
// Aproveitar a representacao binaria para os gerar !
int subSetIndex;
int sumElements;
int i;
// O numero de sub-conjuntos e 2^n
int numSubSets = (int)pow(2.0, size);
// Nao se testa o (sub-)conjunto vazio
int* binaryCounter = createBinCounter(size);
for (subSetIndex = 1; subSetIndex < numSubSets; subSetIndex++) {
sumElements = 0;
increaseBinCounter(binaryCounter, size);
for (i = 0; i < size; i++) {
if (binaryCounter[i] && ((sumElements += a[i]) > sum)) {
break; /* Eficiencia --- Testar tambem sem este break !!*/
}
}
// Listar todas as solucoes encontradas
if (sumElements == sum) {
solutionFound(sum, a, size, binaryCounter);
}
}
destroyBinCounter(&binaryCounter);
}