This commit is contained in:
2026-03-30 21:45:30 -03:00
parent ff4c6cb794
commit 5bffc57bd6
2 changed files with 24 additions and 51 deletions

View File

@@ -1,125 +1,98 @@
#include <limits.h> #include <limits.h>
#include <pthread.h> #include <pthread.h>
#include "suma.h" #include "suma.h"
// Defina aca las estructuras que necesite // Defina aca las estructuras que necesite
enum {NTHREADS= 8};
enum { NTHREADS = 8 }; typedef long long ll;
typedef struct { typedef struct {
int *a; int *a;
long long *prefix; ll *prefix;
int n; int n;
Set inicio; Set inicio;
Set fin; Set fin;
Set encontrado; Set encontrado;
} ArgsBuscar; } ArgsBuscar;
static Set total_combinaciones(int n) { static Set total_combinaciones(int n) {
if (n >= (int)(sizeof(Set) * CHAR_BIT)) if (n >= (int)(sizeof(Set) *CHAR_BIT))
return ~(Set)0; return ~(Set)0;
return ((Set)1 << n) - 1; return ((Set)1 << n)-1;
} }
static ll suma_subconjunto(int a[], int n, Set k) {
static long long suma_subconjunto(int a[], int n, Set k) { ll suma=0;
long long suma = 0; for (int i=0; i<n;i++) {
for (int i = 0; i < n; i++) {
if (k & ((Set)1 << i)) if (k & ((Set)1 << i))
suma += a[i]; suma +=a[i];
} }
return suma; return suma;
} }
static int contar_unos_finales(Set k) { static int contar_unos_finales(Set k) {
int cant = 0; int cant=0;
while ((k&1)!=0) {
while ((k & 1) != 0) {
cant++; cant++;
k >>= 1; k >>= 1;
} }
return cant; return cant;
} }
static Set buscar_rango(int a[], ll prefix[], int n, Set inicio, Set fin) {
static Set buscar_rango(int a[], long long prefix[], int n, Set inicio, Set fin) {
if (inicio == 0 || inicio > fin) if (inicio == 0 || inicio > fin)
return 0; return 0;
Set k = inicio; Set k = inicio;
long long suma = suma_subconjunto(a, n, k); ll suma = suma_subconjunto(a, n, k);
while (1) { while (1) {
if (suma == 0) if (suma == 0)
return k; return k;
if (k == fin) if (k == fin)
break; break;
int cambios = contar_unos_finales(k); int cambios = contar_unos_finales(k);
suma -= prefix[cambios]; suma -= prefix[cambios];
suma += a[cambios]; suma += a[cambios];
k++; k++;
} }
return 0; return 0;
} }
// Defina aca la funcion que ejecutaran los threads // Defina aca la funcion que ejecutaran los threads
static void *thread_buscar(void *ptr) { static void *thread_buscar(void *ptr) {
ArgsBuscar *args = ptr; ArgsBuscar *args = ptr;
args->encontrado = buscar_rango(args->a, args->prefix, args->n, args->inicio, args->encontrado = buscar_rango(args->a, args->prefix, args->n, args->inicio,
args->fin); args->fin);
return NULL; return NULL;
} }
// Reprograme aca la funcion buscar // Reprograme aca la funcion buscar
Set buscar(int a[], int n) { Set buscar(int a[],int n) {
Set comb = total_combinaciones(n); Set comb= total_combinaciones(n);
Set base = comb / NTHREADS; Set base= comb / NTHREADS;
Set extra = comb % NTHREADS; Set extra =comb % NTHREADS;
Set siguiente = 1; Set siguiente =1;
pthread_t tids[NTHREADS]; pthread_t tids[NTHREADS];
ArgsBuscar args[NTHREADS]; ArgsBuscar args[NTHREADS];
long long prefix[CHAR_BIT * sizeof(Set) + 1]; ll prefix[CHAR_BIT * sizeof(Set) + 1];
int creados = 0; int creados = 0;
prefix[0] = 0; prefix[0] = 0;
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
prefix[i + 1] = prefix[i] + a[i]; prefix[i + 1] = prefix[i] + a[i];
for (int t = 0; t < NTHREADS; t++) { for (int t = 0; t < NTHREADS; t++) {
Set largo = base + (Set)(t < (int)extra); Set largo = base + (Set)(t < (int)extra);
args[t].a = a; args[t].a = a;
args[t].prefix = prefix; args[t].prefix = prefix;
args[t].n = n; args[t].n = n;
args[t].inicio = siguiente; args[t].inicio = siguiente;
args[t].fin = (largo == 0) ? siguiente - 1 : siguiente + largo - 1; args[t].fin = (largo == 0) ? siguiente - 1 : siguiente + largo - 1;
args[t].encontrado = 0; args[t].encontrado = 0;
if (largo != 0) if (largo != 0)
siguiente = args[t].fin + 1; siguiente =args[t].fin + 1;
if (pthread_create(&tids[t], NULL, thread_buscar, &args[t]) != 0) { if (pthread_create(&tids[t], NULL, thread_buscar, &args[t]) != 0) {
for (int i = 0; i < creados; i++) for (int i = 0; i < creados; i++)
pthread_join(tids[i], NULL); pthread_join(tids[i], NULL);
return buscar_rango(a, prefix, n, 1, comb); return buscar_rango(a, prefix, n, 1, comb);
} }
creados++; creados++;
} }
Set mejor=0;
Set mejor = 0; for (int t=0; t<NTHREADS;t++) {
for (int t = 0; t < NTHREADS; t++) {
pthread_join(tids[t], NULL); pthread_join(tids[t], NULL);
if (args[t].encontrado != 0 && if (args[t].encontrado != 0 &&
(mejor == 0 || args[t].encontrado < mejor)) (mejor == 0||args[t].encontrado<mejor))
mejor = args[t].encontrado; mejor=args[t].encontrado;
} }
return mejor; return mejor;
} }

Binary file not shown.