zoukankan      html  css  js  c++  java
  • 关于分治算法的个人理解

    关于分治算法的个人理解:
    把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。
    以快速排序为例,先取一个参数。将大于该参数的值放在右边,小于该参数的值放在左边,使该参数处于最正确的位置上。
    该案例的基本思想:是将该数组排序问题分成为该数组中的数值与选取的参数值比较大小。即简单的一对一的比较问题。
    该比较问题相互独立、具有最优子结构性质,且可以合并。

    1.快速排序

    public class Test{

    public static void main(String []args){

    int arr[] = {40,30,15,57,86,68,98};

    quick(arr , 0 , arr.length-1);

    for(int i:arr){
    System.out.print(i+" ");
    }

    }

    public static void quick(int[] arr , int min , int max){

    if(min < max){

    int n = sort(arr , min , max);

    quick(arr , min , n-1);
    quick(arr , n+1 , max);

    }

    }

    public static int sort(int[] arr , int min , int max){

    int sum = arr[min];

    while(min < max){

    while(min < max && arr[max] >= sum){

    max--;

    }

    arr[min] = arr[max];

    while(min < max && arr[min] <= sum){

    min++;

    }

    arr[max] = arr[min];

    }

    arr[min] = sum;

    return min;

    }

    }

    二分搜索:
    public class Test{

    public static void main(String []args){

    int []arr = {0,1,3,5,7,8,9};

    System.out.println(select(arr,0,arr.length-1,3));
    }

    public static int select(int[] arr , int min , int max , int i){

    while(min <= max){

    int middle = (min + max)/2;

    if(i == arr[middle]){
    return middle;
    }else if(i<arr[middle]){
    return select(arr,min,middle - 1,i);
    }else{
    return select(arr,middle + 1,max,i);
    }
    }
    return -1;
    }

    }

    汉诺塔:

    public class Test {

    public static void main(String []args){

    move(3,"A","B","C");
    }

    public static void move(i,String A, Sting B, String C){

    if(i==1){
    System.out.println("把"+i+"从"+A+"移动到"+C);
    }else{

    move(i-1,A,C,B);
    System.out.println("把"+i+"从"+A+"移动到"+C);
    move(i-1,B,A,C);
    }
    }
    }


    矩阵相加:

    public class Test{

    public static void main(String []args){

    int[][] a = {{1,2},{3,4}};
    int[][] b = {{5,6},{7,8}};

    int[][] c = new int[a.length][b.length];

    if( a.length != b.length){
    System.out.println();
    }else{
    for(int i=0;i<a.length;i++){
    for(int j=0;i<b.length;j++){
    c[i][j] = a[i][j] + b[i][j];
    }

    }
    }
    }
    }

    矩阵相减:

    public class Test{

    public static void main(String []args){

    int[][] a= {{1,2},{3,4}};
    int[][] b= {{5,6},{7,8}};

    int[][] c = new int[a.length][b.length];

    if( a.length != b.length){
    System.out.println();
    }else{
    for(int i=0;i<a.length;i++){
    for(int j=0;i<b.length;j++){
    c[i][j] = a[i][j] - b[i][j];
    }

    }
    }
    }
    }

    矩阵相乘(简单直接):

    public class Test{

    public static void main(String []args){
    int[][] a= {{1,2},{3,4}};
    int[][] b= {{5,6},{7,8}};

    int[][] c = new int[a.length][b.length];

    if( a.length != b.length){
    System.out.println("您输入的矩阵不正确!!!");
    }else{
    for(int i=0;i<a.length;i++){
    for(int j=0;i<b.length;j++){
    c[i][j] = 0;
    for(int k=0;k<c.length;k++){
    c[i][j] += a[i][k]*b[k][j]
    }
    }

    }
    }
    }
    }

    矩阵相乘(利用分治思想):


    public class Test {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    int [][]a = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};
    int [][]b = {{1,2,3,4},{1,2,3,4},{1,2,3,4},{1,2,3,4}};

    int [][]c = flag(a,b,a.length);

    for (int i = 0; i < c.length; i++) {
    for (int j = 0; j < c.length; j++) {
    System.out.print(c[i][j] + " ");
    }
    System.out.println();
    }
    }

    private static int[][] flag(int[][] a, int[][] b, int n) {

    int[][] result = new int[n][n];

    if (n == 1) {
    result[0][0] = a[0][0]*b[0][0];
    return result;
    }

    int [][]a11 = new int[n/2][n/2];
    int [][]a12 = new int[n/2][n/2];
    int [][]a21 = new int[n/2][n/2];
    int [][]a22 = new int[n/2][n/2];
    int [][]b11 = new int[n/2][n/2];
    int [][]b12 = new int[n/2][n/2];
    int [][]b21 = new int[n/2][n/2];
    int [][]b22 = new int[n/2][n/2];

    //将矩阵A分块
    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    a11[i][j] = a[i][j];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    a12[i][j] = a[i][j+n/2];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    a21[i][j] = a[i+n/2][j];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    a22[i][j] = a[i+n/2][j+n/2];
    }
    }

    //将矩阵A分块
    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    b11[i][j] = b[i][j];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    b12[i][j] = b[i][j+n/2];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    b21[i][j] = b[i+n/2][j];
    }
    }

    for (int i = 0; i < n/2; i++) {
    for (int j = 0; j < n/2; j++) {
    b22[i][j] = b[i+n/2][j+n/2];
    }
    }

    //求出各分块的相加与相减的值
    int[][] s1 = del(b12,b22,n/2);
    int[][] s2 = add(a11,a12,n/2);
    int[][] s3 = add(a21,a22,n/2);
    int[][] s4 = del(b21,b11,n/2);
    int[][] s5 = add(a11,a22,n/2);
    int[][] s6 = add(b11,b22,n/2);
    int[][] s7 = del(a12,a22,n/2);
    int[][] s8 = add(b21,b22,n/2);
    int[][] s9 = del(a11,a21,n/2);
    int[][] s10 = add(b11,b12,n/2);

    //求出该运算中的7次乘法

    int[][] M1 = flag(a11,s1,n/2);
    int[][] M2 = flag(s2,b22,n/2);
    int[][] M3 = flag(s3,b11,n/2);
    int[][] M4 = flag(a22,s4,n/2);
    int[][] M5 = flag(s5,s6,n/2);
    int[][] M6 = flag(s7,s8,n/2);
    int[][] M7 = flag(s9,s10,n/2);


    //做最后的加减
    int[][] C11 = add(del(add(M5,M4,n/2),M2,n/2),M6,n/2);
    int[][] C12 = add(M1,M2,n/2);
    int[][] C21 = add(M3,M4,n/2);
    int[][] C22 = del(del(add(M5,M1,n/2),M3,n/2),M7,n/2);

    for(int i = 0; i < n; i++)
    for(int j = 0; j < n; j++) {
    if(i < n/2) {
    if(j < n/2){
    result[i][j] = C11[i][j];
    }else{
    result[i][j] = C12[i][j-n/2];
    }
    }else {
    if(j < n/2){
    result[i][j] = C21[i-n/2][j];
    }else{
    result[i][j] = C22[i-n/2][j-n/2];
    }
    }
    }

    return result;
    }

    private static int[][] add(int[][] a, int[][] b, int n) {
    int[][] result = new int[n][n];
    for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) {
    result[i][j] = a[i][j] + b[i][j];
    }
    }
    return result;
    }

    private static int[][] del(int[][] a, int[][] b, int n) {
    int[][] result = new int[n][n];
    for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) {
    result[i][j] = a[i][j] - b[i][j];
    }
    }
    return result;
    }

    }

  • 相关阅读:
    Visual C# 2008+SQL Server 2005 数据库与网络开发 12.4 自定义控件
    Visual C# 2008+SQL Server 2005 数据库与网络开发 13.1 菜单和菜单事件的创建
    Visual C# 2008+SQL Server 2005 数据库与网络开发 11.6 小结
    vs2005部署报表服务器项目老提示输入用户名密码解决办法
    Excel 文本处理常用函数
    使用APMServ时出现“1、Apache启动失败,请检查相关配置。√MySQL5.1已启动。”错误的终极解决办法:
    <img> 标签的border等属性尽量少用
    时间相减
    全面介绍 Netstat命令的使用技巧!
    apmserver中 mysql的root密码设定
  • 原文地址:https://www.cnblogs.com/shuaiyongyong/p/7304963.html
Copyright © 2011-2022 走看看