parent
428015be71
commit
766e3168d0
|
@ -3,8 +3,8 @@
|
|||
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" || exit ; pwd -P )
|
||||
cd "$parent_path" || exit
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: $0 <source file>"
|
||||
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
|
||||
echo "Usage: $0 <source file> [debug|memcheck]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -13,6 +13,16 @@ if [ ! -f "$1" ]; then
|
|||
exit 1
|
||||
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_basename=$(basename "$1")
|
||||
|
||||
|
@ -30,4 +40,30 @@ if [ $? -ne 0 ]; then
|
|||
exit 1
|
||||
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%.*}"
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
| [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 |
|
||||
| [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)
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
Binary file not shown.
Loading…
Reference in New Issue