模拟退火算法(代码)

算法理解-模拟退火 求解函数以求解以下这么一个函数为例子,实现代码为R语言 f(x)=x∗sin(10∗π∗x)+2x∈[−1,2]f(x) = x*sin(10*\pi*x)+2 \\ x \in[-1, 2] 其函数图像为: 求解流程与概念初始解的产生又称做状态产生函数,通常由两部分组成: 1)第一次产生候选解的分布函数。 2)第一次产生候选解不满足条件的情况下,再次产生解的分布函数。 下面采用的是标准 阅读详情

在实际日常中,人们会经常遇到如下问题:在某个给定的定义域X内,求函数f(x)对应的最优值。此处以最小值问题举例(最大值问题可以等价转化成最小值问题),形式化为:

\min_{x \in X}f(x)

如果X是离散有限取值,那么可以通过穷取法获得问题的最优解;如果X连续,但f(x)是凸的,那可以通过梯度下降等方法获得最优解;如果X连续且f(x)非凸,虽说根据已有的近似求解法能够找到问题解,可解是否是最优的还有待考量,很多时候若初始值选择的不好,非常容易陷入局部最优值。

随着日常业务场景的复杂化,第三种问题经常遇见。如何有效地避免局部最优的困扰?模拟退火算法应运而生。其实模拟退火也算是启发式算法的一种,具体学习的是冶金学中金属加热-冷却的过程。由S.Kirkpatrick, C.D.Gelatt和M.P.Vecchi在1983年所发明的,V.Čern在1985年也独立发明此演算法。

不过模拟退火算法到底是如何模拟金属退火的原理?主要是将热力学的理论套用到统计学上,将搜寻空间内每一点想象成空气内的分子;分子的能量,就是它本身的动能;而搜寻空间内的每一点,也像空气分子一样带有“能量”,以表示该点对命题的合适程度。演算法先以搜寻空间内一个任意点作起始:每一步先选择一个“邻居”,然后再计算从现有位置到达“邻居”的概率。若概率大于给定的阈值,则跳转到“邻居”;若概率较小,则停留在原位置不动。

一、模拟退火算法基本思想

模拟退火是启发示算法的一种,也是一种贪心算法,但是它的搜索过程引入了随机因素。在迭代更新可行解时,以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。以下图为例,假定初始解为左边蓝色点A,模拟退火算法会快速搜索到局部最优解B,但在搜索到局部最优解后,不是就此结束,而是会以一定的概率接受到左边的移动。也许经过几次这样的不是局部最优的移动后会到达全局最优点D,于是就跳出了局部最小值。

根据热力学的原理,在温度为T时,出现能量差为dE的降温的概率为p(dE),表示为:

p(dE)=exp(\frac{dE}{kT})

其中k是波尔兹曼常数,值为k=1.3806488\times10^{-23},exp表示自然指数,且dE<0。因此dE/kT < 0,所以p(dE)函数的取值范围是(0, 1)。满足概率密度函数的定义。其实这条公式更直观意思就是:温度越高,出现一次能量差为p(dE)的降温的概率就越大;温度越低,则出现降温的概率就越小。

在实际问题中,这里的“一定的概率”的计算参考了金属冶炼的退火过程。假定当前可行解为x,迭代更新后的解为x_{new},那么对应的“能量差”定义为:

\Delta f = f(x_{new}) - f(x)

其对应的“一定概率”为:

最小值优化:p(\Delta f)=exp(-\frac{\Delta f}{kT})

最大值优化:p(\Delta f)=exp(\frac{\Delta f}{kT})

注:在实际问题中,可以设定k=1,即将参数k与T合并。

