parent
428015be71
commit
766e3168d0
|
@ -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%.*}"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
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