学校给了一个4×3G的cluster,写一个并行的程序。这里采用的是MPI, Message Passing Interface。算法在前面的post里讨论过了,我的算法很烂拉,没有好好利用,就算在那么强悍的机器上也没有办法跑到什么好结果。班上有4组牛人跑到最好的4个结果,166106,167692,171233,171313。哪位大哥有兴趣可以挑战一下,嘿嘿

这里是代码,non-blocking的版本。写的很烂

tsp.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <time.h>

#ifndef _TSP_H_
#define _TSP_H_

#define CITYSIZE 500
/* 15000 > distance(0,0,10000,10000) */
#define MAXDIST  15000
/* 7500000 > 15000 * (500 - 1) */
#define MAXTOTAL 7500000

/* cities informatin */
typedef struct S_c {
 int x;
 int y;
 int visited;
} CITY;

/* a linked-list record local path generated by perm() */
struct S_path {
 int* path;
 struct S_path* next;
 struct S_path* prev;
} *head, *tail;

//***********************************************************************
void showCity(CITY*,int);              // show city coordinate,for test *
void showDist(int[][CITYSIZE],int);          // show distances,for test *
void showPath(int*,int,int,int[][CITYSIZE]);         // show found path *
double distance(int,int,int,int);                   // distance formula *
void perm(int*,int,int,int);                  // generate a permutation *
void swap(int*,int*);                                     // for perm() *
int localSearch(int,int*,int*,int[][CITYSIZE]);                      // *
int findrepeat(int*,int);                      // check if result valid *
int weightOf(int*,int[][CITYSIZE]);        // calculate a path's weight *
void ga(int);                               // simple genetic algorithm *
/************************************************************************/

void showDist(int array[][CITYSIZE], int size){
 int i, j;
 for(i = 0; i < size; ++i){
  for(j = 0; j < size; ++j){
   printf("%4d,", array[i][j]);
  }
  printf("/n");
 }
}

void showCity(CITY* array, int size){
 int i; 
 for(i = 0; i < size; ++i){
  printf("%d:%d:%d:%d/n", i,
        array[i].x,
        array[i].y,
        array[i].visited);
 }// for end
}

void showPath(int* array, int size, int total, int weight[][CITYSIZE]){
 int i;
 if(findrepeat(array, size)){printf("Wrong answer!/n");exit(0);}
 if(total!=weightOf(array, weight)){
  printf("wrong answer!/n");exit(0);}
 printf("%d:", total);
 for(i = 0; i < size - 1; ++i) printf("%d,", array[i]);
 printf("%d/n/n", array[i]);
}

