Algorithm Base --- 排序

一、选择排序

        首先找到数组中最小的元素,其次将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换),再次在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序,这种方式叫选择排序。

public class Selection {

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    public static void sort (Comparable[] a){
        // 将a[]按升序排列
        int N = a.length; // 数组长度
        for (int i = 0; i < N; i++) {
            //将a[i]和a[i+1..N]中最小的元素交换
            int min = i; // 最小元素的索引
            for (int j = i + 1; j < N; j++)
                if (less(a[j], a[min]))
                    min = j;
            exch(a, i, min);
        }
    }

    private static boolean isSorted(Comparable[] a) {
        for (int i = 1;i < a.length;i++){
            if (less(a[i],a[i - 1]))
                return false;
        }
        return true;
    }

    private static void show(Comparable[] a) {
        for (int i = 0;i < a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        //从标准输入读取字符串,将它们排序并输出
        String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
        sort(a);
        assert isSorted(a);
        show(a);
    }

}


二、插入排序

        有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序(百度百科)

public class Insertion {

    private static boolean isSorted(Comparable[] a) {
        for (int i = 1;i < a.length;i++){
            if (less(a[i],a[i - 1]))
                return false;
        }
        return true;
    }

    private static void show(Comparable[] a) {
        for (int i = 0;i < a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    public static void sort (Comparable[] a){
        // 将a[]按升序排列
        int N = a.length; // 数组长度
        for (int i = 0; i < N; i++) {
            //将a[i]插入到a[i-1]、a[i-2]、a[i-3]...之中
            for (int j = i;j > 0 && less(a[j],a[j-1]);j--){
                exch(a,j,j-1);
            }
        }
    }

    public static void main(String[] args) {
        //从标准输入读取字符串,将它们排序并输出
        String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
        sort(a);
        assert isSorted(a);
        show(a);
    }
}


三、希尔排序

        希尔排序是插入排序的一种又称“缩小增量排序”,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法(百度百科)

package com.arithmetic;

public class Shell {

    private static boolean isSorted(Comparable[] a) {
        for (int i = 1;i < a.length;i++){
            if (less(a[i],a[i - 1]))
                return false;
        }
        return true;
    }

    private static void show(Comparable[] a) {
        for (int i = 0;i < a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    public static void sort (Comparable[] a){
        // 将a[]按升序排列
        int N = a.length; // 数组长度
        int h = 1;
        while (h < N/3)
            h = 3 * h + 1;
        while (h >= 1){
            // 将数组变为h有序
            for (int i = h;i < N;i++){
                // 将a[i]插入到a[i - h],a[i - 2*h],a[i - 3*h]...
                for (int j = i;j >= h && less(a[j],a[j - h]);j -= h)
                    exch(a,j,j - h);
            }
            h = h/3;
        }
    }

    public static void main(String[] args) {
        //从标准输入读取字符串,将它们排序并输出
        String[] a = new String[]{"1","5","6","3","7","10","8","0","9","2","4"};
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

四、归并排序

        归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。(百度百科)

4.1、自顶向下的归并排序

public class Merge {

    private static Comparable[] aux; // 归并所需的辅助数组

    private static boolean isSorted(Comparable[] a) {
        for (int i = 1;i < a.length;i++){
            if (less(a[i],a[i - 1]))
                return false;
        }
        return true;
    }

    private static void show(Comparable[] a) {
        for (int i = 0;i < a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    /*private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }*/

    public static void sort (Comparable[] a){
        aux = new Comparable[a.length]; // 一次性分配空间
        sort(a,0,a.length - 1);
    }

    public static void sort (Comparable[] a,int lo,int hi){
        // 将a[lo ... hi]排列
        if (hi <= lo) return;
        int mid = lo + (hi - lo)/2;
        sort(a,lo,mid); // 将左半边排序
        sort(a,mid + 1,hi) ; // 将右半边排序
        merage(a,lo,mid,hi); // 归并结果
    }

    private static void merage(Comparable[] a, int lo, int mid, int hi) {
        // 将a[lo ... mid] 和 a[mid + 1 ... hi] 归并
        int i = lo,j = mid + 1;
        for (int k = lo;k <= hi;k++) // 将a[lo ... hi]复制到aux[lo ... hi]
            aux[k] = a[k];
        for (int k = lo;k <= hi;k++) // 归并回到a[lo ... hi]
            if (i > mid)
                a[k] = aux[j++];
            else if (j > hi)
                a[k] = aux[i++];
            else if (less(aux[j],aux[i]))
                a[k] = aux[j++];
            else
                a[k] = aux[i++];
    }

    public static void main(String[] args) {
        //从标准输入读取字符串,将它们排序并输出
        String[] a = new String[]{"A","C","E","B","E","D","C","F","G","A","C"};
        sort(a);
        assert isSorted(a);
        show(a);
    }
}

4.2、自底向上的归并排序

public class MergeBU {

    private static Comparable[] aux; // 归并所需的辅助数组

    private static boolean isSorted(Comparable[] a) {
        for (int i = 1;i < a.length;i++){
            if (less(a[i],a[i - 1]))
                return false;
        }
        return true;
    }

    private static void show(Comparable[] a) {
        for (int i = 0;i < a.length;i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    public static void sort (Comparable[] a){
        // 进行lgN次两两归并
        int N = a.length;
        aux = new Comparable[N];
        for (int sz = 1;sz < N;sz = sz + sz) // sz:子数组大小
            for (int lo = 0;lo < N - sz;lo += sz + sz) // lo:子数组大小
                merage(a,lo,lo + sz - 1,Math.min(lo + sz + sz - 1,N - 1));
    }

    private static void merage(Comparable[] a, int lo, int mid, int hi) {
        // 将a[lo ... mid] 和 a[mid + 1 ... hi] 归并
        int i = lo,j = mid + 1;
        for (int k = lo;k <= hi;k++) // 将a[lo ... hi]复制到aux[lo ... hi]
            aux[k] = a[k];
        for (int k = lo;k <= hi;k++) // 归并回到a[lo ... hi]
            if (i > mid)
                a[k] = aux[j++];
            else if (j > hi)
                a[k] = aux[i++];
            else if (less(aux[j],aux[i]))
                a[k] = aux[j++];
            else
                a[k] = aux[i++];
    }

    public static void main(String[] args) {
        //从标准输入读取字符串,将它们排序并输出
        String[] a = new String[]{"A","C","E","B","E","D","C","F","G","A","C"};
        sort(a);
        assert isSorted(a);
        show(a);
    }
}


五、快速排序












NSGA-II (Non-dominated Sorting Genetic Algorithm II) 是一种经典的多目标优化算法,用于解决包含两个或更多冲突优化目标的问题。在Python中,可以使用`deap`库(Distributed Evolutionary Algorithms in Python)来实现NSGA-II,它是一个强大的工具包,支持多种遗传算法和进化策略。 以下是使用`deap`实现NSGA-II的基本步骤: 1. **安装依赖**: 首先需要安装`deap`库,可以使用pip命令: ```bash pip install deap ``` 2. **定义适应度函数**: 定义一个函数来评估解的适应度,这个函数通常接受一组个体作为输入,并返回它们的目标值组合。 3. **初始化种群**: 创建一个种群(Population),每个个体代表一个解决方案,包含目标变量及其对应的编码。 4. **非支配排序**: 根据每个个体的目标值进行排序,分为多个非支配层级(fronts)。 5. **交叉(Crossover)**: 对于每对父代,随机选择一个交叉点进行交叉操作,生成新的后代。 6. **变异(Mutation)**: 为了增加多样性,对新生成的个体进行一些随机变异。 7. **替换(Replacement)**: 将部分旧的非优势个体替换为新产生的个体,通常是保留一定数量的前几层(精英保留策略)。 8. **循环迭代**: 重复步骤4到7直到达到预设的最大迭代次数或满足某个停止条件。 下面是一个简单的Python代码片段展示了如何使用`deap`创建一个基本的NSGA-II实例: ```python from deap import base, creator, tools # ... (其他设置) def fitness_function(individual): # 这里计算适应度,例如处理多个目标函数 return [individual.fitness.weights[0] - individual.fitness.weights[1], individual.fitness.weights[1]], creator.create("Fitness", base.Fitness, weights=(-1.0, 1.0)) # 假设目标是减小第一目标,最大化第二目标 creator.create("Individual", list, fitness=creator.Fitness) toolbox = base.Toolbox() toolbox.register("attr_float", random.uniform, -10, 10) toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, n=problem_dim) toolbox.register("population", tools.initRepeat, list, toolbox.individual) # ... (后续设置如选择、交叉、变异等操作) for _ in range(max_gen): pop = toolbox.population(n=m individuals) # ... (执行进化过程) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值