【算法】遗传算法

一、引言

        遗传算法(Genetic Algorithm, GA)是一种模拟生物进化过程的启发式搜索算法,它通过模拟自然选择、遗传、交叉和突变等生物学机制来优化问题的解决方案。遗传算法因其通用性、高效性和鲁棒性,在多个领域中得到了广泛应用,如工程、科研、经济和艺术等。

二、算法原理

遗传算法的核心原理包括以下几个方面:

  • 编码:将问题的解编码为染色体(通常为一串数字或符号序列)。
  • 初始种群:随机生成一组解作为初始种群。
  • 适应度函数:定义一个适应度函数来评估每个个体的性能。
  • 选择:根据适应度选择个体进行繁殖,高适应度的个体有更高的被选择概率。
  • 交叉:选中的个体通过交叉操作生成新的后代,模拟基因重组。
  • 突变:以一定概率随机改变个体的某些基因,增加种群的多样性。
  • 新一代种群:形成新的种群,重复上述过程直到满足终止条件。

三、数据结构

遗传算法中常用的数据结构包括:

  • 染色体:表示问题的解,通常为一串数字或符号序列。
  • 适应度数组:存储每个个体适应度值的数组。
  • 个体(Individual):表示一个解。通常用一个染色体(Chromosome)来表示,染色体由基因(Gene)组成。
  • 种群(Population):由多个个体组成,是算法的基础单元。
  • 适应度函数(Fitness Function):用于评估个体的优劣。
  • 选择策略(Selection Strategy):确定哪些个体会被选择进行繁殖。常见的策略包括轮盘赌选择、锦标赛选择等。
  • 交叉策略(Crossover Strategy):决定如何将两个父母个体的基因组合成子代个体。常见的策略包括单点交叉、两点交叉等。
  • 变异策略(Mutation Strategy):在个体中引入随机变异,以增加种群的多样性。

四、算法使用场景

遗传算法适用于解决以下类型的优化问题:

  • 组合优化问题:如旅行商问题(TSP)、车辆路径问题(VRP)等。

  • 参数优化问题:如神经网络权重优化、机器学习模型参数调优等。

  • 调度问题:如作业调度、任务调度等。
  • 设计问题:如结构设计、网络设计等。
  • 数据挖掘:特征选择、聚类分析。

五、算法实现

  • 初始化种群:随机生成一组个体,每个个体代表一个可能的解。
  • 评估适应度:根据目标函数评估每个个体的适应度。
  • 选择操作:根据适应度选择较优的个体进行繁殖。
  • 交叉操作:将选择出来的个体配对,通过交叉生成新个体。
  • 变异操作:对新个体进行随机变异,以保持种群的多样性。
  • 替代操作:用新生成的个体替代旧种群中的个体,形成新的种群。
  • 终止条件:当达到预定的终止条件(如最大代数或适应度阈值)时,算法停止。
import numpy as npdef initialize_population(pop_size, gene_length):return np.random.randint(2, size=(pop_size, gene_length))def fitness_function(individual):# 示例:适应度函数为个体基因的汉明重量return np.sum(individual)def select(population, fitness_values):# 示例:轮盘赌选择probabilities = fitness_values / np.sum(fitness_values)indices = np.random.choice(range(len(population)), size=len(population), p=probabilities)return population[indices]def crossover(parent1, parent2):# 示例:单点交叉point = np.random.randint(1, len(parent1))child1 = np.concatenate((parent1[:point], parent2[point:]))child2 = np.concatenate((parent2[:point], parent1[point:]))return child1, child2def mutate(individual, mutation_rate):# 示例:基因突变for i in range(len(individual)):if np.random.rand() < mutation_rate:individual[i] = 1 - individual[i]return individualdef genetic_algorithm(population_size, gene_length, num_generations):population = initialize_population(population_size, gene_length)for _ in range(num_generations):fitness_values = np.array([fitness_function(ind) for ind in population])population = select(population, fitness_values)next_generation = []while len(next_generation) < population_size:parent1, parent2 = np.random.choice(population, size=2, replace=False)child1, child2 = crossover(parent1, parent2)child1 = mutate(child1, 0.01)child2 = mutate(child2, 0.01)next_generation.extend([child1, child2])population = np.array(next_generation)best_individual = population[np.argmax(fitness_values)]return best_individual# 运行遗传算法
best_solution = genetic_algorithm(100, 10, 50)
print("Best solution:", best_solution)