double distance(int x1, int y1, int x2, int y2){
 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int localSearch(int step, int* tour, int* total, int weight[][CITYSIZE]){
 int i = 0;
 
 for(; (i + step) < CITYSIZE; i = i + step){
  int j = 0;
  int sublength = 0, newweight = 0, currBest;
  for(; j < step; ++j) sublength += weight[tour[i+j]][tour[i+j+1]];
  currBest = sublength;
  /* for sequence 01234, we need a permutation of p(123) only.
   * so, the lower and upper bound would be i + 1 and i + step - 1.
   */
  perm(tour, i + 1, i + step - 1, i + 1);
  // check all new path in permutation.
  struct S_path* onePath = tail->prev;
  while(onePath != head){
   onePath->prev->next = tail;
   tail->prev = onePath->prev;
   newweight = weight[tour[i]][onePath->path[0]] +
               weight[onePath->path[step-2]][tour[i+step]];
   for(j = 0; j < step - 2; ++j)
    newweight += weight[onePath->path[j]][onePath->path[j+1]];
   if(newweight < currBest){
    currBest = newweight;
    memcpy(tour+i+1,onePath->path,sizeof(int)*(step-1));
   }
   free(onePath->path);
   free(onePath);
   onePath = tail->prev;
  }// while end
  // update total length
  *total = *total - sublength + currBest;
 }// for end
 //showPath(tour,CITYSIZE, *total, weight);
 return *total;
}

/* variable 'original' record the start point(lower bound) in array,
 * used for output, when invoke perm(), original and k is same.
 */
void perm(int* list, int k, int m, int original){
 int i, j;
 if(k > m){// exist a permutation, add to list
  struct S_path* myPath =(struct S_path*)malloc(sizeof(struct S_path));
  struct S_path* tmp = head->next;
  myPath->path = (int*)malloc(sizeof(int)*(m - original + 1));
  head->next = myPath;
  myPath->prev = head;
  myPath->next = tmp;
  tmp->prev = myPath;
  for(i = original; i <= m; ++i) myPath->path[i-original] = list[i];
 } else {
  for(j = k; j <= m; ++j){
   swap(&list[k], &list[j]);
   perm(list, k + 1, m, original);
   swap(&list[k], &list[j]);
  }
 }
}

void swap(int* a, int* b){
 int temp = *a;
 *a = *b;
 *b = temp;
}

int findrepeat(int* array, int size){
 int i, j;
 for(i = 0; i < size; ++i){
  int tmp = 0;
  for(j = 0; j < size; ++j) if(i == array[j]) tmp++;
  if(tmp > 1){printf("error: repeat city!/n");return 1;}
 }
 return 0;
}

int weightOf(int* array, int weight[][CITYSIZE]){
 int w = 0, i = 0;
 for(; i < CITYSIZE - 1; ++i)
  w += weight[array[i]][array[i+1]];
 return w;
}

/*
// cannot get a path shorter than 190k in 1min, DEPRECATED
// need weight[][],all500paths[][],all500weights[] support
void ga(int separator){
 time_t seed;
 time(&seed);
 srand(seed);

int epoch = 0;
 for(; epoch < 1000000; ++epoch){
  // printf("epoch %d:/n", epoch);
  rand(); // dump first number
  
  // randomly pick two path index
  int index1 = (int)((double)rand()*500/RAND_MAX);
  int index2 = (int)((double)rand()*500/RAND_MAX);

// get the two paths copies
  int path1[CITYSIZE], path2[CITYSIZE];
  memcpy(path1, all500paths[index1], sizeof(path1));
  memcpy(path2, all500paths[index2], sizeof(path2));

// exchange two fragments to get next epoch
  int* frag1 = (int*)malloc(sizeof(int)*separator);
  memcpy(frag1, path1, sizeof(int)*separator);
  memcpy(path1, path2, sizeof(int)*separator);
  memcpy(path2, frag1, sizeof(int)*separator);
  free(frag1);

// re-generate path1 & path2
  int i, check1[CITYSIZE] = {0}, check2[CITYSIZE] = {0};
  // separator~CITYSIZE-1 is original path, isn't changed
  for(i = separator; i < CITYSIZE; ++i){
   check1[path1[i]]++;
   check2[path2[i]]++;
  }

// check new part in path
  // 0~seprator-1 is new part copied from the other one
  for(i = 0; i < separator; ++i){
   if(check1[path1[i]]){
    int j = 0;
    while(check1[j])j++; // step to first non-zero position
    check1[j]++;
    path1[i] = j;
   }else check1[path1[i]]++;
  
   if(check2[path2[i]]){
    int j = 0;
    while(check2[j])j++;
    check2[j]++;
    path2[i] = j;
   }else check2[path2[i]]++;
  }

int mytotal1 = 0, mytotal2 = 0;
  // calculate new path length
  for(i = 0; i < CITYSIZE - 1; ++i){
   mytotal1 += weight[path1[i]][path1[i+1]];
   mytotal2 += weight[path2[i]][path2[i+1]];
  }
  // update if better route found
  if(mytotal1 < all500weights[path1[0]]){
   printf("better found in path%d: %d/n", path1[0], mytotal1);
   all500weights[path1[0]] = mytotal1;
   memcpy(all500paths[path1[0]], path1, sizeof(int)*CITYSIZE);
  }
  if(mytotal2 < all500weights[path2[0]]){
   printf("better found in path%d: %d/n", path2[0], mytotal2);
   all500weights[path2[0]] = mytotal2;
   memcpy(all500paths[path2[0]], path2, sizeof(int)*CITYSIZE);
  }
 }// for end, one epoch end
}
*/
#endif

tsp.c

/* 500 cities Hamilton Path */
/* Repetitive Nearest Neighbour Algorithm (RNNA) */
/* with Local Search */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <time.h>
#include "tsp.h"

/* local search factor
 * greater number means deeper recursive
 */
#define STEP 11

#define WORK 1
#define DIE 2

int tour[CITYSIZE],  // best path
 total = MAXTOTAL; // best path length

void master();
void slave(int);

int main(int argc, char *argv[]){
// time_t start, done;
// time(&start);
    int myid;

MPI_Init(&argc, &argv);
 MPI_Comm_rank(MPI_COMM_WORLD, &myid);
   
 if(myid == 0) master();
 else slave(myid);

MPI_Finalize();
// time(&done);
// printf("process %d's execution time = %d seconds/n", myid, done - start);
    return 0;
}

void master(){
 // mpi used varibles
 int numprocs;
 int allFree = 1;
 char tmp;
 int* freeprocs = (int*)calloc(numprocs - 1, sizeof(int));
 int* indicies  = (int*)malloc((numprocs - 1) * sizeof(int));
 MPI_Request* reqs = (MPI_Request*)calloc(numprocs-1, sizeof(MPI_Request));
 MPI_Status * stat = (MPI_Status*)malloc(sizeof(MPI_Status)*(numprocs-1));
 MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
 memset(freeprocs, 0, numprocs - 1);
 
 // assignment used varibles
 FILE *fin;
 CITY city[CITYSIZE];
 int i, j,
  tmptour[CITYSIZE],
  weight[CITYSIZE][CITYSIZE]={0};   // distances between cities

fin = fopen("cities.dat", "r");
 
 /* read cities locations */
 char dump;  // useless information, used to omit ':'
 for(i = 0; i < CITYSIZE; ++i){
  fscanf(fin, "%d %c %d", &dump, &dump, &city[i].x);
  fscanf(fin, "%c %d", &dump, &city[i].y);
 }
 
 /* calculate cities distance */
 for(i = 0; i < CITYSIZE; ++i){
     for(j = 0; j < CITYSIZE; ++j){
      if(i < j){
          weight[i][j] = (int)distance(city[i].x, city[i].y,
                                    city[j].x, city[j].y);
          weight[j][i] = weight[i][j];
      }//if end
     }//for end
 }// for end

/* RNNA start, use NNA for all 500 cities.
  * best path stored in tour[], best weight stored in total
  */
 int tmptotal = MAXTOTAL, startCty = 0;
 for(; startCty < CITYSIZE; ++startCty){
  /* if found better path */
  if(tmptotal < total){
   total = tmptotal;
   memcpy(tour, tmptour, sizeof(tour));
   showPath(tour, CITYSIZE, total, weight);
  }
  /* initialization */
  tmptotal = 0;
  for(i = 0; i < CITYSIZE; ++i) city[i].visited = 0;
  
  int nextCty, currCty = startCty;
  tmptour[0] = startCty;
  city[startCty].visited = 1;
  
  for(i = 1; i < CITYSIZE; ++i){
   int cost = MAXDIST;
   for(j = 0; j < CITYSIZE; ++j){
    if((cost > weight[currCty][j]) && // currCty~j is better and
       (!city[j].visited)  &&         // j hasn't been visited and
       (j != currCty)){               // j is not currCty
        cost = weight[currCty][j];
        nextCty = j;
    }// if end
   }// for end

// step to next city
   currCty = nextCty;
   // add this city into path
   tmptour[i] = currCty;
   city[currCty].visited = 1;
   // accumulate path length
   tmptotal += cost;
  }// for end
 }// for end 
 /* RNNA finished here, local search start */
 
 // send distance matrix to slaves first
 for(i = 1; i < numprocs; ++i){
  MPI_Isend(weight, CITYSIZE * CITYSIZE, MPI_INT,
      i, WORK, MPI_COMM_WORLD, reqs + i);
 }
 
 // get packet length
 int s1, s2, s3, st;
 MPI_Pack_size(CITYSIZE, MPI_INT, MPI_COMM_WORLD, &s1);
 MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &s2);
 MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &s3);

