update2
This commit is contained in:
75
T1/suma.c
75
T1/suma.c
@@ -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.
Reference in New Issue
Block a user