六、同类型算法对比

        粒子群优化(PSO):基于个体与群体之间的信息共享,收敛速度较快,但容易陷入局部最优。
        蚁群算法(ACO):模拟蚂蚁觅食行为,适用于路径优化问题,但计算量较大。
        模拟退火(SA):借鉴物理退火过程,适用于大规模问题,容易避免局部最优但计算复杂度较高。

遗传算法与其他优化算法(如粒子群优化、模拟退火、蚁群算法等)相比,具有以下特点:

  • 全局搜索能力强:遗传算法通过模拟自然进化过程,具有较强的全局搜索能力。

  • 鲁棒性:遗传算法对初始种群和参数设置不敏感,具有较强的鲁棒性。

  • 适用于多种优化问题:遗传算法适用于连续、离散及混合类型的优化问题。

  • 编码简单:遗传算法的编码方式较为简单,易于实现。

七、多语言代码实现

Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;class Individual {List<Integer> genes;double fitness;public Individual(int geneLength) {genes = new ArrayList<>(Collections.nCopies(geneLength, 0));Random rand = new Random();for (int i = 0; i < geneLength; i++) {genes.set(i, rand.nextInt(2)); // Binary genes}}public void calculateFitness() {// Example fitness function: sum of genesfitness = genes.stream().mapToInt(Integer::intValue).sum();}
}class GeneticAlgorithm {private List<Individual> population;private int geneLength;private int populationSize;private double mutationRate;private int generations;public GeneticAlgorithm(int geneLength, int populationSize, double mutationRate, int generations) {this.geneLength = geneLength;this.populationSize = populationSize;this.mutationRate = mutationRate;this.generations = generations;population = new ArrayList<>();for (int i = 0; i < populationSize; i++) {population.add(new Individual(geneLength));}}public void evolve() {for (int generation = 0; generation < generations; generation++) {evaluateFitness();List<Individual> newPopulation = new ArrayList<>();while (newPopulation.size() < populationSize) {Individual parent1 = selectParent();Individual parent2 = selectParent();Individual child = crossover(parent1, parent2);mutate(child);newPopulation.add(child);}population = newPopulation;}}private void evaluateFitness() {population.forEach(Individual::calculateFitness);}private Individual selectParent() {// Simple roulette wheel selectiondouble totalFitness = population.stream().mapToDouble(i -> i.fitness).sum();double rand = new Random().nextDouble() * totalFitness;double sum = 0;for (Individual individual : population) {sum += individual.fitness;if (sum >= rand) return individual;}return population.get(population.size() - 1); // Should not reach here}private Individual crossover(Individual parent1, Individual parent2) {Individual child = new Individual(geneLength);int crossoverPoint = new Random().nextInt(geneLength);for (int i = 0; i < geneLength; i++) {child.genes.set(i, i < crossoverPoint ? parent1.genes.get(i) : parent2.genes.get(i));}return child;}private void mutate(Individual individual) {for (int i = 0; i < geneLength; i++) {if (new Random().nextDouble() < mutationRate) {individual.genes.set(i, 1 - individual.genes.get(i));}}}
}

Python

import randomclass Individual:def __init__(self, gene_length):self.genes = [random.randint(0, 1) for _ in range(gene_length)]self.fitness = 0def calculate_fitness(self):self.fitness = sum(self.genes)class GeneticAlgorithm:def __init__(self, gene_length, population_size, mutation_rate, generations):self.gene_length = gene_lengthself.population_size = population_sizeself.mutation_rate = mutation_rateself.generations = generationsself.population = [Individual(gene_length) for _ in range(population_size)]def evolve(self):for _ in range(self.generations):self.evaluate_fitness()new_population = []while len(new_population) < self.population_size:parent1 = self.select_parent()parent2 = self.select_parent()child = self.crossover(parent1, parent2)self.mutate(child)new_population.append(child)self.population = new_populationdef evaluate_fitness(self):for individual in self.population:individual.calculate_fitness()def select_parent(self):total_fitness = sum(individual.fitness for individual in self.population)rand = random.uniform(0, total_fitness)sum_ = 0for individual in self.population:sum_ += individual.fitnessif sum_ >= rand:return individualreturn self.population[-1]def crossover(self, parent1, parent2):crossover_point = random.randint(0, self.gene_length - 1)child = Individual(self.gene_length)child.genes = parent1.genes[:crossover_point] + parent2.genes[crossover_point:]return childdef mutate(self, individual):for i in range(self.gene_length):if random.random() < self.mutation_rate:individual.genes[i] = 1 - individual.genes[i]

C++

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>class Individual {
public:std::vector<int> genes;double fitness;Individual(int geneLength) : genes(geneLength), fitness(0) {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis(0, 1);for (int &gene : genes) {gene = dis(gen);}}void calculateFitness() {fitness = std::accumulate(genes.begin(), genes.end(), 0.0);}
};class GeneticAlgorithm {std::vector<Individual> population;int geneLength;int populationSize;double mutationRate;int generations;public:GeneticAlgorithm(int geneLength, int populationSize, double mutationRate, int generations): geneLength(geneLength), populationSize(populationSize), mutationRate(mutationRate), generations(generations) {for (int i = 0; i < populationSize; ++i) {population.emplace_back(geneLength);}}void evolve() {for (int generation = 0; generation < generations; ++generation) {evaluateFitness();std::vector<Individual> newPopulation;while (newPopulation.size() < populationSize) {Individual parent1 = selectParent();Individual parent2 = selectParent();Individual child = crossover(parent1, parent2);mutate(child);newPopulation.push_back(child);}population = newPopulation;}}private:void evaluateFitness() {for (auto& individual : population) {individual.calculateFitness();}}Individual selectParent() {double totalFitness = 0;for (const auto& individual : population) {totalFitness += individual.fitness;}std::uniform_real_distribution<> dis(0, totalFitness);std::random_device rd;std::mt19937 gen(rd());double rand = dis(gen);double sum = 0;for (const auto& individual : population) {sum += individual.fitness;if (sum >= rand) {return individual;}}return population.back(); // Should not reach here}Individual crossover(const Individual& parent1, const Individual& parent2) {std::uniform_int_distribution<> dis(0, geneLength - 1);std::random_device rd;std::mt19937 gen(rd());int crossoverPoint = dis(gen);Individual child(geneLength);std::copy(parent1.genes.begin(), parent1.genes.begin() + crossoverPoint, child.genes.begin());std::copy(parent2.genes.begin() + crossoverPoint, parent2.genes.end(), child.genes.begin() + crossoverPoint);return child;}void mutate(Individual& individual) {std::uniform_real_distribution<> dis(0, 1);std::random_device rd;std::mt19937 gen(rd());for (int i = 0; i < geneLength; ++i) {if (dis(gen) < mutationRate) {individual.genes[i] = 1 - individual.genes[i];}}}
};

Go

package mainimport ("math/rand""time"
)type Individual struct {Genes   []intFitness float64
}func NewIndividual(geneLength int) *Individual {genes := make([]int, geneLength)for i := range genes {genes[i] = rand.Intn(2)}return &Individual{Genes: genes}
}func (ind *Individual) CalculateFitness() {sum := 0for _, gene := range ind.Genes {sum += gene}ind.Fitness = float64(sum)
}type GeneticAlgorithm struct {Population    []*IndividualGeneLength    intPopulationSize intMutationRate  float64Generations   int
}func NewGeneticAlgorithm(geneLength, populationSize int, mutationRate float64, generations int) *GeneticAlgorithm {population := make([]*Individual, populationSize)for i := 0; i < populationSize; i++ {population[i] = NewIndividual(geneLength)}return &GeneticAlgorithm{Population:   population,GeneLength:   geneLength,PopulationSize: populationSize,MutationRate: mutationRate,Generations:  generations,}
}func (ga *GeneticAlgorithm) Evolve() {for i := 0; i < ga.Generations; i++ {ga.EvaluateFitness()newPopulation := make([]*Individual, ga.PopulationSize)for j := 0; j < ga.PopulationSize; j++ {parent1 := ga.SelectParent()parent2 := ga.SelectParent()child := ga.Crossover(parent1, parent2)ga.Mutate(child)newPopulation[j] = child}ga.Population = newPopulation}
}func (ga *GeneticAlgorithm) EvaluateFitness() {for _, ind := range ga.Population {ind.CalculateFitness()}
}func (ga *GeneticAlgorithm) SelectParent() *Individual {totalFitness := 0.0for _, ind := range ga.Population {totalFitness += ind.Fitness}randValue := rand.Float64() * totalFitnesssum := 0.0for _, ind := range ga.Population {sum += ind.Fitnessif sum >= randValue {return ind}}return ga.Population[len(ga.Population)-1] // Should not reach here
}func (ga *GeneticAlgorithm) Crossover(parent1, parent2 *Individual) *Individual {crossoverPoint := rand.Intn(ga.GeneLength)child := NewIndividual(ga.GeneLength)copy(child.Genes[:crossoverPoint], parent1.Genes[:crossoverPoint])copy(child.Genes[crossoverPoint:], parent2.Genes[crossoverPoint:])return child
}func (ga *GeneticAlgorithm) Mutate(ind *Individual) {for i := range ind.Genes {if rand.Float64() < ga.MutationRate {ind.Genes[i] = 1 - ind.Genes[i]}}
}func main() {rand.Seed(time.Now().UnixNano())ga := NewGeneticAlgorithm(10, 100, 0.01, 50)ga.Evolve()
}

八、应用场景的整个代码框架

用遗传算法进行超参数调优,可构建如下的项目结构:

project/├── main.py├── ga.py├── objective.py├── utils.py├── requirements.txt└── README.md

main.py

from ga import GeneticAlgorithm
from objective import objective_functiondef main():ga = GeneticAlgorithm(objective_function, pop_size=100, gene_length=5)best_solution, best_fitness = ga.run(generations=200)print(f"Optimal parameters: {best_solution}, Maximum fitness: {best_fitness}")if __name__ == '__main__':main()

ga.py

import numpy as np
import randomclass GeneticAlgorithm:def __init__(self, objective_function, pop_size=50, gene_length=10, mutation_rate=0.01):self.objective_function = objective_functionself.pop_size = pop_sizeself.gene_length = gene_lengthself.mutation_rate = mutation_rateself.population = self.initialize_population()def initialize_population(self):return [np.random.rand(self.gene_length) for _ in range(self.pop_size)]def calculate_fitness(self):return [self.objective_function(ind) for ind in self.population]def selection(self, fitness):idx = np.random.choice(range(len(self.population)), size=len(self.population), p=fitness/np.sum(fitness))return [self.population[i] for i in idx]def crossover(self, parent1, parent2):point = random.randint(1, len(parent1)-1)return np.concatenate((parent1[:point], parent2[point:]))def mutate(self, individual):for i in range(len(individual)):if random.random() < self.mutation_rate:individual[i] = random.random()return individualdef run(self, generations):for generation in range(generations):fitness = self.calculate_fitness()self.population = self.selection(fitness)next_population = []while len(next_population) < self.pop_size:parent1, parent2 = random.sample(self.population, 2)child = self.crossover(parent1, parent2)child = self.mutate(child)next_population.append(child)self.population = next_populationbest_individual = self.population[np.argmax(self.calculate_fitness())]return best_individual, self.objective_function(best_individual)

objective.py

def objective_function(x):return -(x[0]**2 + x[1]**2) + 10  # Example objective function

utils.py

import numpy as np
import random
import matplotlib.pyplot as pltdef set_random_seed(seed):"""Set the random seed for reproducibility.Parameters:seed (int): The seed value to use."""random.seed(seed)np.random.seed(seed)def initialize_population(pop_size, gene_length):"""Initialize a population with random values.Parameters:pop_size (int): The number of individuals in the population.gene_length (int): The length of each individual (chromosome).Returns:List[np.ndarray]: A list containing the initialized population."""return [np.random.rand(gene_length) for _ in range(pop_size)]def plot_fitness_progress(fitness_history):"""Plot the progress of fitness over generations.Parameters:fitness_history (List[float]): A list of fitness values for each generation."""plt.figure(figsize=(10, 5))plt.plot(fitness_history, label='Fitness', color='blue')plt.title('Fitness Progress Over Generations')plt.xlabel('Generation')plt.ylabel('Fitness')plt.legend()plt.grid()plt.show()def save_results_to_file(results, filename):"""Save the results to a text file.Parameters:results (dict): The results to save (e.g., best solution, fitness).filename (str): The name of the file where results will be saved."""with open(filename, 'w') as f:for key, value in results.items():

requirements.txt

numpy>=1.21.0
matplotlib>=3.4.0
scikit-learn>=0.24.0  # 如果需要用于机器学习相关的库
pandas>=1.2.0  # 如果你想处理数据集

        遗传算法是一种灵活强大的优化工具,适用于多个领域。通过不断演化和选择,可以找到较优的解。在具体实现时,需综合考虑问题的实际需求,合理设计适应度函数和遗传操作。由于遗传算法的随机性,可能需要多次运行以找到较优解。希望这篇博文能帮助你更好地理解和实现遗传算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/426724.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

esp32核心跑分程序

https://github.com/ochrin/coremark/tree/esp32 最近一直捣腾esp32s3 (Sense) 做微型摄像。过程中发现一款不错的跑分软件&#xff0c;特此记一笔。 其中针对esp32s3各类参数设定&#xff08;用idf.py menuconfig)&#xff0c;做个记录。 CPU Frequency去240MHz&#xff08…

C语言 | Leetcode C语言题解之第413题等差数列划分

题目&#xff1a; 题解&#xff1a; int numberOfArithmeticSlices(int* nums, int numsSize) {if (numsSize 1) {return 0;}int d nums[0] - nums[1], t 0;int ans 0;// 因为等差数列的长度至少为 3&#xff0c;所以可以从 i2 开始枚举for (int i 2; i < numsSize; i…

Java | Leetcode Java题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; class Solution {public String addStrings(String num1, String num2) {int i num1.length() - 1, j num2.length() - 1, add 0;StringBuffer ans new StringBuffer();while (i > 0 || j > 0 || add ! 0) {int x i > 0 ? n…

通用四期ARM架构银河麒麟桌面操作系统V10【安装、配置FTP服务端】

一、操作环境 服务端&#xff1a;银河麒麟桌面操作系统V10SP1 &#xff08;服务端包链接&#xff1a;https://download.csdn.net/download/AirIT/89747026&#xff09; 客户端&#xff1a;银河麒麟桌面操作系统V10SP1 &#xff08;客户端包链接&#xff1a;https://downloa…

keil里sprintf的用法

代码&#xff1a; #include<stdio.h> int main(void) {float i-123.45;char zifu[10];sprintf(zifu,"%f",i);while(1);return 0; } 仿真结果 代码&#xff1a; #include<stdio.h> int main(void) {float i123.45;char zifu[10];sprintf(zifu,"%f…

【网络】传输层协议TCP

TCP协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793定义。TCP在IP&#xff08;Internet Protocol&#xff0c;互联网协议&#xff09;网络层上提供…

LeetCode004-两个有序数组的中位数-最优算法代码讲解

最有帮助的视频讲解 【LeetCode004-两个有序数组的中位数-最优算法代码讲解】 https://www.bilibili.com/video/BV1H5411c7oC/?share_sourcecopy_web&vd_sourceafbacdc02063c57e7a2ef256a4db9d2a 时间复杂度 O ( l o g ( m i n ( m , n ) ) ) O(log(min(m,n))) O(log(min(…

Flask-JWT-Extended登录验证

1. 介绍 """安装:pip install Flask-JWT-Extended创建对象 初始化与app绑定jwt JWTManager(app) # 初始化JWTManager设置 Cookie 的选项:除了设置 cookie 的名称和值之外&#xff0c;你还可以指定其他的选项&#xff0c;例如&#xff1a;过期时间 (max_age)&…

vue之 package.json和package-lock.json

一、package.json 定义了当前项目所需要引用的各个模块&#xff0c;可以手工修改配置&#xff0c;也可以删除后&#xff0c;使用npm init命令重新自动生成。 但是该文件只锁定大版本号&#xff0c;也就是版本号的第一位&#xff0c;所以你会发现两个文件中同一个包的版本号不一…

项目实现:云备份②(文件操作、Json等工具类的实现)

云备份 前言文件操作实用工具类设计文件属性的获取文件的读写操作文件压缩与解压缩的实现文件目录操作 Json 实用工具类设计编译优化 前言 如果有老铁不知道当前项目实现的功能是什么的话&#xff0c;可以先移步这篇文章内容&#xff1a; 云备份项目的介绍 其中介绍了云备份项…

[数据集][目标检测]无人机飞鸟检测数据集VOC+YOLO格式6647张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6647 标注数量(xml文件个数)&#xff1a;6647 标注数量(txt文件个数)&#xff1a;6647 标注…

数据结构与算法——顺序表期末复习五大经典题型

目录 一&#xff1a;顺序表-移除元素 二&#xff1a;顺序表-删除有序数组中的重复项 三&#xff1a;顺序表-合并两个有序数组 四&#xff1a;顺序表-旋转数组 五&#xff1a;顺序表-数组形式的整数加法 一&#xff1a;顺序表-移除元素 题型链接&#xff1a;27. 移除元素 -…

npm切换为淘宝镜像源

要切换 npm 的镜像源&#xff0c;您可以使用以下几种方法&#xff1a; 前言 然而&#xff0c;由于众所周知的网络环境问题&#xff0c;直接使用npm官方源下载依赖包时&#xff0c;常常会遇到速度慢甚至下载失败的情况。因此&#xff0c;使用更稳定、更快速的国内镜像源就显得尤…

【Python】探索Magenta:音乐与艺术的机器智能创作

下班了&#xff0c;今天的苦就先吃到这里。 在人工智能的浪潮中&#xff0c;机器学习技术正逐渐渗透到艺术创作的各个领域。今天&#xff0c;我们来探索一个特别的项目——Magenta&#xff0c;它是由Google Brain团队发起的&#xff0c;旨在使用机器智能生成音乐和艺术。这个项…

实战讲稿:Spring Boot整合MyBatis

文章目录 实战讲稿&#xff1a;Spring Boot整合MyBatis课程目标课程内容1. 创建员工映射器接口1.1 创建子包1.2 创建接口 2. 测试员工映射器接口2.1 自动装配员工映射器2.2 测试按标识符查询员工方法2.3 测试查询全部员工方法2.4 测试插入员工方法2.5 测试更新员工方法2.6 测试…

WAAP解决方案:守护数字时代的安全盾牌

在当今这个数字化、数据驱动的时代&#xff0c;网络安全已成为企业运营中不可或缺的一环。随着Web应用程序和API接口在业务中的广泛应用&#xff0c;其面临的安全威胁也日益复杂多变。为此&#xff0c;WAAP&#xff08;Web Application and API Protection&#xff09;解决方案…

上市公司-客户ESG数据集(dta+xlsx+参考文献)(2009-2023年)

参考《经济问题》中李普玲&#xff08;2024&#xff09;的做法&#xff0c;将供应商与主要客户数据对应起来&#xff0c;并对上市公司及关联上市公司的ESG数据进行匹配&#xff0c;形成“供应商——客户ESG”的数据集&#xff0c;保留客户的销售占比 一、数据介绍 数据名称&am…

ROS和ROS2借助智能大模型的学习和研究方法

机器人相关知识的本身和价值-CSDN博客 知识本身在智能时代毫无价值&#xff0c;需要基于知识应用和创新才有价值。 学历报废并非来自扩招&#xff0c;而是智能模型的快速发展。-CSDN blink-领先的开发者技术社区 2024年中秋&#xff0c;智能模型实力已经如此&#xff0c;但还…

十七,Spring Boot 整合 MyBatis 的详细步骤(两种方式)

十七&#xff0c;Spring Boot 整合 MyBatis 的详细步骤(两种方式) 文章目录 十七&#xff0c;Spring Boot 整合 MyBatis 的详细步骤(两种方式)1. Spring Boot 配置 MyBatis 的详细步骤2. 最后&#xff1a; MyBatis 的官方文档&#xff1a;https://mybatis.p2hp.com/ 关于 MyBa…

宝兰德MCP系列介绍 ①:中间件管理能力全线升级,驱动企业数字化管理效能提升

在企业数字化转型加速与新技术涌现下&#xff0c;中间件作为衔接底层基础设施和上层业务应用的桥梁&#xff0c;应用愈发广泛且关键。但为了有效管理并维护众多类型的中间件&#xff0c;企业需更多专业运维与资源&#xff0c;这大大分散业务焦点并提升成本。因此&#xff0c;优…