st = s1 + s2 + s3;
 
 int step = 3, position = 0;
 // used to store received paths
 int lsResults[numprocs - 1][CITYSIZE];
 while(step < STEP || allFree){
  for(i = 0; i < numprocs - 1 && step < STEP; ++i){
   if(*(freeprocs + i) == 0){// found idle slave...
    *(freeprocs + i) = 1;
    char* buffer = (char*)malloc(sizeof(char)*(st));
    MPI_Pack(tour, CITYSIZE, MPI_INT, buffer,
       st, &position, MPI_COMM_WORLD);
    MPI_Pack(&total, 1, MPI_INT, buffer,
       st, &position, MPI_COMM_WORLD);
    MPI_Pack(&step, 1, MPI_INT, buffer,
       st, &position, MPI_COMM_WORLD);
  
    MPI_Send(buffer, position, MPI_PACKED,
        i + 1, WORK, MPI_COMM_WORLD);
    free(buffer);
    position =0;
    step++;
    MPI_Irecv(*(lsResults + i), CITYSIZE, MPI_INT,
        i + 1, 1, MPI_COMM_WORLD, reqs + i);
   }// if end
  }// for end
  MPI_Testsome(numprocs - 1, reqs, &j, indicies, stat);

if(j > 0){
   for(i = 0; i < j; ++i){
    *(freeprocs + indicies[i]) = 0;
    tmptotal = weightOf(lsResults[indicies[i]], weight);
    if(tmptotal < total){
     total = tmptotal;
     memcpy(tour, lsResults[indicies[i]], sizeof(tour));
     showPath(tour, CITYSIZE, total, weight);
    }// if end
   }// for end
  }// if end
  
  allFree = 1;
  for(i = 0; i < numprocs-1 && allFree; ++i)
   if(*(freeprocs + i) == 0) allFree = 0;
 }// while end
 
 // kill all slaves
 for(i = 1; i < numprocs; ++i){
  // no meaning data, just for matching data format
  char* buffer = (char*)malloc(sizeof(char)*(st));
  MPI_Pack(tour, CITYSIZE, MPI_INT, buffer,
     st, &position, MPI_COMM_WORLD);
  MPI_Pack(&total, 1, MPI_INT, buffer,
     st, &position, MPI_COMM_WORLD);
  MPI_Pack(&step, 1, MPI_INT, buffer,
     st, &position, MPI_COMM_WORLD);
  MPI_Isend(buffer, position, MPI_PACKED,
      i, DIE, MPI_COMM_WORLD, reqs + i);
  free(buffer);
  position = 0;
 }
}

