您的位置:首页 > 其它

双线程实现超大型3000*3000矩阵的转置

2013-11-22 23:14 274 查看

import java.util.Random;

//主类

public class Root {

 public static int time = 0;

 public static void main(String[] args) throws InterruptedException {

  // 矩阵的行列数目

  final int ROW_NUM = 3000;

  final int COLUM_NUM = 3000;

  // 查找最佳任务分配索引的查找阀值

  long threshold = 2300;

  // 算法执行的开始和结束时间

  long start_Time = 0;

  long end_Time = 0;

  // 串并行算法的执行时间

  double serial_Time;

  double parall_Time;

  // 分配任务的最佳索引值

  int theBestInternal = 0;

  // 创建伪随机数生成器,初始化种子为0

  Random random = new Random(0);

  // 构造整型矩阵

  int array[][] = new int[ROW_NUM][COLUM_NUM];

  //并行计算开始计时

  start_Time = System.currentTimeMillis();

  // 寻找最佳任务分配索引点

  theBestInternal = findTheBestInternal(1500, 2250,

    threshold, COLUM_NUM);

  end_Time = System.currentTimeMillis();

  System.out.println("最佳的任务分配索引是: " + theBestInternal);

  System.out.println("分配耗时为: " + (end_Time - start_Time));

  System.out.println("time= " + time);

  // 三个测试线程

  ImplTransform transform1 = new ImplTransform(0, theBestInternal, 2999,

    array);

  ImplTransform transform2 = new ImplTransform(theBestInternal, 2998,

    2999, array);

  ImplTransform transform3 = new ImplTransform(0, 2998, 2999, array);

  // 随机的初始化数组元素

  InitializeArray(random, array);

  // 并行算法执行之前的数组形态

  // printArray(array);

  start_Time = System.currentTimeMillis();

  transform1.start();

  transform2.start();

  transform1.join();

  transform2.join();

  end_Time = System.currentTimeMillis();

  parall_Time = end_Time - start_Time;

  System.out.println("并行执行时为: " + parall_Time);

  // 并行算法执行之后的数组形态

  // printArray(array);

  // 串行算法执行前的状态

  // printArray(array);

  start_Time = System.currentTimeMillis();

  transform3.start();

  transform3.join();

  end_Time = System.currentTimeMillis();

  serial_Time = end_Time - start_Time;

  System.out.println("串行执行时为: " + serial_Time);

  System.out.println("加速比为: " + (serial_Time / parall_Time));

 }

 private static void InitializeArray(Random random, int[][] array) {

  for (int i = 0; i <= array.length - 1; i++) {

   for (int j = 0; j <= array.length - 1; j++) {

    array[i][j] = random.nextInt(400);

   }

  }

 }

 private static void printArray(int[][] array) {

  // 打印数组

  for (int i = 0; i <= array.length - 1; i++) {

   for (int j = 0; j <= array.length - 1; j++) {

    System.out.print(array[i][j] + " ");

   }

   System.out.println();

  }

 }

 // 通过二分法查找最佳的任务分配索引点

 /**

  * start_Index,end_Index为确定的精确查找范围 threshold为查找的阀值 column_TotalNums为数组的最大列索引

  */

 public static int findTheBestInternal(int start_Index, int end_Index,

   long threshold, int column_TotalNums) {

  int middle = 0;

  // 定义二维数组的一半以内的前不部分和后半部分的和(按对角线分割)

  long frontSum = 0;

  long laterSum = 0;

  middle = (start_Index + end_Index) / 2;

  frontSum = (middle * middle) / 2;

  laterSum = (column_TotalNums + middle) * (column_TotalNums - middle)

    / 2;

  // 如果前半和后半的总和差值超过了阀值

  if (Math.abs(laterSum - frontSum) > threshold) {

      time++;

      if(time > 5000){

       System.exit(0);

      }

   if (laterSum > frontSum) {

    start_Index = middle;

    middle = (start_Index + end_Index) / 2;

    return findTheBestInternal(start_Index, end_Index, threshold,

      column_TotalNums);

   } else if(laterSum < frontSum){

    end_Index = middle;

    middle = (start_Index + end_Index) / 2;

    return findTheBestInternal(start_Index, end_Index, threshold,

      column_TotalNums);

   }

  }

  return middle;

 }

}

//线程类

public class ImplTransform extends Thread {

 // 定义线程对矩阵进行转换的起始行下标

 int start_Row = 0;

 int end_Row = 0;

 // 矩阵的最大列索引

 int max_Columns = 0;

 // 要进行转置的目标二维数组

 int array[][] = null;

 public ImplTransform(int start_Row, int end_Row, int max_Columns,

   int[][] array) {

  super();

  this.start_Row = start_Row;

  this.end_Row = end_Row;

  this.max_Columns = max_Columns;

  this.array = array;

 }

 public void run() {

  ArrayTransform();

 }

 public void ArrayTransform() {

  int i = 0;

  int j = 0;

  for (i = start_Row; i <= end_Row; i++) {

   for (j = start_Row + 1; j <= max_Columns; j++) {

    // 通过异或运算将矩阵中的对应位置的数字进行转置

    if(array[i][j] != array[j][i]){

     array[j][i] = array[i][j] ^ array[j][i];

     array[i][j] = array[j][i] ^ array[i][j];

     array[j][i] = array[i][j] ^ array[j][i];

    }

   }

  }

 }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: