排序算法---ALL的总结

本文介绍了多种经典的排序算法,包括插入排序(直接插入排序、希尔排序)、选择排序(直接选择排序、堆排序)、交换排序(冒泡排序、快速排序)、归并排序及基数排序(计数排序、桶排序)。每种算法都有简洁明了的操作流程描述,帮助读者快速理解其工作原理。

复杂度

一句话解释

PS:点击蓝色标题,可查看详解介绍!

插入排序
1.直接插入排序:

循环每个位置,与前一个的比较,若大则不动;若小,则移动到其前面,继续,直到比前面的一个大。

2.希尔排序:

插入排序的升级版本,是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。

把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,当增量减至1时,整个数据恰被分成一组,算法终止。

选择排序
1.直接选择排序:

在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换……第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,至此选择排序完成。

2.堆排序:

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

交换排序
1.冒泡排序:

每次比较两个相邻的元素,如果它们的顺序错误就把它们预期的顺序交换过来。

2.快速排序:

在数序列中找一个数作为基准数(一般为第一个数),经过比较调整,将所有小于基准数的数放在基准数左边,将所有大于基准数的数放在基准数放在右边。然后分别递归基准数左边和右边的序列。

归并排序:

算法将数组分为两半,对每部分递归的应用归并排序。在两部分都排好序后,对他们进行归并。

基数排序
1.计数排序:

用待排序的数作为计数数组的下标,统计每个数字的个数。然后依次输出即可得到有序序列。

2.桶排序:

如果需要对数据范围在0~n的整数进行排序,我们需要n+1个桶,来记录0~n之间每一个数字出现的次数,我们将桶按照0~n编号,然后将出现的数字放在与编号相等的桶里,统计每个桶内数字的个数,待全部的数字装好,输出桶内数字不为0的桶编号,桶内数字为几输出几次。

NSGA-II(Non-dominated Sorting Genetic Algorithm II)是一种改进的多目标遗传算法。1994年,Kalyanmoy Deb提出了原始的NSGA算法,该算法采用分层的非支配排序机制以及适应度共享机制,但计算复杂度为$O(MN^3)$ [^4]。2000年,Deb和他的学生对其进行改进并提出了NSGA-II,文章于2002年发表,NSGA-II采用快速非支配排序以及拥挤距离的策略,将时间复杂度降低到$O(MN^2)$,因速度及效果上的优势,多年来被作为对比算法 [^4]。 ### 算法基本原理 NSGA-II是以遗传算法为基础,基于Pareto最优概念获得的。它与基本遗传算法的主要区别是在进行选择操作之前对个体进行快速非支配排序,这增大了优秀个体被保留的概率,而选择、交叉、变异等操作与基本遗传算法无异;经过诸多学者研究测试,NSGA-II比传统的多目标遗传算法效果更好 [^1]。 ### 应用场景 在多目标优化问题中,传统算法难以同时优化多个相互冲突的目标,而NSGA-II可基于Pareto最优概念,找到一组折衷的最优解,在工程设计、经济管理、交通运输等领域有广泛应用。例如在工程设计中,需同时考虑产品的性能、成本、重量等多个目标,NSGA-II可帮助工程师找到满足多个目标的最优设计方案;在经济管理中,企业需同时考虑利润最大化和成本最小化,NSGA-II可用于优化企业的生产计划和资源分配。 ```python # 以下是一个简单的NSGA-II算法框架示例,实际应用中需要根据具体问题进行调整 import random import math # 个体类 class Individual: def __init__(self, genes): self.genes = genes self.objectives = [] self.rank = None self.crowding_distance = None self.dominated_count = None self.dominated_solutions = [] # 快速非支配排序 def fast_non_dominated_sort(population): fronts = [[]] for p in population: p.dominated_count = 0 p.dominated_solutions = [] for q in population: if p != q: p_dominates_q = all(p.objectives[i] <= q.objectives[i] for i in range(len(p.objectives))) and \ any(p.objectives[i] < q.objectives[i] for i in range(len(p.objectives))) q_dominates_p = all(q.objectives[i] <= p.objectives[i] for i in range(len(p.objectives))) and \ any(q.objectives[i] < p.objectives[i] for i in range(len(p.objectives))) if p_dominates_q: p.dominated_solutions.append(q) elif q_dominates_p: p.dominated_count += 1 if p.dominated_count == 0: p.rank = 0 fronts[0].append(p) i = 0 while fronts[i]: Q = [] for p in fronts[i]: for q in p.dominated_solutions: q.dominated_count -= 1 if q.dominated_count == 0: q.rank = i + 1 Q.append(q) i += 1 fronts.append(Q) return fronts # 拥挤距离计算 def crowding_distance_assignment(front): n_obj = len(front[0].objectives) l = len(front) for i in range(n_obj): front = sorted(front, key=lambda x: x.objectives[i]) front[0].crowding_distance = math.inf front[-1].crowding_distance = math.inf f_max = front[-1].objectives[i] f_min = front[0].objectives[i] for j in range(1, l - 1): front[j].crowding_distance += (front[j + 1].objectives[i] - front[j - 1].objectives[i]) / (f_max - f_min) # 选择操作 def selection(population): tournament_size = 2 parents = [] for _ in range(len(population)): tournament = random.sample(population, tournament_size) best = min(tournament, key=lambda x: (x.rank, -x.crowding_distance)) parents.append(best) return parents # 示例主函数,这里只是简单框架,未实现具体的目标函数和交叉变异操作 def nsga_ii(population_size, num_generations): population = [Individual([random.random() for _ in range(5)]) for _ in range(population_size)] for gen in range(num_generations): # 计算目标值 for ind in population: ind.objectives = [sum(ind.genes), sum([x**2 for x in ind.genes])] fronts = fast_non_dominated_sort(population) new_population = [] i = 0 while len(new_population) + len(fronts[i]) <= population_size: for ind in fronts[i]: ind.crowding_distance = 0 crowding_distance_assignment(fronts[i]) new_population.extend(fronts[i]) i += 1 fronts[i] = sorted(fronts[i], key=lambda x: (x.rank, -x.crowding_distance)) new_population.extend(fronts[i][:population_size - len(new_population)]) parents = selection(new_population) # 这里需要实现交叉和变异操作 population = new_population return population ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值