NX二次开发——矩形排料5(基于最低水平线+遗传算法排料策略实现)

本文主要是介绍NX二次开发——矩形排料5(基于最低水平线+遗传算法排料策略实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、概述

二、知识回顾

2.1适应度函数的确定

2.2基因编码

2.3遗传算法复制(选择)

2.4遗传算法交叉操作        通过交叉操作可以增加种群个体的多样性,既可以产生更多的优秀解。下面通过顺序编码方法进行改进(网上有很多方法)。注意这里直接用顺序编码方式会产生非法子代,不是结果不好,本文采取整数编码。

2.5遗传算法变异操作        从遗传算法的角度来看,解的进化主要是靠选择机制和交叉策略来完成,变异只是产生新个体的辅助方法,目的在于提高算法的局部搜索能力,避免陷入早熟。通过交叉算子和变异算子的相互配合,共同完成对搜索空间的全局搜索和局部搜索,从而使遗传算法能够良性的搜索以完成最优化问题的寻优过程,变异概率一般不能太大,本次取为0.05左右。

2.5.1位置交换变异

2.5.2旋转变异(基因正负号变化)

三、所用函数代码与运行结果

3.1所用函数代码

3.2运行结果

3.3结果分析


一、概述

        本文前三篇对矩形排料的理论知识已经做出了讲解,第四篇基于最低水平线搜索策略已经实现了NX基于最低水平线排料,这篇主要详细的记录一下基于最低水平线+遗传算法排料策略实现。

二、知识回顾

2.1适应度函数的确定

        上一篇矩形排料3已经对适应度函数进行了认识,这里我进行简单的叙述。参考“下台阶算法”提出了以板材利用率的大小表示适应度函数值的大小,板材利用率越高,适应度函数值越大,定义如下:

/******************************************************************************************
double			ratio         板材的利用率(适应度函数值)
double			usedArea	  需要排样矩形件的面积总和(*100单位转化)
double			width		  板材宽度
double			maxHigh       板材排料后最大使用高度,不包括使用完整后的板材
int				symbol		  板料个数标识
******************************************************************************************/
ratio = (usedArea * 100.0) / (width * (maxHigh + (symbol - 1)));
2.2基因编码

        用遗传算法解决实际问题时,必需先确定染色体的编码方法。编码就是将问题的解用一种代码来表示,从而将问题的状态空间与遭传算法的码空间相对应,这在很大程度上依赖于所要求解问题的性质。编码是应用遭传算法求解问题时的一个关键步骤 ,编码方法决定了染色体的排列形式,编码的好坏将直接影响到遭传算法的性能和效率。

       由于板材和零件都是矩形,为了使矩形排放时板材的利用率尽可能高,每个零件在具体排放时只能有横放和竖放两种方式。由于每个基因的编码可以为正或负,在本文中统一规定:矩形的编号为正表示矩形横排,即矩形的长边平行于X轴;矩形的编号为负表示矩形竖排,即矩形的长边平行于Y轴 。

        本文采用整数顺序编码方式:先将要排放的每个矩形都统一进行编号,矩形的编号可以为正或负,矩形编号的正负是根据矩形是横放还是竖放来决定的。一个矩形的编号对应一个基因的编码。设要排放的矩形总数为n,n个矩形的编号构成了一个染色体。种群中每条染色体的长度与待排矩形零件总数相同,染色体中每个基因的编码对应相应矩形的编号,所有基因编码的一个排列顺序构成了一个染色体。

        染色体{-2, 1 , 5 , 3 , -4}表示先排 2 号矩形,矩形竖排;接着排 1 号矩形,矩形横排;接下来横排矩形 5 ,然后横排矩形3 ,最后竖排矩形 4 ,如下图1所示:

图1基因编码

2.3遗传算法复制(选择)

        选择操作是为了保证个体的优良特性得以保存并能有效的遗传到下一代中,目的在于保留有效、优良基因,以保证解的质量,提高收敛速度。选择算子,就是依适应度大小,按照某种规则,从当前的种群中选择适应度高的个体遗传到下一代种群中同时淘汰那些适应度值低的个体。本次利用轮盘赌进行选择,其主要实现的思路如下:将种群中所有染色体编号,并根据各自适应值计算按比例分配的概率,依次计算染色体累加概率,产生(0,1)之间随机数,若其最多能大于序列中第m个值,则第m个染色体被随机选择。

  

        个体放入适应度越大,其被选中的概率越高,个体被选择的概率值可以看做在轮盘区间范围,每次轮盘赌算法都会在(0,1)之间产生一个随机数,通过随机数落在轮盘哪个区间来确定被选中个体。注意累计所占比例最后一定是1,如果不为1的话一定计算有误。

2.4遗传算法交叉操作
        通过交叉操作可以增加种群个体的多样性,既可以产生更多的优秀解。下面通过顺序编码方法进行改进(网上有很多方法)。注意这里直接用顺序编码方式会产生非法子代,不是结果不好,本文采取整数编码。

         根据交叉概率p_{i},选择 2个个体 x_{i}x_{j}进行交叉操作。随机选择一个交叉点,在交叉点处,交换 2个个体后半部分得到 2个新的个体x_{i}^{'}x_{j}^{'}, 如下图所示:注意这里数字前的负号只表示矩形是横放还是竖放(在考虑交叉时,看做标记即可)

61354279810

个体x_{i}

97568321410

个体x_{j}

61354321410

个体x_{i}^{'}

97568279810

个体x_{j}^{'}

        很显然,交叉操作可能产生非法个体,即个体中有重复的基因。所以必须对2个新个体的基因进行调整。

**1**找出个体x_{i}^{'}的重复基因1,3,4;个体x_{j}^{'}的重复基因9,7,8;

**2**将1,3,4与9,7,8以及其关联的负号对应交换,得到两个合法的新个体x_{i}^{''}x_{j}^{''},如下所示:

69758321410

个体x_{i}^{''}

13564279810

个体x_{j}^{''}

2.5遗传算法变异操作
        从遗传算法的角度来看,解的进化主要是靠选择机制和交叉策略来完成,变异只是产生新个体的辅助方法,目的在于提高算法的局部搜索能力,避免陷入早熟。通过交叉算子和变异算子的相互配合,共同完成对搜索空间的全局搜索和局部搜索,从而使遗传算法能够良性的搜索以完成最优化问题的寻优过程,变异概率一般不能太大,本次取为0.05左右。
2.5.1位置交换变异

        位置变异的思想是产生[1,n]之间的两个正整数随机数,num1、num2,将两个位置交换。例如:产生的随机数num1=2、num2=6

原染色体:

61354279810

变异后染色体:

62354179810

具体步骤:

**1**在要进行变异的个体中,随机选择2个基因位;

**2**将所选择 2个基因位上的基因值交换,得到 1个新个体。

2.5.2旋转变异(基因正负号变化)

 排列方式变异的思想是:第一步在[1,n]之间产生一个随机数num;第二步在[0,1]之间产生一个随机数 rand,若rand>0.5,刚将其排列方式进行改变,反之,不予理睬,这里所说的变是指排列时矩形是横放还是竖放。

例如:产生的随机数分别为num=5,rand=0.7。

原染色体:

61354279810

变异后染色体:

6135-4279810

三、所用函数代码与运行结果

3.1所用函数代码
//用户定义头文件
#include <atlbase.h>
#include <Windows.h>
#include <vector>
#include <algorithm>
#include "uf.h"
#include "uf_modl.h"
#include "uf_obj.h"
#include "uf_ui.h"
#include "uf_eval.h"
#include "uf_csys.h"
#include <numeric>
#include <algorithm>
#include <random>
#include <stdio.h>
#include <random>
#include <cmath>
#include <numeric>
#include <iostream>
#include <unordered_map>/*****************************************************************************************************
struct:			OutLine1			水平线类结构体
double			Origin				水平线起始x位置
double			End					水平线终止x位置
double			Height				水平线高度
******************************************************************************************************/
struct OutLine1
{double Origin;double End;double Height;// 有参数构造函数OutLine1(const double& origin, const double& end, const double&  height): Origin(origin), End(end), Height(height){}
};//用户定义
/*****************************************************************************************************
Function:		vector<vector<int>>				NXOpen_GA_RectangularLayout		初始化种群
input:			int								ProductsNum						每个染色体的尺寸大小	
input:			int								Population_size					种群大小
return:		vector<vector<int>>				Population						初始化种群后的数据
******************************************************************************************************/
vector<vector<int>> NXOpen_GA_RectangularLayout::Initial_population(int ProductsNum, int Population_size)
{。。。。。。
}/*****************************************************************************************************
Function:		void				initLineList1		初始化水平线集
input:			double				origin				水平线起始x位置
input:			double				end					水平线终止x位置
input:			double				height				水平线高度
input,output:	vector<OutLine1>	lineList			水平线集合
input,output:	OutLine1			lowestLine			最低水平线
input,output:	int					lowestLineIdx		水平线集合中的最低水平线所在位置的ID
******************************************************************************************************/
void NXOpen_GA_RectangularLayout::initLineList1(double origin, double end, double height, vector<OutLine1> &lineList, OutLine1 &lowestLine, int &lowestLineIdx)
{。。。。。。
}/*******************************************************************************************************************
Function:		void				findLowestLine1		找出最低水平线(如果最低水平线不止一条则选取最左边的那条)
input,output:	vector<OutLine1>	lineList			水平线集合
input,output:	OutLine1			lowestLine			最低水平线
input,output:	int					lowestLineIdx		水平线集合中的最低水平线所在位置的ID
*********************************************************************************************************************/
void NXOpen_GA_RectangularLayout::findLowestLine1(vector<OutLine1> lineList, int &lowestLineIdx, OutLine1 &lowestLine)
{。。。。。。
}/*******************************************************************************************************************
Function:		double				lineWidth1			获得放置矩形件的可用长度
input:			int					index				水平线集合中的最低水平线所在位置的ID
input:			OutLine1			lineList			水平线集合
return:		double				availableWidth		返回放置矩形件的可用长度
*********************************************************************************************************************/
double NXOpen_GA_RectangularLayout::lineWidth1(int index, vector<OutLine1> lineList)
{。。。。。。
}/*******************************************************************************************************************
Function:		double				lineHigh1			获得放置矩形件的可用高度
input:			int					index				水平线集合中的最低水平线所在位置的ID
input:			OutLine1			lineList			水平线集合
input,output:	double				containerHigh		板材的高度
return:		double				availableHigh		返回放置矩形件的可用高度
*********************************************************************************************************************/
double NXOpen_GA_RectangularLayout::lineHigh1(int index, vector<OutLine1> lineList, double containerHigh)
{。。。。。。
}/*******************************************************************************************************************
Function:		double				maxlineHigh1		水平线集合中最大的高度
input:			OutLine1			lineList			水平线集合
return:		double				maxlineHigh1		返回放置矩形件的可用高度
*********************************************************************************************************************/
double NXOpen_GA_RectangularLayout::maxlineHigh1(vector<OutLine1> lineList)
{。。。。。。
}/*******************************************************************************************************************************************
Function:		int						searchBySize1			获得候选物品的索引;根据长度搜索矩形件(找出宽度或高度小于目标长度的首个矩形件)
input:			double					targetWidth				放置矩形件的可用长度
input:			vector<vector<double>>	data					要放置的矩形物品列表
return:		int						candidateIdx			返回候选物品的索引
********************************************************************************************************************************************/
int NXOpen_GA_RectangularLayout::searchBySize1(double targetWidth, vector<vector<double>> data)
{。。。。。。
}/*******************************************************************************************************************************************
Function:		int						searchBySize2			获得候选物品的索引;根据长度搜索矩形件(找出宽度或高度小于目标长度的首个矩形件)
input:			double					targetWidth				放置矩形件的可用长度
input:			double					targetHigh				放置矩形件的可用高度
input:			vector<vector<double>>	data					要放置的矩形物品列表
return:		int						candidateIdx			返回候选物品的索引
********************************************************************************************************************************************/
int NXOpen_GA_RectangularLayout::searchBySize2(double targetWidth, double targetHigh, vector<vector<double>> data)
{。。。。。。
}/***********************************************************************************************************************************
Function:		vector<double>		rotateNew1			对于满足长度小于可用长度的矩形件进行旋转放置(宽度放不下时,对矩形件进行旋转)
input:			vector<double>		pro					要放置的矩形件
return:		vector<double>		temp				返回放置矩形件
*************************************************************************************************************************************/
vector<double> NXOpen_GA_RectangularLayout::rotateNew1(vector<double> pro)
{。。。。。。
}/***********************************************************************************************************************************
Function:		void				updateLineList			在水平线集合中更新最低水平线
input:			int					index					水平线集合中的最低水平线所在位置的ID
intput,output:	OutLine1			newLine					新的最低水平线
intput,output:	vector<OutLine1>	lineList				替换新的最低水平线后的水平线集合
*************************************************************************************************************************************/
void NXOpen_GA_RectangularLayout::updateLineList(int index, OutLine1& newLine, vector<OutLine1> &lineList)
{。。。。。。
}/***********************************************************************************************************************************
Function:		void				insertLineList			在水平线集合的最低水平线后插入新的最低水平线
input:			int					index					水平线集合中的最低水平线所在位置的ID
intput,output:	OutLine1			newLine					新的最低水平线
intput,output:	vector<OutLine1>	lineList				替换新的最低水平线后的水平线集合
*************************************************************************************************************************************/
void NXOpen_GA_RectangularLayout::insertLineList(int index, OutLine1& newLine, vector<OutLine1> &lineList)
{。。。。。。
}/**************************************************************************************************
Function:		void					packing			将候选物品排样
input,output:	vector<double>			pro				要放置的矩形件
intput:			int						lowestLineIdx	水平线集合中的最低水平线所在位置的ID
input,output:	OutLine1				lineList		水平线集合
input,output:	vector<vector<double>>	resultPos		排序后的矩形物品列表
intput:			OutLine1				lowestLine		最低水平线
***************************************************************************************************/
void NXOpen_GA_RectangularLayout::packing(vector<double> pro, int &lowestLineIdx, vector<OutLine1> &lineList, vector<vector<double>> &resultPos, OutLine1 lowestLine)
{。。。。。。
}/*****************************************************************************************************************
Function:		void					enhanceLine1	最低水平线宽度小于要排样矩形宽度,提升水平线
intput,output:	int						index			水平线集合中的最低水平线所在位置的ID
input,output:	vector<OutLine1>		lineList		水平线集合
input,output:  OutLine1				lowestLine		最低水平线
input:			double					containerHigh	板料高度
input:			double					containerWidth	板料宽度
input:			double					lingjianjuli	零件距离
input,output:	int						symbol			板料个数标识
******************************************************************************************************************/
void NXOpen_GA_RectangularLayout::enhanceLine1(int &index, vector<OutLine1> &lineList, double containerHigh, double containerWidth, double lingjianjuli, OutLine1 &lowestLine)
{。。。。。。
}/*****************************************************************************************************************
Function:		double					calHighLine1	计算板材的最大使用高度
intput:			vector<OutLine1>		lineList		水平线集合
return:		double					maxHigh			最大高度
******************************************************************************************************************/
double NXOpen_GA_RectangularLayout::calHighLine1(vector<OutLine1> lineList)
{。。。。。。
}/***********************************************************************************************************************************
Function:		double					calUsedRatio1	计算排料矩形件的总面积、板材的最低水平线高度,板材利用率1,板材利用率2
intput,output:	double					usedArea		排样矩形件的面积总和
input:			vector<vector<double>>	resultPos		排样矩形件信息集合
input:			double					width			板材宽度
input:			double					High			板料使用的最小高度,不包括使用完整后的板材
input:			vector<OutLine1>		lineList		水平线集合
input:			int						symbol			板料个数标识
intput,output:	double					ratio			板材利用率
************************************************************************************************************************************/
void NXOpen_GA_RectangularLayout::calUsedRatio1(double &usedArea, vector<vector<double>> resultPos, double width, double High, vector<OutLine1> lineList, int symbol, double &ratio)
{。。。。。。
}/**************************************************************************************************
Function:		void							Packing_main	将候选物品排样主函数(放置个体)
intput,output:	double							usedArea		排样矩形件的面积总和
intput,output:	double							ratio			板材利用率
intput,output:	double							MaxHeight		板料排放物品后达到的最大高度,不包括使用完整后的板材
input:			double							container_height板材高度
input:			double							container_width	板材宽度
input:			vector<vector<double>>			products		要排放的矩形物件集合
return:		vector<vector<vector<double>>>	resultPos		返回将多个板料候选物品排样数据集合
***************************************************************************************************/
vector<vector<vector<double>>> NXOpen_GA_RectangularLayout::Packing_main(double &usedArea,double &ratio, double&MaxHeight, double container_height, double container_width, vector<vector<double>> products)
{。。。。。。
}/*****************************************************************************************************************
Function:		vector<double>			Get_Fitness			获得适应度函数
input:			vector<vector<double>>	products			要排放的矩形物件集合
input:			double					container_height	板材高度
input:			double					container_width		板材宽度
intput:			vector<vector<int>>		Population			种群集合
return:		vector<double>			fitness				当代种群中的适应度函数值大小集合
******************************************************************************************************************/
vector<double> NXOpen_GA_RectangularLayout::Get_Fitness(vector<vector<double>> products, double container_height, double container_width, vector<vector<int>> Population)
{。。。。。。
}/*****************************************************************************************************************
Function:		void					Get_bestAndworst			获得当代最佳和最差个体索引
intput,output:	int						best_idx					当代最佳个体索引
intput,output:	double					worst_idx					当代最差个体索引
input:			vector<double>			fitness						当代适应度函数值集合
******************************************************************************************************************/ 
void NXOpen_GA_RectangularLayout::Get_bestAndworst(int &best_idx, int &worst_idx, vector<double> fitness)
{。。。。。。
}/*****************************************************************************************************************
Function:		void					select			遗传算法选择(复制)操作——轮盘赌思想
intput:		vector<vector<int>>		Population		种群集合
input:			vector<double>			fitness			当代适应度函数值集合
return:		vector<vector<int>>		Population		新的种群集合
******************************************************************************************************************/
vector<vector<int>> NXOpen_GA_RectangularLayout::select(vector<vector<int>> Population, vector<double> fitness)
{。。。。。。
}/*****************************************************************************************************************
Function:		vector<int>				randNum					随机产生1到n的数,一共n个,每个只出现一次
intput:		int 					number					需要产生的个数
return:		vector<vector<int>>		random_combination		产生随机数集合
******************************************************************************************************************/
vector<int> NXOpen_GA_RectangularLayout::randNum(int number)
{。。。。。。
}/*****************************************************************************************************************
Function:		int			getRandomNumber					随机产生一个在[main,max]区间内的正整数
intput:		int 		min								产生随机数的下限
intput:		int			max								产生随机数的上限
return:			int			RandomNumber					返回产生的随机数
******************************************************************************************************************/
int NXOpen_GA_RectangularLayout::getRandomNumber(int min, int max)
{。。。。。。
}/*****************************************************************************************************************
Function:		double			getRandomNumber					随机产生一个在[main,max]区间内的double类型
intput:		double 			min								产生随机数的下限
intput:		double			max								产生随机数的上限
return:			double			RandomNumber					返回产生的随机数
******************************************************************************************************************/
double NXOpen_GA_RectangularLayout::getRandomNumber(double min, double max)
{。。。。。。
}/*****************************************************************************************************************
Function:		void			findDuplicatePositions			查询两个vector中重复的元素并记录下其位置
intput:		vector<int> 	nums1							第一个vector
intput:		vector<int>		nums2							第二个vector
intput,output:	vector<int> 	Element							第一个与第二个重复数字集合
intput,output:	vector<int>		positions						第一个与第二个重复数字位置集合
******************************************************************************************************************/
void NXOpen_GA_RectangularLayout::findDuplicatePositions(vector<int> nums1, vector<int> nums2, vector<int> &Element, vector<int> &positions)
{。。。。。。
}/*****************************************************************************************************************
Function:		void			crossover_inner			两个个体进行交叉操作
intput,output:	vector<int> 	individual1				第一个个体
intput,output:	vector<int> 	individual2				第二个个体
intput:		int				position				要交叉的位置
******************************************************************************************************************/
void NXOpen_GA_RectangularLayout::crossover_inner(vector<int> &individual1, vector<int> &individual2, int position)
{。。。。。。
}/*****************************************************************************************************************
Function:		void					crossover			交叉操作
intput,output:	vector<vector<int>> 	Population			种群集合
intput:		double				 	PC					交叉概率	
******************************************************************************************************************/
void NXOpen_GA_RectangularLayout::crossover(vector<vector<int>> &Population, double PC)
{。。。。。。
}/*****************************************************************************************************************
Function:		void					mutation			变异操作
intput,output:	vector<vector<int>> 	Population			种群集合
intput:		double				 	PM					变异概率
******************************************************************************************************************/
void NXOpen_GA_RectangularLayout::mutation(vector<vector<int>> &Population, double PM)
{
。。。。。。
}/*****************************************************************************
Function:		void		print		打印输出信息
intput,output:	double		d			排样矩形件的面积总和
input:			bool		ISEnter		是否换行
注意:下边重载函数类似
******************************************************************************/
void NXOpen_GA_RectangularLayout::print(const double &d, bool ISEnter)
{char msg[50];sprintf(msg, "%f", d);logical response = 0;UF_UI_is_listing_window_open(&response);if (!response) UF_UI_open_listing_window();UF_UI_write_listing_window(msg);if (ISEnter) UF_UI_write_listing_window("\n");
}void NXOpen_GA_RectangularLayout::print(const char * msg, bool ISEnter)
{logical response = 0;UF_UI_is_listing_window_open(&response);if (!response) UF_UI_open_listing_window();UF_UI_write_listing_window(msg);if (ISEnter) UF_UI_write_listing_window("\n");
}void NXOpen_GA_RectangularLayout::print(const int &i, bool ISEnter)
{char msg[50];sprintf(msg, "%d", i);logical response = 0;UF_UI_is_listing_window_open(&response);if (!response) UF_UI_open_listing_window();UF_UI_write_listing_window(msg);if (ISEnter) UF_UI_write_listing_window("\n");
}
3.2运行结果

基于最低水平线算法+遗传算法的NX矩形排料-CSDN直播具体运行结果看下图所示:

动图太大上传不了,这里有视频链接,大家可以查看。

3.3结果分析

        有3.2运行结果效果图可以看出,遗传算法计算的并不是最好的,只是在有限的时间内进行相对最优的求解,与第四章中的基于最低水平线搜索策略相比总是给人的很差的感觉,这里值得说明的是,本次采用的是最低水平线法,由于相较于基于最低水平线搜索策略其存在弊端,所以避免不了,下一篇我想利用基于最低水平线搜索策略+遗传算法看一看效果。当然这里所说的效果不好只是相对的,因为我主要是思路是做一款支持设置零件间距离修改,和零件与板料间距离,以及超过最大板材高度后可以自动在另一个完整的板材上进行排料,为了效果明显,我故意设置其宽度和高度,实际的应用中并不是这样差,应该可以达到80%左右。

这篇关于NX二次开发——矩形排料5(基于最低水平线+遗传算法排料策略实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/921919

相关文章

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

Conda虚拟环境的复制和迁移的四种方法实现

《Conda虚拟环境的复制和迁移的四种方法实现》本文主要介绍了Conda虚拟环境的复制和迁移的四种方法实现,包括requirements.txt,environment.yml,conda-pack,... 目录在本机复制Conda虚拟环境相同操作系统之间复制环境方法一:requirements.txt方法

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求