Esempio n. 1
0
static void generate_tsp_jobs (struct tsp_queue *q, int hops, int len, tsp_path_t path, long long int *cuts, tsp_path_t sol, int *sol_len, int depth)
{
    if (len >= minimum) {
        (*cuts)++ ;
        return;
    }
    
    if (hops == depth) {
        /* On enregistre du travail à faire plus tard... */
        add_job (q, path, hops, len);
    } else {
        int me = path [hops - 1];        
        for (int i = 0; i < nb_towns; i++) {
            if (!present (i, hops, path)) {
                path[hops] = i;
                int dist = distance[me][i];
                generate_tsp_jobs (q, hops + 1, len + dist, path, cuts, sol, sol_len, depth);
            }
        }
    }
}
Esempio n. 2
0
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    struct tsp_queue q;
    struct timespec t1, t2;
	

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
      switch (opt) {
      case 's':
	affiche_sol = true;
	break;
      default:
	usage(argv[0]);
	break;
      }
    }

    if (optind != argc-3)
      usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);
   
    minimum = INT_MAX;
      
    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);
	
	/* on vide le chemin 'path' : on met des -1 dans toutes les cases */
    memset (path, -1, MAX_TOWNS * sizeof (int));
	/* on définit la première ville comme étant 0 */
    path[0] = 0;

    /* On met des travaux dans la file d'attente q */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);
   
	/* on vide le chemin 'solution' : on met des -1 dans toutes les cases */
	/* puis on définit la première ville comme étant 0 */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;

	/* allocation du tableau d'informations sur les threads */
    tab_threads = malloc(nb_threads*sizeof(Cell));
	memset(tab_threads, 0, nb_threads*sizeof(int));

	/* initialisation du mutex*/
	pthread_mutex_init(&mutex, NULL);

	int i;

	/* on place tous les threads dans l'état 'non-occupé' */
	for(i=0; i<nb_threads; i++){
		tab_threads[i].occupe = 0;
    }

	/* Tant que la file de jobs n'est pas vide on sort un job et on l'execute avec tsp */
    while (!empty_queue (&q)) {
        int hops = 0, len = 0;
		/* on récupère un job dans la file d'atente des jobs */
        get_job (&q, solution, &hops, &len);
        
        i = 0;
		/* on boucle tant qu'on n'a pas trouvé de thread pour effectuer le job */
        while (1){
			/* si le thread i n'est pas occupé alors on va l'utiliser pour effectuer le job */
            if(!tab_threads[i].occupe){
                
				/* on place le thread i en statut 'occupé' */
                tab_threads[i].occupe = 1;

				/* on crée une structure arguments qui va recevoir les arguments de tsp */
                struct arg_struct arguments;

				arguments.hops = hops;
				arguments.len = len;
				memcpy(arguments.path, solution, nb_towns * sizeof (int));

				/* tsp est récursive et on a besoin de savoir quand le thread a terminé le job afin de le mettre en 'non-occupé' */
				/* On introduit donc un entier qui est 1 si le tsp appelé est celui du père et 0 si c'est dans les fils */
                arguments.pere = 1; 

				/* lancement du thread sur tsp avec les bons arguments*/
                pthread_create (&tab_threads[i].thread, NULL, tsp, (void*)&arguments);
                break;
            }
			/* sinon on va regarder si le suivant%nb_threads est occupé */
            i = (i+1)%nb_threads;
        }
    }

    i = 0;
	/* on attend la fin de tous les threads avant de continuer */
    while(1){
        pthread_join(tab_threads[i].thread, NULL);
        i++;
        if (i == nb_threads) break;
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
      print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
	   nb_towns, myseed, sol_len, nb_threads,
	   perf/1000000ll, perf%1000000ll, cuts);

    return 0 ;
}
Esempio n. 3
0
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    uint64_t vpres=0;
    struct timespec t1, t2;

	pthread_mutex_init(&q_mutex, NULL);
	pthread_mutex_init(&sol_mutex, NULL);
	pthread_mutex_init(&minimum_mutex, NULL);
	pthread_mutex_init(&cuts_mutex, NULL);

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "spq")) != -1) {
      switch (opt) {
      case 's':
	affiche_sol = true;
	break;
      case 'p':
	affiche_progress = true;
	break;
      case 'q':
	quiet = true;
	break;
      default:
	usage(argv[0]);
	break;
      }
    }

    if (optind != argc-3)
      usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);
   
    minimum = INT_MAX;
      
    /* generer la carte et la matrice de distance */
    if (! quiet)
      fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);

    memset (path, -1, MAX_TOWNS * sizeof (int));
    path[0] = 0;
    vpres=1;

    /* mettre les travaux dans la file d'attente */
    generate_tsp_jobs (&q, 1, 0, vpres, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);

	/* generate other threads */
	pthread_t *tids = malloc((nb_threads-1)*sizeof(pthread_t));
	for(int i = 0; i < nb_threads-1; i++){
		pthread_create(&(tids[i]), NULL, main_tsp, NULL);
	}
   
	main_tsp(NULL);
