add files
This commit is contained in:
BIN
T1/suma.asan
BIN
T1/suma.asan
Binary file not shown.
Binary file not shown.
BIN
T1/suma.bin
BIN
T1/suma.bin
Binary file not shown.
95
T1/suma.c
95
T1/suma.c
@@ -1,18 +1,19 @@
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "suma.h"
|
||||
|
||||
// Defina aca las estructuras que necesite
|
||||
|
||||
enum { NTHREADS = 8 };
|
||||
|
||||
typedef struct {
|
||||
int *a;
|
||||
long long *prefix;
|
||||
int n;
|
||||
Set start;
|
||||
Set end;
|
||||
Set found;
|
||||
} BuscarArgs;
|
||||
Set inicio;
|
||||
Set fin;
|
||||
Set encontrado;
|
||||
} ArgsBuscar;
|
||||
|
||||
static Set total_combinaciones(int n) {
|
||||
if (n >= (int)(sizeof(Set) * CHAR_BIT))
|
||||
@@ -20,89 +21,105 @@ static Set total_combinaciones(int n) {
|
||||
return ((Set)1 << n) - 1;
|
||||
}
|
||||
|
||||
static long long suma_inicial(int a[], int n, Set k) {
|
||||
long long sum = 0;
|
||||
static long long suma_subconjunto(int a[], int n, Set k) {
|
||||
long long suma = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (k & ((Set)1 << i))
|
||||
sum += a[i];
|
||||
suma += a[i];
|
||||
}
|
||||
|
||||
return sum;
|
||||
return suma;
|
||||
}
|
||||
|
||||
static Set buscar_rango(int a[], long long prefix[], int n, Set start, Set end) {
|
||||
if (start == 0 || start > end)
|
||||
static int contar_unos_finales(Set k) {
|
||||
int cant = 0;
|
||||
|
||||
while ((k & 1) != 0) {
|
||||
cant++;
|
||||
k >>= 1;
|
||||
}
|
||||
|
||||
return cant;
|
||||
}
|
||||
|
||||
static Set buscar_rango(int a[], long long prefix[], int n, Set inicio, Set fin) {
|
||||
if (inicio == 0 || inicio > fin)
|
||||
return 0;
|
||||
|
||||
Set k = start;
|
||||
long long sum = suma_inicial(a, n, k);
|
||||
Set k = inicio;
|
||||
long long suma = suma_subconjunto(a, n, k);
|
||||
|
||||
while (1) {
|
||||
if (sum == 0)
|
||||
if (suma == 0)
|
||||
return k;
|
||||
|
||||
if (k == end)
|
||||
if (k == fin)
|
||||
break;
|
||||
|
||||
unsigned int shift = (unsigned int)__builtin_ctzll(~k);
|
||||
sum -= prefix[shift];
|
||||
sum += a[shift];
|
||||
int cambios = contar_unos_finales(k);
|
||||
suma -= prefix[cambios];
|
||||
suma += a[cambios];
|
||||
k++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *buscar_thread(void *ptr) {
|
||||
BuscarArgs *args = ptr;
|
||||
args->found = buscar_rango(args->a, args->prefix, args->n, args->start,
|
||||
args->end);
|
||||
// Defina aca la funcion que ejecutaran los threads
|
||||
|
||||
static void *thread_buscar(void *ptr) {
|
||||
ArgsBuscar *args = ptr;
|
||||
|
||||
args->encontrado = buscar_rango(args->a, args->prefix, args->n, args->inicio,
|
||||
args->fin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Reprograme aca la funcion buscar
|
||||
Set buscar(int a[], int n) {
|
||||
Set comb = total_combinaciones(n);
|
||||
Set base = comb / NTHREADS;
|
||||
Set extra = comb % NTHREADS;
|
||||
Set next = 1;
|
||||
Set siguiente = 1;
|
||||
pthread_t tids[NTHREADS];
|
||||
BuscarArgs args[NTHREADS];
|
||||
ArgsBuscar args[NTHREADS];
|
||||
long long prefix[CHAR_BIT * sizeof(Set) + 1];
|
||||
int created = 0;
|
||||
int creados = 0;
|
||||
|
||||
prefix[0] = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
prefix[i + 1] = prefix[i] + a[i];
|
||||
|
||||
for (int t = 0; t < NTHREADS; t++) {
|
||||
Set len = base + (Set)(t < (int)extra);
|
||||
Set largo = base + (Set)(t < (int)extra);
|
||||
|
||||
args[t].a = a;
|
||||
args[t].prefix = prefix;
|
||||
args[t].n = n;
|
||||
args[t].start = next;
|
||||
args[t].end = (len == 0) ? next - 1
|
||||
: (t == NTHREADS - 1 ? comb : next + len - 1);
|
||||
args[t].found = 0;
|
||||
args[t].inicio = siguiente;
|
||||
args[t].fin = (largo == 0) ? siguiente - 1 : siguiente + largo - 1;
|
||||
args[t].encontrado = 0;
|
||||
|
||||
if (len != 0)
|
||||
next = args[t].end + 1;
|
||||
if (largo != 0)
|
||||
siguiente = args[t].fin + 1;
|
||||
|
||||
if (pthread_create(&tids[t], NULL, buscar_thread, &args[t]) != 0) {
|
||||
for (int i = 0; i < created; i++)
|
||||
if (pthread_create(&tids[t], NULL, thread_buscar, &args[t]) != 0) {
|
||||
for (int i = 0; i < creados; i++)
|
||||
pthread_join(tids[i], NULL);
|
||||
return buscar_rango(a, prefix, n, 1, comb);
|
||||
}
|
||||
created++;
|
||||
|
||||
creados++;
|
||||
}
|
||||
|
||||
Set best = 0;
|
||||
Set mejor = 0;
|
||||
for (int t = 0; t < NTHREADS; t++) {
|
||||
pthread_join(tids[t], NULL);
|
||||
if (args[t].found != 0 && (best == 0 || args[t].found < best))
|
||||
best = args[t].found;
|
||||
if (args[t].encontrado != 0 &&
|
||||
(mejor == 0 || args[t].encontrado < mejor))
|
||||
mejor = args[t].encontrado;
|
||||
}
|
||||
|
||||
return best;
|
||||
return mejor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user