基于剪枝搜索的分治算法(原理)--找到第k个顺序统计量

来源:互联网 发布:西装定制 知乎 编辑:程序博客网 时间:2024/06/08 17:56

剪枝搜索方法:
基本思想:利用计算问题的特征,剪除不影响问题求解的输入数据,由剩下的输入数据构成一个与原问题形式相同,但规模更小的子问题,递归求解子问题得到原问题的解。
正确性:其正确性由剪枝策略的正确性保证。
算法复杂度分析:
剪枝策略共剪除了λ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();        }    }}
0 0
原创粉丝点击