//    /* calculer chacun des travaux */
//	long long int myCuts = 0;
//    tsp_path_t solution;
//    memset (solution, -1, MAX_TOWNS * sizeof (int));
//    solution[0] = 0;
//    while (!empty_queue (&q, &q_mutex)) {
//        int hops = 0, len = 0;
//        get_job (&q, solution, &hops, &len, &vpres, &q_mutex);
//	
//	// le noeud est moins bon que la solution courante
//	if (minimum < INT_MAX
//	    && (nb_towns - hops) > 10
//	    && ( (lower_bound_using_hk(solution, hops, len, vpres)) >= minimum
//		 || (lower_bound_using_lp(solution, hops, len, vpres)) >= minimum)
//	    )
//
//	  continue;
//
//	tsp (hops, len, vpres, solution, &myCuts, sol, &sol_len);
//    }
//
//	/* update cuts */
//	pthread_mutex_lock(&cuts_mutex);
//	cuts += myCuts;
//	pthread_mutex_unlock(&cuts_mutex);

//    clock_gettime (CLOCK_REALTIME, &t2);
//    perf = TIME_DIFF (t1,t2);
//	printf("Main thread finished after %lld.%03lld ms\n\n", perf/1000000ll, perf%1000000ll);

	/* wait for other threads */
	for(int i = 0; i < nb_threads-1; i++){
		pthread_join(tids[i], NULL);
	}
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
      //print_solution_svg (sol, sol_len);
      print_solution_svg_to_file (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
	   nb_towns, myseed, sol_len, nb_threads,
	   perf/1000000ll, perf%1000000ll, cuts);

	pthread_mutex_destroy(&q_mutex);
	pthread_mutex_destroy(&sol_mutex);
	pthread_mutex_destroy(&minimum_mutex);
	pthread_mutex_destroy(&cuts_mutex);

    return 0 ;
}
Esempio n. 4
0
/* Main */
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    tsp_path_t sol;
    int sol_len;
    long long int cuts = 0;
    struct tsp_queue q;
    struct timespec t1, t2;

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
        switch (opt) {
            case 's':
                affiche_sol = true;
                break;
            default:
                usage(argv[0]);
                break;
        }
    }

    if (optind != argc-3)
        usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);

    minimum = INT_MAX;

    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);

    memset (path, -1, MAX_TOWNS * sizeof (int));
    path[0] = 0;

    /* mettre les travaux dans la file d'attente */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);

    /* calculer chacun des travaux */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;
    ThreadCell* list = NULL;
    ThreadCell* cur = NULL;

    for (int i = 0; i < nb_threads; i++) {
        ThreadCell* cell = (ThreadCell*) malloc(sizeof(ThreadCell));
        cell->next = NULL;
        WorkerArgs* args = (WorkerArgs*) malloc(sizeof(WorkerArgs));
        args->q = &q;
        memcpy(args->solution, solution, sizeof(tsp_path_t));
        args->cuts = &cuts;
        memcpy(args->sol, sol, sizeof(tsp_path_t));
        args->sol_len = &sol_len;
        pthread_create(&(cell->tid), NULL, tsp_worker, (void*) args);
        if (!list) {
            list = cell;
            cur = list;
        } else {
            cur->next = cell;
            cur = cur->next;
        }
        
    }
    
    void * status;
    while (list != NULL) {
        pthread_join(list->tid, &status);
        if (status == PTHREAD_CANCELED) {
            printf("Thread cancelled");
            exit(EXIT_FAILURE);
        }
        ThreadCell* tmp = list;
        list = list->next;
        free(tmp);
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
        print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
            nb_towns, myseed, sol_len, nb_threads,
            perf/1000000ll, perf%1000000ll, cuts);
    freemap();
    return 0 ;
}
Esempio n. 5
0
int main (int argc, char **argv)
{
    unsigned long long perf;
    tsp_path_t path;
    tsp_path_t sol;
    int sol_len;
    long long int cuts = 0;
    struct tsp_queue q;
    struct timespec t1, t2;

    /* lire les arguments */
    int opt;
    while ((opt = getopt(argc, argv, "s")) != -1) {
      switch (opt) {
      case 's':
	affiche_sol = true;
	break;
      default:
	usage(argv[0]);
	break;
      }
    }

    if (optind != argc-3)
      usage(argv[0]);

    nb_towns = atoi(argv[optind]);
    myseed = atol(argv[optind+1]);
    nb_threads = atoi(argv[optind+2]);
    assert(nb_towns > 0);
    assert(nb_threads > 0);
   
    minimum = INT_MAX;
      
    /* generer la carte et la matrice de distance */
    fprintf (stderr, "ncities = %3d\n", nb_towns);
    genmap ();

    init_queue (&q);

    clock_gettime (CLOCK_REALTIME, &t1);

    memset (path, -1, MAX_TOWNS * sizeof (int));
    path[0] = 0;

    /* mettre les travaux dans la file d'attente */
    generate_tsp_jobs (&q, 1, 0, path, &cuts, sol, & sol_len, 3);
    no_more_jobs (&q);
   
    /* calculer chacun des travaux */
    tsp_path_t solution;
    memset (solution, -1, MAX_TOWNS * sizeof (int));
    solution[0] = 0;
    while (!empty_queue (&q)) {
        int hops = 0, len = 0;
        get_job (&q, solution, &hops, &len);
        tsp (hops, len, solution, &cuts, sol, &sol_len);
    }
    
    clock_gettime (CLOCK_REALTIME, &t2);

    if (affiche_sol)
      print_solution_svg (sol, sol_len);

    perf = TIME_DIFF (t1,t2);
    printf("<!-- # = %d seed = %ld len = %d threads = %d time = %lld.%03lld ms ( %lld coupures ) -->\n",
	   nb_towns, myseed, sol_len, nb_threads,
	   perf/1000000ll, perf%1000000ll, cuts);

    return 0 ;
}