void slave(int myid){
 MPI_Status status;
 MPI_Request request;
 int W[CITYSIZE * CITYSIZE],
  weight[CITYSIZE][CITYSIZE],
  tour[CITYSIZE],
  i, j, total, step, position = 0;

// get packet length
 int s1, s2, s3, st;
 MPI_Pack_size(CITYSIZE, MPI_INT, MPI_COMM_WORLD, &s1);
 MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &s2);
 MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &s3);

st = s1 + s2 + s3;
 
 // initialize list for localSearch()
 head = (struct S_path*)malloc(sizeof(struct S_path));
 tail = (struct S_path*)malloc(sizeof(struct S_path));
 head->next = tail;
 head->prev = NULL;
 tail->prev = head;
 tail->next = NULL;

// receive distance matrix
 MPI_Recv(W, CITYSIZE * CITYSIZE, MPI_INT,
    0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
 // cast to 2d array
 for(i = 0; i < CITYSIZE; ++i)
  for(j = 0; j < CITYSIZE; ++j)
   weight[i][j] = W[i * CITYSIZE + j];
 
 while(1){
  char* buffer = (char*)malloc(sizeof(char)*st);
  MPI_Recv(buffer, st, MPI_PACKED,
     0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
  MPI_Unpack(buffer, st, &position,
       tour, CITYSIZE, MPI_INT, MPI_COMM_WORLD); 
  MPI_Unpack(buffer, st, &position,
       &total, 1, MPI_INT, MPI_COMM_WORLD);
  MPI_Unpack(buffer, st, &position,
       &step, 1, MPI_INT, MPI_COMM_WORLD);
  free(buffer);
  position = 0;
  if (status.MPI_TAG == DIE) return;
  
  localSearch(step, tour, &total, weight);
  MPI_Isend(tour, CITYSIZE, MPI_INT, 0,
      WORK, MPI_COMM_WORLD, &request);
  MPI_Wait(&request, &status);
 }
}

Parellel TSP相关推荐

  1. 【一】TSP、VRP、VRP模型介绍

    一. TSP问题数学模型 编辑 TSP,即Traveling Salesman Problem,也就是旅行商问题,又译为旅行推销员问题.货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求 ...

  2. 智能算法的应用记录一点点-----TSP 路径规划

    在研究智能算法的时候,想到怎么应用了吗?单纯的使用基准函 数进行测试就能证明算法是优秀的吗?? 文章链接: [图文]几种智能算法概述及其应用_百度文库 https://wenku.baidu.com/ ...

  3. 基于GA的TSP问题

    来源: 在matlab上实现遗传算法解决TSP旅行者问题 - CSDN博客 https://blog.csdn.net/cordova/article/details/64912680?locatio ...

  4. 双调TSP问题通俗讲解

    欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题,下图a给出了7个点问题的解.这个问题的一般形式是NP完全的,故其解需要多于多项式的时间.                 ...

  5. 利用HTML5 Canvas和Javascript实现的蚁群算法求解TSP问题演示

    HTML5提供了Canvas对象,为画图应用提供了便利. Javascript可执行于浏览器中, 而不须要安装特定的编译器: 基于HTML5和Javascript语言, 可随时编写应用, 为算法測试带 ...

  6. 启发式搜索求解TSP近似解

    一. 实验要求 TSP (旅行商) 问题是运筹学和最优化理论等领域的经典问题,它已证明是NP(Nondeterministic Polynomial)完全问题,到目前为止, 所有的NP完全问题都还没有 ...

  7. 旅行售货员 java_JAVA旅行商售货TSP

    题目描述 有若干个城市,任何两个城市之间的距离都是确定的,现要求一旅行商从某城市出发必须经过每一个城市且只在一个城市逗留一次,最后回到出发的城市,问如何事先确定一条最短的线路以保证路径最短? 输入 输 ...

  8. 自组织映射网络(SOM)如何解决TSP问题

    本文仅介绍思路,不进行实践. 以3个城市为例,假设给定的TSP问题中城市是以坐标的形式给出,那么坐标是一个二维的向量.从而我们设计一个SOM网络如下: 我们希望做到的是,在训练完成后,每个城市(黑色) ...

  9. java 双调旅行商 hamiltonian,双调欧几里得旅行商问题(TSP)

    最小环+欧拉回路=最短哈密顿图 介绍 TSP(Traveling Salesman Problem)即旅行商问题,是数学领域中著名问题之一.这个问题是这样的:假设有一个旅行商人要拜访n个城市,他必须选 ...

最新文章

  1. Codeforces 375D - Tree and Queries(dfs序+莫队)
  2. Strut2与Hibernate的一个web分页功能
  3. docker端口映射或启动容器时报错 driver failed programming external connectivity on endpoint
  4. django06: ORM示例2--uer 与file
  5. vs2010的sdf文件和ipch文件夹
  6. 实用调试技巧 Debug Release F10 F11 初始化 越界访问 堆栈 模拟实现库函数
  7. 1405 奶牛的旅行
  8. opencv3.4.2调用训练好的Openpose模型
  9. 3.Python标准库—math库的使用
  10. 计算机专业论文推荐,计算机专业论文参考文献推荐
  11. 微信小程序转码机器人❤️免费无水印❤️
  12. VBA小模板:一个普通随机抽奖,需要模拟多轮用VBA怎么做?
  13. 手动抛出异常回滚事务,且返回数据给前端
  14. AutoCAD 的托管程序集
  15. Java阻塞队列-BlockingQueue介绍及实现原理
  16. 机械键盘指南(一)纵览与轴
  17. 机会都是留给有准备的人,你在准备什么?| 每天成就更大成功
  18. 利用QT实现瀑布图、Lofar谱图、色谱图,热力图(二)
  19. 通俗易懂讲解汇率、外币汇率、本币汇率、通货膨胀
  20. 使用layer弹出层组件绑定页面按钮

热门文章

  1. 微软跳上OpenID Bandwagon
  2. html onload状态事件,HTML onload事件用法及代码示例
  3. 苹果编程新纪元 之 Swift
  4. 一千万数据,怎么快速查询
  5. 智能汽车里究竟“藏”有多少传感器?
  6. vue文件夹上传组件选哪个好?
  7. constexpr specifier
  8. 分数阶 计算机应用,分数阶计算器
  9. 小提琴统计图_快速绘制分组小提琴图工具
  10. 小提琴统计图_R语言数据可视化系列(4)箱线图和小提琴图(附详细代码)