二、模拟退火算法描述

  1. 初始化:初始温度T(充分大),温度下限T_{min}(充分小),初始解状态x(是算法迭代的起点),每个T值的迭代次数L;
  2. 对l=1, 2, ..., L做第3至第6步;
  3. 产生新解x_{new}: x_{new}=x+\Delta x;\Delta x为[d_{min}, d_{max}]之间的随机数。
  4. 利计算增量\Delta f = f(x_{new}) - f(x),其中f(x)为优化目标;
  5. 若\Delta f<0(若寻找最大值,\Delta f>0)则接受x_{new}作为新的当前解,否则以概率exp(-\Delta f / (kT))接受x_{new}作为新的当前解;
  6. 如果满足终止条件则输出当前解作为最优解,结束程序。(终止条件通常取为连续若干个新解都没有被接受时终止算法。);
  7. T逐渐减少,且T>T_{min},然后转第2步。

在每个温度T下迭代L次,通过不断改变x来寻找当前温度下的最优值,然后降低温度继续寻找,直到温度达到最低,即选择概率p接近于0。

 

注意:生成新的x后,要判断是否在定义域内,对于超出的x值要抛弃。

三、模拟退火算法的优缺点

模拟退火算法的应用很广泛,可以高效地求解NP完全问题,如货郎担问题(Travelling Salesman Problem,简记为TSP)、最大截问题(Max Cut Problem)、0-1背包问题(Zero One Knapsack Problem)、图着色问题(Graph Colouring Problem)等等,但其参数难以控制,不能保证一次就收敛到最优值,一般需要多次尝试才能获得(大部分情况下还是会陷入局部最优值)。观察模拟退火算法的过程,发现其主要存在如下三个参数问题:

(1) 温度T的初始值设置问题 

温度T的初始值设置是影响模拟退火算法全局搜索性能的重要因素之一、初始温度高,则搜索到全局最优解的可能性大,但因此要花费大量的计算时间;反之,则可节约计算时间,但全局搜索性能可能受到影响。

(2) 退火速度问题,即每个T值的迭代次数

模拟退火算法的全局搜索性能也与退火速度密切相关。一般来说,同一温度下的“充分”搜索是相当必要的,但这也需要计算时间。循环次数增加必定带来计算开销的增大。

(3) 温度管理问题 

温度管理问题也是模拟退火算法难以处理的问题之一。实际应用中,由于必须考虑计算复杂度的切实可行性等问题,常采用如下所示的降温方式:

T=\alpha \times T , \alpha \in (0, 1)

注:为了保证较大的搜索空间,α一般取接近于1的值,如0.95、0.9,代码中设置为0.98。

算法原理转自:https://blog.youkuaiyun.com/huahua19891221/article/details/81737053。

四、案例

TSP问题即旅行商问题,经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应如何选择行进路线,以使总的行程最短。从图论的角度来看,该问题实质是在一个带权完全无向图中,找一个权值最小的哈密尔顿回路。

分析:不同路线构求得的解构成了解空间,算法以一定的概率从解空间中迭代出极值,不同每次放入路线更新方式采用随机调整路线。

五、代码


#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

#define T     3000    //初始温度
#define EPS   1e-8    //终止温度
#define DELTA 0.98    //温度衰减率	

#define LIMIT 1000   //概率选择上限
#define OLOOP 20    //外循环次数
#define ILOOP 100   //内循环次数
#define cN 6       //城市数量
using namespace std;

//定义路线结构体
struct Path
{
	int citys[cN];
	double len;
};

//定义城市点坐标
struct Point
{
	double x, y;
};
typedef struct Point pt;
Path bestPath;        //记录最优路径
       
double w[cN][cN];   //两两城市之间路径长度
int nCase;        //测试次数

