Camino máximo de primera fila a última. Versión OpenMP.

Sobre una matriz de números enteros positivos, $A$ de dimensión NxN, se quiere obtener el camino de longitud máxima desde la primera a la última fila de la matriz. Los posibles caminos empiezan en cualquier elemento de la primera fila, y desde una casilla se avanza a una vecina en la fila siguiente, en la misma columna o en la columna anterior o siguiente. La longitud de un camino viene dada por la suma de los valores en las casillas por las que pasa.

Se resuelven varios problemas. Para cada problema la función a paralelizar devuelve la longitud de camino máximo, y tiene parámetros:

Input parameter:

int N: número de filas y columnas

double *A: matriz de dimensión NxN

La entrada tiene en la primera línea el número de problemas. Para cada problema hay una línea con tres valores:

N, la semilla para la generación aleatoria, el valor máximo para la generación (el mínimo es uno).

Ficheros

4
5 6 5
17 11 10
17 12 13
17 1 20
/*
  CPP_CONTEST=2018Junio
  CPP_PROBLEM=F
  CPP_LANG=CPP+OPENMP
  CPP_PROCESSES_PER_NODE=calisto 1
*/

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>

extern void escribir(int *,int,int);

void copiar(int n,int *vd,int *vo) 
//se copia el vector vo en el vd
{
  int i;
  for(i=0;i<n;i++)
    vd[i]=vo[i];
}

int back(int n,int *A,int fila,int columna)
{
  int valor;
  if(fila==n-1)
    return A[fila*n+columna];
  else
  {
    int maximo=0;
    if(columna!=0)
    {
      valor=A[fila*n+columna]+back(n,A,fila+1,columna-1);
      if(valor>maximo)
        maximo=valor;
    }
    if(columna!=n-1)
    {
      valor=A[fila*n+columna]+back(n,A,fila+1,columna+1);
      if(valor>maximo)
        maximo=valor;
    }
    valor=A[fila*n+columna]+back(n,A,fila+1,columna);
    if(valor>maximo)
      maximo=valor;
    return maximo;
  }
}

int  sec(int n,int *A)
{
  int VOA=0; //valor óptimo actual
  
  for(int i=0;i<n;i++) //se calculan los óptimos empezando en cada una de las columnas de la primera fila
  {
     int valor=0; //para almacenar el valor calculado
     valor=back(n,A,0,i); //se pasa la fila y columna por lo que se sigue haciendo el backtracking
     if(valor>VOA)
     {
        VOA=valor;
     }
#ifdef DEBUG
  printf("columna %d , valor %d , optimo %d\n",i,valor,VOA);
#endif
  }
  return VOA;
}
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <omp.h>
#include <signal.h>
#include <unistd.h>
#include <iostream>
using namespace std;

//Prueba de Metodología de la Programación Paralela
//junio 2018
//Camino máximo de primera a última fila. Versión OpenMP
//Esquema para entrada/salida, validación y toma de tiempos

void generar(int *m, int t,int uv) {
  int i;

  for (i = 0; i < t; i++) {
      m[i] =(int) ((1. * rand() / RAND_MAX)*(uv-1)+1);
  }
}

void escribir(int *m, int N,int M) {
  int i, j;

  for (i = 0; i < N; i++) {
    for (j = 0; j < M; j++)
      printf("%d ", m[i * M + j]);
    printf("\n");
  }
  printf("\n");
}

/*
c
c     mseconds - returns elapsed milliseconds since Jan 1st, 1970.
c
*/
long long mseconds(){
  struct timeval t;
  gettimeofday(&t, NULL);
  return t.tv_sec*1000 + t.tv_usec/1000;
}

static void alarm_handler(int sig) {
  fprintf(stderr, "Time Limit Exceeded\n");
  abort();
}

extern int sec(int n,int *A);

int main(int argc,char *argv[]) {
  int N; //tamaño matriz
  int *A;
  int cuantos; //número de problemas
  int semilla; //semilla para generación aleatoria
  int uv; //valore superior para generación aleatoria
  long long ti,tf,tt=0;

  FILE *stats_file = fopen("stats", "w");

  struct sigaction sact;
  sigemptyset(&sact.sa_mask);
  sact.sa_flags = 0;
  sact.sa_handler = alarm_handler;
  sigaction(SIGALRM, &sact, NULL);
  alarm(60);  /* time limit */
 
  scanf("%d",&cuantos);

  for(int i=0;i<cuantos;i++)
  {
      scanf("%d",&N);                   
      scanf("%d",&semilla);  
      scanf("%d",&uv); 

      A = (int *) calloc(sizeof(int),N*N);

      srand(semilla);
      generar(A,N*N,uv);
#ifdef DEBUG
  escribir(A,N,N);
#endif
    ti=mseconds(); 
    cout <<sec(N,A)<<endl;
    tf=mseconds(); 
#ifdef DEBUG
  escribir(A,N,N);
#endif
      if(i!=0) tt+=tf-ti;
      free(A);
  }
  
    fprintf(stats_file, "%Ld\n", tt);
    fclose(stats_file);
  return 0;
}