专业学习|一文了解并实操自适应大邻域搜索(讲解代码)
一、自适应大邻域搜索概念介绍
自适应大邻域搜索(Adaptive Large Neighborhood Search,ALNS)是一种用于解决组合优化问题的元启发式算法。以下是关于它的详细介绍:
-自适应大领域搜索的核心思想是:破坏解
、修复解
、动态调整权重并选择(自适应)
。
(一) 基本原理
(1)大邻域搜索(LNS)基础
传统的局部搜索算法通常在当前解的小邻域内进行搜索,容易陷入局部最优解。大邻域搜索则通过破坏(destroy)当前解的一部分,生成一个更大的邻域,然后再通过修复(repair)操作得到新的可行解,从而有可能跳出局部最优。
例如,在车辆路径规划问题中,破坏操作可以是移除一些客户节点,修复操作则是将这些移除的节点重新插入到路径中。
与同类算法相比:在邻域搜索算法中,有的算法可以只使用一种邻域,如模拟退火算法,因此它仅仅搜索了解空间的一小部分,找到全局最优的概率较小,它的优势之一是可以避免陷入局部最优;
邻域搜索算法以一个初始解 x xx 为输入,在 x xx 的邻域进行搜索,以寻找可能存在的更优解,每次找到一个更优解,就用它替换当前解,直到达到局部最优解(找不到任何更优解)。该算法被称为最佳改进算法,因为它总是选择邻域中的最佳解。
而有的算法可以使用多种算子,如变邻域搜索算法(VNS),它通过在当前解的多个邻域中寻找更满意的解,能够大大提高算法在解空间的搜索范围,但是它在使用算子时盲目地将每种算子形成的邻域结构都搜索一遍,缺少了一些启发式信息的指导;
而自适应大邻域搜索算法就弥补了这种不足,这种算法根据算子的历史表现与使用次数选择下一次迭代使用的算子,通过算子间的相互竞争来生成当前解的邻域结构,而在这种结构中有很大概率能够找到更好的解;
销毁方法通常包含随机元素,因此每次调用该方法时都会销毁解决方案的不同部分。然后,解 x xx 的邻域 N ( x ) N(x)N(x) 被定义为通过首先应用破坏方法然后应用修复方法可以达到的解集。
(2)自适应机制
ALNS在LNS的基础上引入了自适应机制。它会根据不同的破坏和修复操作在搜索过程中的表现,动态地调整这些操作被选择的概率。表现好的操作在后续搜索中被选择的概率会增加,反之则减少。
具体来说,算法会为每个破坏和修复操作维护一个分数,根据该分数更新操作的权重,进而影响操作被选择的概率。
(二) 主要步骤
(1) 初始化
生成一个初始解。这个初始解可以是通过某种启发式方法得到的,也可以是随机生成的。
初始化各种破坏和修复操作的权重,通常初始权重可以设置为相等。
(2) 迭代搜索
选择操作:根据当前操作的权重,使用某种选择策略(如轮盘赌选择)选择一个破坏操作和一个修复操作。
破坏阶段:使用选择的破坏操作对当前解进行破坏,得到一个部分解。
修复阶段:使用选择的修复操作对部分解进行修复,得到一个新的可行解。
接受准则:根据一定的接受准则(如模拟退火中的Metropolis准则)决定是否接受这个新解。如果接受,则将新解作为当前解;否则,保持当前解不变。
更新操作分数和权重:根据新解的质量,更新所使用的破坏和修复操作的分数,然后根据分数更新操作的权重。
(3) 终止条件
当满足一定的终止条件(如达到最大迭代次数、运行时间超过限制等)时,算法停止,输出当前找到的最优解。
1. 生成初始解,当前解X0 = 初始解,最优解X1 = X02. 重复以下步骤进行迭代直到停止准则2.1 根据算子权重选择破坏与修复算子,并更新算子使用次数2.2 破坏算子和修复算子依次对当前解操作得到新解X22.3 更新当前解 - 如f(X2) < f(X0),则X0 = X2- 如f(X2) > f(X0),则以一定的概率接受该解作为当前解2.4 更新最优解 - 如f(X2) < f(X1),则X1 = X22.5 更新算子的分数2.6 更新算子的权重2.7 重置当前解3. 返回最优解X1
(4)关于破坏算子选择以及修复算子选择说明
(5)关于动态调整权重并选择(自适应过程)的说明
(三)算法评析
(1)优点
全局搜索能力强:通过大邻域搜索,能够跳出局部最优,有更大的机会找到全局最优解。
自适应特性:能够根据搜索过程中的反馈动态调整操作的选择概率,提高搜索效率。
灵活性高:可以应用于各种组合优化问题,只需要根据具体问题设计合适的破坏和修复操作。
(2) 缺点
参数调整复杂:算法中有多个参数需要调整,如初始权重、分数更新规则等,参数设置不当可能会影响算法的性能。
计算复杂度高:由于需要进行多次破坏和修复操作,计算量较大,对于大规模问题可能需要较长的运行时间。
(3) 应用领域
ALNS在许多组合优化问题中都有应用,例如:
车辆路径规划问题(VRP):包括带时间窗的VRP、多车辆VRP等。
调度问题:如作业车间调度、项目调度等。
资源分配问题:如护士排班、课程排课等。
二、算法实例
(一)ALNS算法实现34个城市的TSP问题
#以下是python实现的代码。 其中,destroy算子有3个:随机筛选N个城市、删除距离最大的N个城市和随机删#除连续的N个城市;repair算子有2个:随机插入和贪心插入,不过考虑到随机插入的效果大概率比较差,所以#代码中实际只使用了贪心插入。import copy
import time
import random
import numpy as np
import pandas as pd
import os
import math
import foliumclass ALNSSearch():# 计算TSP总距离# 计算TSP总距离@staticmethoddef dis_cal(path, dist_mat):distance = 0for i in range(len(path) - 1):distance += dist_mat[path[i]][path[i + 1]]distance += dist_mat[path[-1]][path[0]]return distance# 随机删除N个城市@staticmethoddef random_destroy(x, destroy_city_cnt):new_x = copy.deepcopy(x)removed_cities = []# 随机选择N个城市,并删除removed_index = random.sample(range(0, len(x)), destroy_city_cnt)for i in removed_index:removed_cities.append(new_x[i])x.remove(new_x[i])return removed_cities# 删除距离最大的N个城市@staticmethoddef max_n_destroy(x, destroy_city_cnt):new_x = copy.deepcopy(x)removed_cities = []# 计算顺序距离并排序dis = []for i in range(len(new_x) - 1):dis.append(dist_mat[new_x[i]][new_x[i + 1]])dis.append(dist_mat[new_x[-1]][new_x[0]])sorted_index = np.argsort(np.array(dis))# 删除最大的N个城市for i in range(destroy_city_cnt):removed_cities.append(new_x[sorted_index[-1 - i]])x.remove(new_x[sorted_index[-1 - i]])return removed_cities# 随机删除连续的N个城市@staticmethoddef continue_n_destroy(x, destroy_city_cnt):new_x = copy.deepcopy(x)removed_cities = []# 随机选择N个城市,并删除removed_index = random.sample(range(0, len(x) - destroy_city_cnt), 1)[0]for i in range(removed_index + destroy_city_cnt, removed_index, -1):removed_cities.append(new_x[i])x.remove(new_x[i])return removed_cities# destroy操作def destroy(self, flag, x, destroy_city_cnt):# 三个destroy算子,第一个是随机删除N个城市,第二个是删除距离最大的N个城市,第三个是随机删除连续的N个城市removed_cities = []if flag == 0:# 随机删除N个城市removed_cities = self.random_destroy(x, destroy_city_cnt)elif flag == 1:# 删除距离最大的N个城市removed_cities = self.max_n_destroy(x, destroy_city_cnt)elif flag == 2:# 随机删除连续的N个城市removed_cities = self.continue_n_destroy(x, destroy_city_cnt)return removed_cities# 随机插入def random_insert(x, removed_cities):insert_index = random.sample(range(0, len(x)), len(removed_cities))for i in range(len(insert_index)):x.insert(insert_index[i], removed_cities[i])# 贪心插入def greedy_insert(self, x, removed_cities):dis = float('inf')insert_index = -1for i in range(len(removed_cities)):# 寻找插入后的最小总距离for j in range(len(x) + 1):new_x = copy.deepcopy(x)new_x.insert(j, removed_cities[i])if self.dis_cal(new_x, dist_mat) < dis:dis = self.dis_cal(new_x, dist_mat)insert_index = j# 最小位置处插入x.insert(insert_index, removed_cities[i])dis = float('inf')# repair操作def repair(self, flag, x, removed_cities):# 两个repair算子,第一个是随机插入,第二个贪心插入if flag == 0:self.random_insert(x, removed_cities)elif flag == 1:self.greedy_insert(x, removed_cities)# 选择destroy算子def select_and_destroy(self, destroy_w, x, destroy_city_cnt):# 轮盘赌逻辑选择算子prob = destroy_w / np.array(destroy_w).sum()seq = [i for i in range(len(destroy_w))]destroy_operator = np.random.choice(seq, size=1, p=prob)[0]# destroy操作removed_cities = self.destroy(destroy_operator, x, destroy_city_cnt)return removed_cities, destroy_operator# 选择repair算子def select_and_repair(self, repair_w, x, removed_cities):# # 轮盘赌逻辑选择算子prob = repair_w / np.array(repair_w).sum()seq = [i for i in range(len(repair_w))]repair_operator = np.random.choice(seq, size=1, p=prob)[0]# repair操作:此处设定repair_operator=1,即只使用贪心策略self.repair(1, x, removed_cities)return repair_operator# ALNS主程序def calc_by_alns(self, dist_mat):# 模拟退火温度T = 100# 降温速度a = 0.97# destroy的城市数量destroy_city_cnt = int(len(dist_mat) * 0.1)# destroy算子的初始权重destroy_w = [1, 1, 1]# repair算子的初始权重repair_w = [1, 1]# destroy算子的使用次数destroy_cnt = [0, 0, 0]# repair算子的使用次数repair_cnt = [0, 0]# destroy算子的初始得分destroy_score = [1, 1, 1]# repair算子的初始得分repair_score = [1, 1]# destroy和repair的挥发系数lambda_rate = 0.5# 当前解,第一代,贪心策略生成removed_cities = [i for i in range(dist_mat.shape[0])]x = []self.repair(1, x, removed_cities)# 历史最优解,第一代和当前解相同,注意是深拷贝,此后有变化不影响x,也不会因x的变化而被影响history_best_x = copy.deepcopy(x)# 迭代cur_iter = 0max_iter = 100print('cur_iter: {}, best_f: {}, best_x: {}'.format(cur_iter, self.dis_cal(history_best_x, dist_mat),history_best_x))while cur_iter < max_iter:# 生成测试解,即伪代码中的x^ttest_x = copy.deepcopy(x)# destroy算子remove, destroy_operator_index = self.select_and_destroy(destroy_w, test_x, destroy_city_cnt)destroy_cnt[destroy_operator_index] += 1# repair算子repair_operator_index = self.select_and_repair(repair_w, test_x, remove)repair_cnt[repair_operator_index] += 1if self.dis_cal(test_x, dist_mat) <= self.dis_cal(x, dist_mat):# 测试解更优,更新当前解x = copy.deepcopy(test_x)if self.dis_cal(test_x, dist_mat) <= self.dis_cal(history_best_x, dist_mat):# 测试解为历史最优解,更新历史最优解,并设置最高的算子得分history_best_x = copy.deepcopy(test_x)destroy_score[destroy_operator_index] = 1.5repair_score[repair_operator_index] = 1.5else:# 测试解不是历史最优解,但优于当前解,设置第二高的算子得分destroy_score[destroy_operator_index] = 1.2repair_score[repair_operator_index] = 1.2else:if np.random.random() < np.exp((self.dis_cal(x, dist_mat) - self.dis_cal(test_x, dist_mat)) / T):# 当前解优于测试解,但满足模拟退火逻辑,依然更新当前解,设置第三高的算子得分x = copy.deepcopy(test_x)destroy_score[destroy_operator_index] = 0.8repair_score[repair_operator_index] = 0.8else:# 当前解优于测试解,也不满足模拟退火逻辑,不更新当前解,设置最低的算子得分destroy_score[destroy_operator_index] = 0.5repair_score[repair_operator_index] = 0.5# 更新destroy算子的权重destroy_w[destroy_operator_index] = \destroy_w[destroy_operator_index] * lambda_rate + \(1 - lambda_rate) * destroy_score[destroy_operator_index] / destroy_cnt[destroy_operator_index]# 更新repair算子的权重repair_w[repair_operator_index] = \repair_w[repair_operator_index] * lambda_rate + \(1 - lambda_rate) * repair_score[repair_operator_index] / repair_cnt[repair_operator_index]# 降低温度T = a * T# 结束一轮迭代,重置模拟退火初始温度cur_iter += 1print('cur_iter: {}, best_f: {}, best_x: {}'.format(cur_iter, self.dis_cal(history_best_x, dist_mat),history_best_x))# 打印ALNS得到的最优解print(history_best_x)print(self.dis_cal(history_best_x, dist_mat))return history_best_xif __name__ == '__main__':original_cities = [['西宁', 101.74, 36.56],['兰州', 103.73, 36.03],['银川', 106.27, 38.47],['西安', 108.95, 34.27],['郑州', 113.65, 34.76],['济南', 117, 36.65],['石家庄', 114.48, 38.03],['太原', 112.53, 37.87],['呼和浩特', 111.65, 40.82],['北京', 116.407526, 39.90403],['天津', 117.200983, 39.084158],['沈阳', 123.38, 41.8],['长春', 125.35, 43.88],['哈尔滨', 126.63, 45.75],['上海', 121.473701, 31.230416],['杭州', 120.19, 30.26],['南京', 118.78, 32.04],['合肥', 117.27, 31.86],['武汉', 114.31, 30.52],['长沙', 113, 28.21],['南昌', 115.89, 28.68],['福州', 119.3, 26.08],['台北', 121.3, 25.03],['香港', 114.173355, 22.320048],['澳门', 113.54909, 22.198951],['广州', 113.23, 23.16],['海口', 110.35, 20.02],['南宁', 108.33, 22.84],['贵阳', 106.71, 26.57],['重庆', 106.551556, 29.563009],['成都', 104.06, 30.67],['昆明', 102.73, 25.04],['拉萨', 91.11, 29.97],['乌鲁木齐', 87.68, 43.77]]original_cities = pd.DataFrame(original_cities, columns=['城市', '经度', '纬度'])D = original_cities[['经度', '纬度']].values * math.pi / 180city_cnt = len(original_cities)dist_mat = np.zeros((city_cnt, city_cnt))for i in range(city_cnt):for j in range(city_cnt):if i == j:# 相同城市不允许访问dist_mat[i][j] = 1000000else:# 单位:kmdist_mat[i][j] = 6378.14 * math.acos(math.cos(D[i][1]) * math.cos(D[j][1]) * math.cos(D[i][0] - D[j][0]) +math.sin(D[i][1]) * math.sin(D[j][1]))# ALNS求解TSPtime0 = time.time()alns = ALNSSearch()history_best_x = alns.calc_by_alns(dist_mat)print(city_cnt)print('使用ALNS求解TSP,耗时: {} s'.format(time.time() - time0))
#运行代码后可发现,经过不到4s的计算时间,ALNS便可以得到15662.59的解,和全局最优解15614.84之间的#gap仅约0.3%。
(2) Robust Optimization for the Dual Sourcing Inventory Routing Problem in Disaster Relief
import numpy as np
import math
import re
import csv
import random
import copy
import time
import os
# --------------------------- Global Configuration ---------------------------------------removal_operators_list=['shaw','distance','worst','worst_replenishment_time','random']
insertion_operators_list=['greedy','2_regret','shaw']##################################################################################for root, dirs, files in os.walk('./Test_set'):for set_name in files:print(set_name)time_start = time.time()instance = set_nameproblem = base.generate_problem(instance)records = base.Record(removal_operators_list, insertion_operators_list)solution = base.generate_initial_solution(problem)removal_operators = base.Removal_operators(removal_operators_list)insertion_operators = base.Insertion_operators(insertion_operators_list)solution.obj = base.calculate_objective(solution, problem)current_solution = copy.deepcopy(solution)best_solution = copy.deepcopy(solution)time_end = time.time()time_cost = time_end - time_startrecords.initial_generator_time_cost = time_costtime_start = time.time()iteration_num = 0iteration_counter = 0segment_counter = 0while time_cost <= 3600:if problem.temperature <= 0.01:breakif iteration_counter >= problem.segments_capacity:segment_counter += 1iteration_counter = 0for i in removal_operators_list:records.removal_operator_score_record[i].append(removal_operators.removal_operator_score[i])records.removal_operator_weights_record[i].append(removal_operators.removal_operator_weight[i])records.removal_operator_times_record[i].append(removal_operators.removal_operator_times[i])for i in insertion_operators_list:records.insertion_operator_score_record[i].append(insertion_operators.insertion_operator_score[i])records.insertion_operator_weights_record[i].append(insertion_operators.insertion_operator_weight[i])records.insertion_operator_times_record[i].append(insertion_operators.insertion_operator_times[i])removal_operators.update_weight(removal_operators_list,problem)insertion_operators.update_weight(insertion_operators_list,problem)for i in removal_operators_list:removal_operators.removal_operator_score[i] = 0removal_operators.removal_operator_times[i] = 0for i in insertion_operators_list:insertion_operators.insertion_operator_score[i] = 0insertion_operators.insertion_operator_times[i] = 0best_solution, current_solution = base.do_2opt(best_solution, current_solution, problem)solution = copy.deepcopy(current_solution)selected_removal_operator = removal_operators.select(removal_operators_list)selected_insertion_operator = insertion_operators.select(insertion_operators_list)removal_operators.removal_operator_times[selected_removal_operator] +=1insertion_operators.insertion_operator_times[selected_insertion_operator] +=1sub_time_start = time.time()sub_time_cost = sub_time_start - time_endbase.do_remove(selected_removal_operator, solution, problem)sub_time_end = time.time()sub_time_cost = sub_time_end - sub_time_startsub_time_start = sub_time_endbase.do_insert(selected_insertion_operator, solution, problem)sub_time_end = time.time()sub_time_cost = sub_time_end - sub_time_startsub_time_start = sub_time_endrecords.best_solution_obj_record.append(best_solution.obj)if solution.obj < current_solution.obj:if solution.obj < best_solution.obj:removal_operators.removal_operator_score[selected_removal_operator] += problem.score_factor_1insertion_operators.insertion_operator_score[selected_insertion_operator] += problem.score_factor_1current_solution = copy.deepcopy(solution)best_solution = copy.deepcopy(solution)current_solution = copy.deepcopy(solution)records.best_solution_obj_record[iteration_num] = best_solution.objsegment_counter = 0print('get best solution= ', best_solution.obj)records.best_solution_update_iteration_num.append(iteration_num)else:removal_operators.removal_operator_score[selected_removal_operator] += problem.score_factor_2insertion_operators.insertion_operator_score[selected_insertion_operator] += problem.score_factor_2current_solution = copy.deepcopy(solution)elif random.random() < math.exp(-(solution.obj - current_solution.obj)/problem.temperature):removal_operators.removal_operator_score[selected_removal_operator] += problem.score_factor_3insertion_operators.insertion_operator_score[selected_insertion_operator] += problem.score_factor_3current_solution = copy.deepcopy(solution)iteration_num += 1iteration_counter += 1time_end = time.time()time_cost = time_end - time_startif time_cost >= 1200 and iteration_num <= 3000/3:problem.cooling_rate = (0.01/problem.temperature) ** (1/iteration_num)if time_cost >= 2400 and iteration_num <= 3000/2:problem.cooling_rate = (0.01/problem.temperature) ** (1/(iteration_num/2))problem.temperature = problem.temperature*problem.cooling_rateprint('iteration '+ str(iteration_num)+' finished!')print(problem.instance_name,' has finished!')with open('Data.csv', 'a', newline='', encoding="ANSI") as f_out:csv.writer(f_out, delimiter=',').writerow([set_name, best_solution.obj,time_cost])print(problem.instance_name, ' has finished!')
三、基础知识介绍
(一)轮盘赌是什么?
来源:Evolutionary Computing: 遗传算法_轮盘赌选择(转载) - 柠檬雨 - 博客园
参考引用(它山之石)
「1」https://zhuanlan.zhihu.com/p/353562821
「2」元启发式算法详解:(自适应)大邻域搜索算法((A)LNS)-CSDN博客
「3」https://zhuanlan.zhihu.com/p/102298240
相关文章:
专业学习|一文了解并实操自适应大邻域搜索(讲解代码)
一、自适应大邻域搜索概念介绍 自适应大邻域搜索(Adaptive Large Neighborhood Search,ALNS)是一种用于解决组合优化问题的元启发式算法。以下是关于它的详细介绍: -自适应大领域搜索的核心思想是:破坏解、修复解、动…...
Redis --- 使用zset处理排行榜和计数问题
在处理计数业务时,我们一般会使用一个数据结构,既是集合又可以保证唯一性,所以我们会选择Redis中的set集合: 业务逻辑: 用户点击点赞按钮,需要再set集合内判断是否已点赞,未点赞则需要将点赞数1…...
排序算法——快速排序
代码仓库: 1037827920/AlgorithmZoo 快速排序 算法步骤 选择基准元素,从数组中选择一个元素作为基准,通常选择方式有: 第一个元素最后一个元素中间元素随机选择 分区操作,将数组元素根据基准分为两部分,…...
有用的sql链接
『SQL』常考面试题(2——窗口函数)_sql的窗口函数面试题-CSDN博客 史上最强sql计算用户次日留存率详解(通用版)及相关常用函数 -2020.06.10 - 知乎 (zhihu.com) 1280. 学生们参加各科测试的次数 - 力扣(LeetCode&…...
手写MVVM框架-构建虚拟dom树
MVVM的核心之一就是虚拟dom树,我们这一章节就先构建一个虚拟dom树 首先我们需要创建一个VNode的类 // 当前类的位置是src/vnode/index.js export default class VNode{constructor(tag, // 标签名称(英文大写)ele, // 对应真实节点children,…...
C++单例模式
单例模式是一种设计模式,它保证一个类只有一个对象。因此单例模式要私有化构造函数,禁用拷贝构造以及赋值重载。同时还要提供一个静态成员函数获取单例对象。 单例模式有两种实现方式:饿汉模式和懒汉模式 饿汉模式:创建静态单例…...
SQL入门到精通 理论+实战 -- 在 MySQL 中学习SQL语言
目录 一、环境准备 1、MySQL 8.0 和 Navicat 下载安装 2、准备好的表和数据文件: 二、SQL语言简述 1、数据库基础概念 2、什么是SQL 3、SQL的分类 4、SQL通用语法 三、DDL(Data Definition Language):数据定义语言 1、操…...
RabbitMQ 可靠性投递
文章目录 前言一、RabbitMQ自带机制1、生产者发送消息注意1.1、事务(Transactions)1.2、发布确认(Publisher Confirms)1.2.1、同步1.2.2、异步 2、消息路由机制2.1、使用备份交换机(Alternate Exchanges)2.…...
Java常见的技术场景面试题
一、单点登录这块怎么实现的? 单点登录概述 单点登录:Single Sign On(简称SSO),只需要登录一次,就可以访问所有信任的应用系统 在以前的时候,一般我们就单系统,所有的功能都在同一个系统上。…...
使用 Postman 进行 API 测试:从入门到精通
使用 Postman 进行 API 测试:从入门到精通 使用 Postman 进行 API 测试:从入门到精通一、什么是 API 测试?二、Postman 简介三、环境搭建四、API 测试流程1. 收集 API 文档2. 发送基本请求示例:发送 GET 请求示例代码(…...
用python实现进度条
前言 在Python中,可以使用多种方式实现进度条。以下是几种常见的进度条格式的实现方法: 1. 使用 tqdm 库 tqdm 是一个非常流行的库,可以轻松地在循环中显示进度条。 from tqdm import tqdm import time# 示例:简单的进度条 fo…...
android 自定义通话录音
在 Android 开发中,实现通话录音功能通常涉及到对系统通话的拦截和录音。由于通话录音涉及到用户隐私和安全性,Android 系统对此有严格的限制和要求。在 Android 10(API 级别 29)及以上版本中,直接访问通话录音功能变得…...
WebSocket——环境搭建与多环境配置
一、前言:为什么要使用多环境配置? 在开发过程中,我们通常会遇到多个不同的环境,比如开发环境(Dev)、测试环境(Test)、生产环境(Prod)等。每个环境的配置和需…...
【自动化办公】批量图片PDF自定义指定多个区域识别重命名,批量识别铁路货物运单区域内容改名,基于WPF和飞桨ocr深度学习模型的解决方案
项目背景介绍 铁路货运企业需要对物流单进行长期存档,以便后续查询和审计。不同的物流单可能包含不同的关键信息,通过自定义指定多个区域进行识别重命名,可以使存档的图片文件名具有统一的规范和明确的含义。比如,将包含货物运单…...
在线教程丨YOLO系列10年更新11个版本,最新模型在目标检测多项任务中达SOTA
YOLO (You Only Look Once) 是计算机视觉领域中最具影响力的实时目标检测算法之一,以其高精度与高效性深受业界青睐,广泛应用于自动驾驶、安防监控、医疗影像等领域。 该模型最早于 2015 年由华盛顿大学研究生 Joseph Redmon 发布,开创了将目…...
c++可变参数详解
目录 引言 库的基本功能 va_start 宏: va_arg 宏 va_end 宏 va_copy 宏 使用 处理可变参数代码 C11可变参数模板 基本概念 sizeof... 运算符 包扩展 引言 在C编程中,处理不确定数量的参数是一个常见的需求。为了支持这种需求,C标准库提供了 &…...
Ubuntu安装VMware17
安装 下载本文的附件,之后执行 sudo chmod x VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle sudo ./VMware-Workstation-Full-17.5.2-23775571.x86_64.bundle安装注意事项: 跳过账户登录的办法:断开网络 可能出现的问题以及解决…...
在Debian 12上安装VNC服务器
不知道什么标题 可以看到这个文章是通过豆包从国外网站copy的,先这样写着好了,具体的我有时间再补充,基本内容都在这里了。 在Debian 12上安装VNC服务器 简介 VNC(Virtual Network Computing,虚拟网络计算…...
设计模式Python版 外观模式
文章目录 前言一、外观模式二、外观模式示例三、抽象外观类四、抽象外观类示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&am…...
Selenium 浏览器操作与使用技巧——详细解析(Java版)
目录 一、浏览器及窗口操作 二、键盘与鼠标操作 三、勾选复选框 四、多层框架/窗口定位 五、操作下拉框 六、上传文件操作 七、处理弹窗与 alert 八、处理动态元素 九、使用 Selenium 进行网站监控 前言 Selenium 是一款非常强大的 Web 自动化测试工具,能够…...
论文解读:《基于TinyML毫米波雷达的座舱检测、定位与分类》
摘要 本文提出了一种实时的座舱检测、定位和分类解决方案,采用毫米波(mmWave)雷达系统芯片(SoC),CapterahCAL60S344-AE,支持微型机器学习(TinyML)。提出了波束距离-多普勒…...
e2studio开发RA2E1(5)----GPIO输入检测
e2studio开发RA2E1.5--GPIO输入检测 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置GPIO口配置按键口配置按键口&Led配置R_IOPORT_PortRead()函数原型R_IOPORT_PinRead()函数原型代码 概述 本篇文章主要介绍如何…...
数据结构:队列篇
图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 文章目录 系列文章目录前言一.队列的概念和结构1.1概念一、动态内存管理优势二、操作效率与安全性…...
idea中git的简单使用
提交,推送直接合并 合到哪个分支就到先切到哪个分支...
Java中的object类
1.Object类是什么? 🟪Object 是 Java 类库中的一个特殊类,也是所有类的父类(超类),位于类继承层次结构的顶端。也就是说,Java 允许把任何类型的对象赋给 Object 类型的变量。 🟦Java里面除了Object类,所有的…...
html2canvas绘制页面并生成图像 下载
1. 简介 html2canvas是一个开源的JavaScript库,它允许开发者在用户的浏览器中直接将HTML元素渲染为画布(Canvas),并生成图像。以下是对html2canvas的详细介绍: 2. 主要功能 html2canvas的主要功能是将网页中的HTML元…...
Certum OV企业型通配符SSL
随着网络攻击手段的不断演变,仅仅依靠HTTP协议已无法满足现代企业对数据安全的需求。SSL证书,特别是经过严格验证的组织验证型SSL证书,成为了保护网站数据传输安全、提升用户信任度的标配。 一、Certum OV企业型通配符SSL概述 Certum&#…...
2024年Web前端最新Java进阶(五十五)-Java Lambda表达式入门_eclipse lambda(1),面试必备
对象篇 模块化编程-自研模块加载器 开源分享:【大厂前端面试题解析核心总结学习笔记真实项目实战最新讲解视频】 Arrays.sort(players, sortByName); // 1.3 也可以采用如下形式: Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2))); ??其…...
JVM 四虚拟机栈
虚拟机栈出现的背景 由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多…...
V103开发笔记1-20250113
2025-01-13 一、应用方向分析 应用项目: PCBFLY无人机项目(包括飞控和手持遥控器); 分析移植项目,应用外设资源包括: GPIO, PWM,USART,GPIO模拟I2C/SPI, ADC,DMA,USB等; 二、移植项目的基本…...
Page Assist - 本地Deepseek模型 Web UI 的安装和使用
Page Assist Page Assist是一个开源的Chrome扩展程序,为本地AI模型提供一个直观的交互界面。通过它可以在任何网页上打开侧边栏或Web UI,与自己的AI模型进行对话,获取智能辅助。这种设计不仅方便了用户随时调用AI的能力,还保护了…...
Cookie及Session---笔记
目录 Cookiecookie简介cookiesession的认证方式tpshop完整登录实现-cookie Sessionsession简介session自动管理cookietpshop完整登录实现-sessioncookie和session的区别获取响应结果指定内容 Cookie cookie简介 工程师针对HTTP协议是无连接无状态特性所设计的一种技术&#x…...
【Block总结】DASI,多维特征融合
论文信息 HCF-Net(Hierarchical Context Fusion Network)是一种新提出的深度学习模型,专门用于红外小目标检测。该论文于2024年3月16日发布,作者包括Shibiao Xu、ShuChen Zheng等,主要研究机构为北京邮电大学。该模型…...
LabVIEW的智能电源远程监控系统开发
在工业自动化与测试领域,电源设备的精准控制与远程管理是保障系统稳定运行的核心需求。传统电源管理依赖本地手动操作,存在响应滞后、参数调节效率低、无法实时监控等问题。通过集成工业物联网(IIoT)技术,实现电源设备…...
4.PPT:日月潭景点介绍【18】
目录 NO1、2、3、4 NO5、6、7、8 NO9、10、11、12 表居中或者水平/垂直居中单元格内容居中或者水平/垂直居中 NO1、2、3、4 新建一个空白演示文稿,命名为“PPT.pptx”(“.pptx”为扩展名)新建幻灯片 开始→版式“PPT_素材.doc…...
《迪拜AI展:探寻中东人工智能发展的璀璨新篇》
迪拜:AI 浪潮下的闪耀明珠 迪拜,这座位于阿拉伯半岛东部、波斯湾东南岸的城市,犹如一颗璀璨的明珠,在中东地区散发着独特的魅力。它是阿拉伯联合酋长国的第二大城市,也是迪拜酋长国的首府 ,凭借优越的地理位…...
axios如何利用promise无痛刷新token
目录 需求 需求解析 实现思路 方法一: 方法二: 两种方法对比 实现 封装axios基本骨架 instance.interceptors.response.use拦截实现 问题和优化 如何防止多次刷新token 同时发起两个或以上的请求时,其他接口如何重试 最后完整代…...
R语言 | 使用 ComplexHeatmap 绘制热图,分区并给对角线分区加黑边框
目的:画热图,分区,给对角线分区添加黑色边框 建议直接看0和4。 0. 准备数据 # 安装并加载必要的包 #install.packages("ComplexHeatmap") # 如果尚未安装 library(ComplexHeatmap)# 使用 iris 数据集 #data(iris)# 选择数值列&a…...
TensorFlow 简单的二分类神经网络的训练和应用流程
展示了一个简单的二分类神经网络的训练和应用流程。主要步骤包括: 1. 数据准备与预处理 2. 构建模型 3. 编译模型 4. 训练模型 5. 评估模型 6. 模型应用与部署 加载和应用已训练的模型 1. 数据准备与预处理 在本例中,数据准备是通过两个 Numpy 数…...
蓝桥杯备考:模拟算法之字符串展开
P1098 [NOIP 2007 提高组] 字符串的展开 - 洛谷 | 计算机科学教育新生态 #include <iostream> #include <cctype> #include <algorithm> using namespace std; int p1,p2,p3; string s,ret; void add(char left,char right) {string tmp;for(char ch left1;…...
[创业之路-282]:《产品开发管理-方法.流程.工具 》-1- 优秀研发体系的特征、IPD关注的4个关键要素、IPD体系的7个特点
目录 一、优秀研发体系的特征 二、IPD关注的4个关键要素 1. 组织管理 2. 市场管理 3. 流程管理 4. 产品管理 三、IPD体系的7个特点 1、产品开发是投资行为: 2、基于市场的产品研发: 3、平台化开发,大平台,小产品&#x…...
Node.js 与 PostgreSQL 集成:深入 pg 模块的应用与实践
title: Node.js 与 PostgreSQL 集成:深入 pg 模块的应用与实践 date: 2025/2/5 updated: 2025/2/5 author: cmdragon excerpt: 随着 JavaScript 在服务器端编程中的兴起,Node.js 已成为构建高性能网络应用程序的重要平台。PostgreSQL 则以其强大的特性以及对复杂数据结构的…...
【Uniapp-Vue3】从uniCloud中获取数据
需要先获取数据库对象: let db uniCloud.database(); 获取数据库中数据的方法: db.collection("数据表名称").get(); 所以就可以得到下面的这个模板: let 函数名 async () > { let res await db.collection("数据表名称…...
LeetCode 0090.子集 II:二进制枚举 / 回溯
【LetMeFly】90.子集 II:二进制枚举 / 回溯 力扣题目链接:https://leetcode.cn/problems/subsets-ii/ 给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的 子集(幂集)。 解集 不能 …...
Pytest+selenium UI自动化测试实战实例
今天来说说pytest吧,经过几周的时间学习,有收获也有疑惑,总之最后还是搞个小项目出来证明自己的努力不没有白费。 环境准备 1 确保您已经安装了python3.x 2 配置python3pycharmselenium2开发环境 3 安装pytest库pip install p…...
黑马点评 - 商铺类型缓存练习题(Redis List实现)
首先明确返回值是一个 List<ShopType> 类型那么我们修改此函数并在 TypeService 中声明 queryTypeList 方法,并在其实现类中实现此方法 GetMapping("list")public Result queryTypeList() {return typeService.queryTypeList();}实现此方法首先需要…...
C++ 创建和配置dll与lib库
C简明教程(13)创建和配置dll与lib库_怎样生成lib库和dll库-CSDN博客 C 动态库与静态库详解 一、为什么要引入库的概念 在 C 编程中,随着项目规模的不断扩大,代码量也会急剧增加。如果将所有代码都写在一个源文件中,…...
深度剖析 Veo2 工具:解锁 AI 视频创作新境界
在当下这个 AI 技术日新月异的时代,各种 AI 工具如雨后春笋般涌现,让人目不暇接。今天,我就来给大家好好说道说道谷歌旗下的 Veo2,这可是一款在 AI 视频创作领域相当有分量的工具。好多朋友都在问,Veo2 到底厉害在哪?好不好上手?能在哪些地方派上用场?别着急,今天我就…...
LabVIEW自定义测量参数怎么设置?
以下通过一个温度采集案例,说明在 LabVIEW 中设置自定义测量参数的具体方法: 案例背景 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度,需自定义以下参数: 采样率:1 kHz 输入量程:0~10 V&a…...
JVM执行流程与架构(对应不同版本JDK)
直接上图(对应JDK8以及以后的HotSpot) 这里主要区分说明一下 方法区于 字符串常量池 的位置更迭: 方法区 JDK7 以及之前的版本将方法区存放在堆区域中的 永久代空间,堆的大小由虚拟机参数来控制。 JDK8 以及之后的版本将方法…...