double dist(Point A, Point B)
{
	return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

void GetDist(std::vector<pt> p, int n)
{
	for (int i = 0; i < n; i++)
		for (int j = i + 1; j < n; j++)
			w[i][j] = w[j][i] = dist(p[i], p[j]);//A到 B的距离等于B到A的距离。
}



void Init(int n)
{
	nCase = 0;
	bestPath.len = 0;
	for (int i = 0; i < n; i++)
	{
		bestPath.citys[i] = i;//对条线设置编号
		if (i != n - 1)
		{
			printf("%d--->", i);
			bestPath.len += w[i][i + 1];
		}
		else
			printf("%d\n", i);
	}
	printf("\n  path length is : %.4f\n", bestPath.len);
	
}

void Print(Path t, int n)
{
	printf("current path : ");
	for (int i = 0; i < n; i++)
	{
		if (i != n - 1)
			printf("%d-->", t.citys[i]);
		else
			printf("%d\n", t.citys[i]);
	}
	printf("\nThe path length is : %.3lf\n", t.len);
	printf("-----------------------------------\n\n");
}

/*-----------------------------
生成新路线
------------------------------*/
Path GetcNext(Path p, int n)
{
	Path ans = p;
	int x = (int)(n * (rand() / (RAND_MAX + 1.0)));
	int y = (int)(n * (rand() / (RAND_MAX + 1.0)));
	while (x == y)
	{
		x = (int)(n * (rand() / (RAND_MAX + 1.0)));
		y = (int)(n * (rand() / (RAND_MAX + 1.0)));
	}
	swap(ans.citys[x], ans.citys[y]);
	ans.len = 0;
 	for (int i = 0; i < n - 1; i++)
		ans.len += w[ans.citys[i]][ans.citys[i + 1]];
	cout << "nCase = " << nCase << endl;
	Print(ans, n);
	nCase++;
	return ans;
}

void SA(int n)
{
	double t = T;
	srand((unsigned)(time(NULL)));
	Path curPath = bestPath;
	Path newPath = bestPath;
	int P_L = 0;
	int P_F = 0;
	while (1)       //外循环,主要更新参数t,模拟退火过程
	{
		for (int i = 0; i < ILOOP; i++)    //内循环,寻找在一定温度下的最优值
		{
			newPath = GetcNext(curPath, n);
			double dE = newPath.len - curPath.len;
			if (dE < 0)   //当前值小于前一个值(求最小值问题),此时更新接受新值。
			{
				curPath = newPath;
				P_L = 0;
				P_F = 0;
			}
			else//以一定概率接受新值,可能会跳出局部最优解
			{
				double rd = rand() / (RAND_MAX + 1.0);
				
				if (exp(dE / t) > rd && exp(dE / t) < 1)//概率大于随机生成的0-1之间的值时,接受新值。
					curPath = newPath;
				P_L++;
			}
			if (P_L > LIMIT)//终止条件
			{
				P_F++;
				break;
			}
		}
		if (curPath.len < bestPath.len)
			bestPath = curPath;
		if (P_F > OLOOP || t < EPS)
			break;
		t *= DELTA;//以一定速率更新温度
	}
}

int main(int argc, const char * argv[]) {

	
	ifstream  f_data("C:/Users/91324/Desktop/Tsp.data");
	std::vector<pt> city_pt;
	city_pt.clear();
	string data = "";

	if (f_data.fail())//文件打开失败:返回0  
	{
		std::cout << "Open file faild!" << std::endl;
		return 0;
	}

	getline(f_data, data);
	int n = atoi(data.c_str());

	while (getline(f_data, data))
	{
		int pos=data.find(" ");
		pt c_pt;
		string x_str = data.substr(0, pos);
		c_pt.x = atof(x_str.c_str());
		string y_str = data.substr(pos+1, pos);
		c_pt.y = atof(y_str.c_str());
		city_pt.push_back(c_pt);

	}


	GetDist(city_pt, n);
	Init(n);
	SA(n);
	Print(bestPath, n);
	printf("Total test times is : %d\n", nCase);
	system("pause");
	return 0;
}

 

模拟退火算法详细讲解(含实例python代码) 模拟退火算法详细讲解(含实例python代码)(一)模拟退火算法简介三级目录(二)模拟退火算法原理(1)基本思想(2)算法步骤(3)参数控制(三)实例分析 最近老师要求做模拟退火算法实验,看了很多博客之后感觉还是不太清楚,最后问了老师之后才搞明白。想把自己的理解写下来,帮助大家更好的理解。本篇文章是在另一篇博客的基础上加了一下自己的理解,然后又把我们在实验中的实例写下来,还有参考代码。希望大家看了之后能够加深对模拟退火算法的理解。 另一篇博客链接: 深度学习 — 模拟退火算法详解. (一)模拟退火算法简介 阅读详情

相关推荐

模拟退火算法解决旅行商问题(附python代码)

一、算法思路 1、模拟退火算法思路 模拟退火算法在每次计算后得到一个新解,若新解比当前解更好,则直接接受该情况以及新解,若新解比当前解更差,则以一定的概率接受新解,且这个概率随着时间的推移逐渐降低,直至达到温度下限。这样做使得搜索可能跳出局部最优解,达到全局最优解。 2、利用模拟退火算法(SA)解决旅行商问题。 在模拟退火过程中,每次迭代都随机选取当前路径中的一段子路径进行翻转,得到新的路径,并计算新路径得到的总距离,接着根据Metropolis准则判断是否接受新的路径,...

毛毛的博客 5313

consplan r语言_模拟退火算法实现:求解中国31个城市TSP问题

最近在学习玻尔兹曼机,里面用到了模拟退火算法,经过一天的实验,总算顺利完成,本文打算记录这一过程,以作备忘。本文内容如下:1、实验环境2、算法原理简介3、TSP案例代码实现4、运行结果解析5、算法的优缺点分析6、关于模拟退火算法改进的一些想法一、实验环境编程语言:R(R语言中求解模拟退火算法的函数有optim,sann等,其中sann在ConsPlan包中,本文基于模拟退火算法原理自行编写)使用数...

weixin_39972264的博客 1194

数学建模之模拟退火算法(含matlab代码)

目录前言模拟退火算法简介算法主体概括算法难点各个变量设置算法总结问题和代码问题数据matlab程序结果展示 前言 本文以面向数学建模的同学为主,不适合想要深入研究此算法的同学,不涉及过多专业知识,尽量让大家在短时间内快速了解这个算法的大体内容,并能用matlab编程加以实现,有时间的话可以自己把代码敲一遍,代码关键部分都有注释,对自己的matlab编程能力还是有一定帮助的,没有时间的话,我也在文中介绍了哪些是可以直接套用的,哪些是需要依据具体问题修改的,有任何疑问,欢迎留言 模拟退火算法 简介 模拟退火算法

jjb-coder的博客 9423

详解模拟退火算法(含MATLAB代码)

目录 1. 什么是智能优化算法 2. 常用的智能优化算法 3. 智能优化算法的特点 二、模拟退火算法 1. 简介 2.算法思想及步骤 三、MATLAB代码 例1. 求解函数的最小值问题 例2. 旅行商(TSP)问题 1. 什么是智能优化算法 智能优化算法又称现代启发式算法,是一种具有全局优化性能、通用性强且适用于并行处理的算法。这种算法一般具有严密的理论依据,...

小草莓的魔法笔记 8万+

R语言中利用模拟退火进行特征筛选

特征筛选是机器学习和数据分析中一个重要的步骤,它可以帮助我们选择最相关或最有价值的特征,以提高模型性能和减少计算成本。通过以上的代码示例,您可以在R语言中应用模拟退火算法进行特征筛选,并根据需要进行相应的修改和调整。特征筛选是机器学习和数据分析中一个重要的步骤,它的目标是从给定的特征集合中选择出最相关或最有价值的特征,以提高模型的性能和减少计算成本。特征筛选问题可以形式化为一个优化问题,即在给定的特征集合中找到一个特征子集,使得某个评估指标(如模型的准确率)达到最大或最小。

TechWhizKid的博客 457

基于Matlab实现模拟退火算法(附上10个案例源码)

基于Matlab实现模拟退火算法(附上10个案例源码)

m0_62143653的博客 3万+

模拟退火算法及其代码

模拟退火算法作为较为简单的智能算法,具有极大的参考意义。 以求解较为简单的y=(x-1)^2的最小值为例(智能算法是数值型解法,虽然我们预先知道其精确值为x=1,y=0) clear clc tic %y=x^2+1-2*x;%求-10到10的最小值 e=0.1^30;L=200000;at=0.99999;T=1; %一般来说循环次数越多越精确。循环次数与e,L,at都有关系。有时候e很大...

bufengzj的博客 2万+

模拟退火算法python代码

变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。(5) 若ΔT0,然后转第2步。(1) 初始化:初始温度T(

Llcm3030zzstj81的博客 595

算法学习之模拟退火算法路径规划(python代码实现)

模拟退火算法路径规划(python代码实现)一、引言二、算法伪代码三、算法流程及代码实现1、地图创建2、初始化路径小结3、计算适应度值 一、引言   机器人控制过程中,路径规划是其中重要的一环。因此本文采用模拟退火算法对机器人移动时的路径进行优化,最终选取出一条最优路径。采用栅格图法为机器人移动的地图进行建模,并根据模拟退火算法机理,在python上仿真实现了最优路径的选取。   本方法与遗传算法有类似之处,对比上一篇博客可以加深理解:算法学习之遗传算法路径规划(python代码实现) 二、算法伪代码   

qq_34942642的博客 9386

关于模拟退火算法的例子

有关于模拟退火算法的源程序及matlab代码实现的具体例子

头歌平台 操作系统课堂练习2.3:系统调用

使用 gdb 调试内核,跟踪到 main 函数入口的方法与之前实训一样。系统运行时,执行的前 3 个系统调用的编号和名字分别是什么?系统运行时,执行的前 3 个系统调用的编号和名字分别是什么?本关卡使用版本 1 内核进行分析,版本 1 内核文件存放在。为了完成本关任务,你需要:跟踪系统调用的发生。此时,系统调用号存放在寄存器 eax 中。

lazbuyaotoutu的博客 2万+

模拟退火算法经典图的代码

        模拟退火算法有一张特别经典的图,用于说明SA算法为何能跳出局部最优解,找到全局最优解。在写论文是必须要有原图和可编辑的原始文件,网上找了好久都没找到代码,在此记录一下。         假定初始解为左边蓝色点A,模拟退火算法...

雾隐雾现的至渝博客 2万+

武汉理工大学数据结构综合实验——连连看游戏综合实践

文章目录实验目的主要仪器设备及耗材一、实验要求二、分析与设计(非线性结构)1.数据结构的设计2.核心算法设计一条直线消子两条直线消子三条直线消子初始化游戏地图搜寻路径提示和重排3.测试用例设计4.测试效果总结 实验目的 (1)线性结构实验目的 调研连连看游戏,了解连连看游戏的功能和规则等 掌握集成开发工具VS2019的使用和C++的基础编程 了解MFC框架 了解线性结构,掌握数组的遍历、消子和胜负判断等算法 了解企业软件开发过程,应用迭代开发思路进行项目开发,养成良好的编程习惯和培养软件工程化思维 .

mo_zhe的博客 7612

模拟退火算法matlab代码

1:maxgen` 表示横轴的范围是从 1 到 `maxgen`,`MAXY` 是纵轴上的数值,`'b-'` 表示使用蓝色的实线连接数据点。disp(best_x)`:** 在命令行窗口输出字符串 "最佳的位置是:",然后输出变量 `best_x` 的值,即找到的最佳解的位置。disp(max_y)`:** 在命令行窗口输出字符串 "此时最优值是:",然后输出变量 `max_y` 的值,即找到的最优解的函数值。`:** 将原来图形上的散点数据清空。`:** 计算新解 `x1` 的函数值,得到 `y1`。

2302_79394843的博客 1831

STM32H743实战(三)-- 时钟系统配置

本文详细讲解了STM32H743时钟系统的配置方法,重点解析了为何选择400MHz而非理论极限480MHz作为稳定运行的主频。通过STM32CubeIDE环境,手把手指导如何从外部晶振配置、电源电压设置到PLL锁相环参数调整,最终实现稳定可靠的400MHz系统时钟,并提供了代码验证与常见问题排查指南。

weixin_29164185的博客 368

【KITTI数据集中Raw_Data数据标定文件中的参数关系解读】

上一节本人将KITTI Odometry数据集中的参数文件进行了解释。本节主要针对一些做融合slam的人,将Raw_Data数据标定文件中的参数按照自己的理解做如下阐述。其中,所讲之处如有错误,欢迎各位批评指正。

weixin_43389152的博客 1527

模拟退火算法python代码_模拟退火算法的三种形式+Python实现

模拟退火有三种具体形式‘fast’:u ~ Uniform(0, 1, size = d)y = sgn(u - 0.5) * T * ((1 + 1/T)**abs(2*u - 1) - 1.0)xc = y * (upper - lower)x_new = x_old + xcc = n * exp(-n * quench)T_new = T0 * exp(-c * k**quench)‘ca...

weixin_39617006的博客 681

突发E层(Es层):短波通信中的“意外惊喜”与“隐形杀手”全解析

本文深入解析了突发E层(Es层)在短波通信中的双重作用,既可能带来超远距离通信的“意外惊喜”,也可能成为通信链路的“隐形杀手”。通过分析Es层的形成机制、时空分布规律及实战应用技巧,帮助通信爱好者与专业人员更好地利用或应对这一电离层现象,提升短波通信的可靠性与效率。

weixin_30443813的博客 827

模拟退火算法(代码可直接运行)

模拟退火算法(SA) 模拟退火是很经典的算法,针对大多数模型、应用,受限于SA运行时间长等特点,已不能直接应用SA,这样的算法值得去改进,我试图找一些缩短运行时间的方法,已经在测试,这里是模拟退火第一篇文章,介绍模拟退火,给出基础代码(经过多次测试,可直接运行)。 参考了https://blog.youkuaiyun.com/qq_34554039/article/details/90294046(该文介绍了...

3W_的博客 3035

C# 上位机内存泄漏排查指南:3 个工具 + 4 个技巧,从 GC 频繁到稳定运行 720 小时

C# 上位机内存泄漏排查的核心是「先定位泄漏存在,再追溯引用根源,最后修复验证通过「Visual Studio 诊断工具(快速定位)+ dotMemory(深度分析)+ PerfView(生产监控)」三个工具的配合,结合「复现场景、排查静态成员+事件、检查非托管资源、GC 日志验证」四个技巧,可高效解决绝大多数泄漏问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 739

【20260309】【亲测可用】【异常】Get https://registry-1.docker.io/v2/: net/http: request canceled

【异常】Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection。

奶爸的编程之路,也就一周冷个三天 2万+

使用15个案例讲解 模拟退火算法 含有代码说明

本文详细介绍了如何在Matlab中实现模拟退火算法,并通过15个具体案例展示了其在各种优化问题中的应用。模拟退火算法是一种有效的全局优化方法,适用于求解复杂的非凸问题。通过Matlab的灵活实现和强大的功能,可以高效地应用模拟退火算法解决实际问题。

qq_46187594的博客 1572

交换机端口模式详解:Access、Hybrid、Trunk

交换机是网络中至关重要的组件之一,用于连接各种设备并启用数据的高效流动。为了更好地管理和控制网络流量,交换机提供了不同的端口模式,其中包括Access、Hybrid和Trunk。本文将深入探讨这三种端口模式,详细解释它们的配置、特性和应用场景,以帮助网络管理员更好地理解和优化网络架构。

网络技术联盟站 4016

【十分钟速成系列】--模拟退火算法(SA)(内含代码)

下图中所示即为在一次温度下,跌代L次,固体能量发生的变化。在该温度下,整个迭代过程中温度不发生变化,能量发生变化,当前一个状态x(n)的能量大于后一个状态x(n+1)的能量时,状态x(n)的解没有状态x(n+1)的解好,所以接受状态x(n+1)。假设开始状态在A,多次迭代之后更新到B的局部最优解,这时发现更新到B时,能力比A要低,则说明接近最优解了,因此百分百转移,状态到达B后,发现下一步能量上升了,如果是梯度下降则是不允许继续向前的,而这里会以一定的概率跳出这个坑,这各概率和当前的状态、能量等都有关系。

zzylalalala的博客 5767

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: C循环读指定路径下的文件
下一篇: jpg转海思nnie所需要的.bgr格式的数据
LiBin1103
博客等级 码龄9年 38粉丝 68原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值