基於剪枝搜索的分治算法(原理)--找到第k個順序統計量

剪枝搜索方法:
基本思想:利用計算問題的特徵,剪除不影響問題求解的輸入數據,由剩下的輸入數據構成一個與原問題形式相同,但規模更小的子問題,遞歸求解子問題得到原問題的解。
正確性:其正確性由剪枝策略的正確性保證。
算法複雜度分析:
剪枝策略共剪除了λn個輸入數據,其中n爲問題的規模,則T(n)滿足:T(n)=T((1λ)n)+f(n)λ(0,1)
找最小的第k個數-線性選擇算法
原理:
線性選擇算法描述:
LinearSelect
輸入:
輸出:

線性選擇算法的實現:
TreeMap

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class LinearSelect {
    public static int table[][] = new int[200][5];
    public static int a[]= new int[200];
    public static int b[] = new int[100];
    public static int c[] = new int[200];
    public static int N=300;

    public static void main(String[] args) {
        Random random = new Random(12);
        int nums[] = new int[N];
        int i = 0;
        while (i < N) {
            nums[i] = random.nextInt()%1000;
            table[i / 5][i % 5] = nums[i];
//          System.out.println(nums[i]);
            i++;
        }
        Arrays.sort(nums);
        displayArrays(nums, 30);
        System.out.println("ans :"+nums[N-15]);
        printTable();
        System.out.println();
        System.out.println(new LinearSelect().findk(N,15));
        System.out.println("job done...");
    }

    /*
     * 
     */
    public int findk(int n,int k) {
        if (n<=20) {
            int arrays[]=new int[n];
            int t0=0;
            while (t0<n) {
                 arrays[t0]=table[t0/5][t0%5];
                 t0++;
            }
            Arrays.sort(arrays);
            displayArrays(arrays, 20);
            return arrays[n-k];
        }
        for (int i = 0; i <n/5; i++) {
            Arrays.sort(table[i]);
        }
        printTable();
        int midpoints[]=new int[n/5];
        Map<Integer,Integer> map=new TreeMap<Integer, Integer>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {    
                if (o1==o2) {
                    return 0;
                }else if (o1>o2) {
                    return 1;
                }else {
                    return -1;
                }
            }

        });
        for (int i = 0; i <n/5; i++) {
            map.put(table[i][2],i);
        }
        System.out.println();
        System.out.println(map.values());
        List<Integer> list=new ArrayList<Integer>(map.values());
        int x=0,y=0,z=0;
        int m=list.size()/2;
        int midValues=table[list.get(m)][2];
        System.out.println("m="+list.get(m)+"midValues: "+table[list.get(n/10)][2]+"  "+midValues);
        for (int i = 0; i <m; i++) {
             int row=list.get(i);
             a[x++]=table[row][0];
             a[x++]=table[row][1];
             a[x++]=table[row][2];
             for (int j = 3; j < 5; j++) {
                 if (table[row][j]<midValues) {
                     a[x++]=table[row][j];
                 }else if (table[row][j]>midValues) {
                    c[z++]=table[row][j];
                }else {
                     b[y++]=table[row][j];
                }
            } 
        }
        a[x++]=table[m][0];
        a[x++]=table[m][1];
        b[y++]=table[m][2];
        c[z++]=table[m][3];
        c[z++]=table[m][4];
        for (int i =m+1; i <list.size(); i++) {
             int row=list.get(i); 
             c[z++]=table[row][2];
             c[z++]=table[row][3];
             c[z++]=table[row][4];
             for (int j = 0; j < 2; j++) {
                 if (table[row][j]<midValues) {
                     a[x++]=table[row][j];
                 }else if (table[row][j]>midValues) {
                     c[z++]=table[row][j];
                }else {
                     b[y++]=table[row][j];
                }
            }

        }
        if (z>k) {
            int t0=0;
            int cc[]=new int[z];
            while (t0<z) {
                table[t0/ 5][t0 % 5] =c[t0];
                cc[t0]=c[t0];
                t0++;
            }
            Arrays.sort(cc);
            displayArrays(cc,z>30?30:z);
            while(t0%5!=0){
                table[t0/ 5][t0 % 5] =-999; //數組補零,不影響最大
                t0++;
            }
            return findk(z,k);
        }else if (y+z<k) {
            int t0=0;
            while (t0<x) {
                table[t0/ 5][t0 % 5] =a[t0];
                t0++;
            }
            while(t0%5!=0){
                table[t0/ 5][t0 % 5] =-999; //數組補零,不影響最大
                t0++;
            }
            return findk(x,k-y-z);
        }else {
            return midValues;
        }
    }
    public static void displayArrays(int nums[],int k) {
        int i=1;
        int n=nums.length;
        while (i<k) {
            System.out.print(String.format("%4d", nums[n-i]));
            i++;            
        }
        System.out.println();
    }
    public static void printTable() {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < table.length; j++) {
                System.out.print(String.format("%4d", table[j][i]));
            }
            System.out.println();
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章