求解旅行商问题的三种精确性建模方法,性能差距巨大

news2025/4/18 15:22:34

文章目录

  • 旅行商问题介绍
  • 三种模型对比
  • 求解模型1
    • 决策变量
    • 目标函数
    • 约束条件
    • Python代码
  • 求解模型2
    • 决策变量
    • 目标函数
    • 约束条件
    • Python代码
  • 求解模型3
    • 决策变量
    • 目标函数
    • 约束条件
    • Python代码
  • 三个模型的优势与不足

旅行商问题介绍

旅行商问题 (Traveling Salesman Problem, TSP) 是一个经典的组合优化问题,目标是找到一条最短路径,该路径必须经过每个城市一次且仅一次,最终返回到起始城市。

问题的输入:

  • N N N: 城市的总数。
  • c c c: 城市之间的距离, c i j c_{ij} cij 表示城市 i i i 和城市 j j j 之间的距离。

问题的输出:
在这里插入图片描述


三种模型对比

以下是三种模型的对比:

特性模型1模型2模型3
变量定义有向弧( x i j x_{ij} xij无向弧( x i j x_{ij} xij,仅 i < j i < j i<j无向弧( x i j x_{ij} xij x i j x_{ij} xij x j i x_{ji} xji 意义相同)
变量数量 N × ( N − 1 ) N \times (N-1) N×(N1) N × ( N − 1 ) / 2 N \times (N-1)/2 N×(N1)/2 N × ( N − 1 ) N \times (N-1) N×(N1)
约束类型显式约束隐式无向性 + 惰性约束显式对称约束 + 惰性约束
子环消除静态约束动态惰性约束动态惰性约束
求解效率较低中等较高
运行时间 (50个城市)12.0 s0.2 s0.1 s

注意:

  • 以上测试是基于gurobi 12.0。
  • 模型1的求解效率是gurobi 12.0 高于 gurobi 11.0,模型2和3反之。

求解模型1

决策变量

  • x i j x_{ij} xij: 二进制变量,如果旅行者从城市 i i i 访问城市 j j j,则 x i j = 1 x_{ij} = 1 xij=1,否则 x i j = 0 x_{ij} = 0 xij=0
  • u i u_i ui: 辅助变量,用于表示城市 i i i 的访问顺序(顺序编号,整数)。

目标函数

最小化总的旅行距离:
minimize Z = ∑ i = 0 N − 1 ∑ j = 0 , j ≠ i N − 1 c i j ⋅ x i j \text{minimize} \quad Z = \sum_{i=0}^{N-1}\sum_{j=0,j \neq i}^{N-1} c_{ij} \cdot x_{ij} minimizeZ=i=0N1j=0,j=iN1cijxij

约束条件

  1. 每个城市有且仅有一个出度:
    ∑ j = 0 , j ≠ i N − 1 x i j = 1 , ∀ i = 0 , 1 , … , N − 1 \sum_{j=0, j \neq i}^{N-1} x_{ij} = 1, \quad \forall i = 0, 1, \ldots, N-1 j=0,j=iN1xij=1,i=0,1,,N1

  2. 每个城市有且仅有一个入度:
    ∑ i = 0 , i ≠ j N − 1 x i j = 1 , ∀ j = 0 , 1 , … , N − 1 \sum_{i=0, i \neq j}^{N-1} x_{ij} = 1, \quad \forall j = 0, 1, \ldots, N-1 i=0,i=jN1xij=1,j=0,1,,N1

  3. 防止子环的约束:
    u i − u j + N ⋅ x i j ≤ N − 1 , ∀ i , j = 1 , … , N − 1 ,    i ≠ j u_i - u_j + N \cdot x_{ij} \leq N - 1, \quad \forall i, j = 1, \ldots, N-1, \; i \neq j uiuj+NxijN1,i,j=1,,N1,i=j

  • 注意此处 i , j i,j i,j 是从 1 1 1 开始,不是从 0 0 0 开始。这是因为,假设路径为 0 → 1 → 2 → 0 0 \rightarrow 1 \rightarrow 2 \rightarrow 0 0120,那么 0 0 0 的路径索引即低于1又高于2,出现矛盾。(~~ 在看公式的时候没注意到此处细节,复现的时候卡在这里了一段时间 ~~

Python代码

import time
import numpy as np
from gurobipy import *
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist

def generate_random_city_coordinates(num_cities):
    """生成随机的城市坐标及距离矩阵"""
    np.random.seed(3)  # 锁定随机种子以确保可重复性
    city_coordinates = np.random.rand(num_cities, 2)    # 生成随机城市坐标(0到1之间的浮点数)
    c = cdist(city_coordinates, city_coordinates, metric='euclidean') # 计算城市之间的欧几里得距离
    return c,city_coordinates

def plot_route(city_coordinates, solution):
    """可视化城市和路径"""

    # 画出路径
    plt.plot(city_coordinates[solution][:, 0], city_coordinates[solution][:, 1], color='black', marker='o')
    plt.plot([city_coordinates[solution[0], 0], city_coordinates[solution[-1], 0]],
             [city_coordinates[solution[0], 1], city_coordinates[solution[-1], 1]], color='black', marker='o')  # 回到起点
    
    # 去掉坐标轴黑框
    ax = plt.gca()
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_color('none')
    ax.spines['bottom'].set_color('none')

    # 隐藏坐标轴刻度
    ax.xaxis.set_ticks_position('none')
    ax.yaxis.set_ticks_position('none')

    # 隐藏坐标轴刻度标签
    ax.set_xticks([]) 
    ax.set_yticks([])

    plt.show()

def solve_tsp(num_cities):
    """解决旅行商问题 (TSP)"""
    
    # 生成距离矩阵
    c,city_coordinates = generate_random_city_coordinates(num_cities)
    
    # 创建模型
    TSP = Model("Traveling Salesman Problem")
    
    # 定义决策变量
    x = TSP.addVars(num_cities, num_cities, vtype=GRB.BINARY, name='visit')  # 边的访问变量
    u = TSP.addVars(num_cities, vtype=GRB.INTEGER, lb=0, name='aux')  # 辅助变量用于限制子环

    # 设置目标函数:最小化总的旅行距离
    TSP.setObjective(quicksum(x[i, j] * c[i, j] for i in range(num_cities) for j in range(num_cities)), GRB.MINIMIZE)

    # 设置约束条件
    # 1. 每个城市有且仅有一个出度
    TSP.addConstrs(quicksum(x[i, j] for j in range(num_cities) if i != j) == 1 for i in range(num_cities))
    
    # 2. 每个城市有且仅有一个入度
    TSP.addConstrs(quicksum(x[j, i] for j in range(num_cities) if i != j) == 1 for i in range(num_cities))

    # 3. 防止子环的约束
    TSP.addConstrs(u[i] - u[j] + x[i, j] * num_cities <= num_cities - 1 
                         for i in range(1, num_cities) for j in range(1, num_cities) if i != j)

    # 求解模型
    TSP.optimize()

    if TSP.status == GRB.OPTIMAL:
        print("找到最优解。")
        # 输出选定的路径
        route = []
        for i in range(num_cities):
            for j in range(num_cities):
                if x[i, j].x > 0.5:  # 判断是否选择了这条边
                    route.append((i, j))

        # 寻找完整路径
        current_city = 0
        solution = [current_city]
        while True:
            current_city = next((j for i,j in route if i == current_city ),None)
            solution.append(current_city)
            if current_city == 0:
                break
        print("最优路径为路径为:","->".join(map(str,solution)))
        print(f"总旅行距离: {TSP.ObjVal:.2f}")
        plot_route(city_coordinates, solution)

    return TSP

# 主程序入口
if __name__ == "__main__":
    start_time = time.time()            # 标记开始时间
    number_of_city_coordinates = 50               # 城市数量
    solve_tsp(number_of_city_coordinates)         # 调用解决TSP的函数
    runtime = time.time() - start_time  # 计算运行时间
    print(f"程序运行时间: {runtime:.2f}秒")

求解模型2

决策变量

  • x i j x_{ij} xij: 二进制变量,如果旅行者经过城市 i i i 和城市 j j j 之间的弧,则 x i j = 1 x_{ij} = 1 xij=1,否则 x i j = 0 x_{ij} = 0 xij=0。 (注意:仅定义 i < j i < j i<j 的边,即 x i j x_{ij} xij 表示无向边。)

目标函数

最小化总的旅行距离:
minimize Z = ∑ i = 0 N − 1 ∑ j = i + 1 N − 1 c i j ⋅ x i j \text{minimize} \quad Z = \sum_{i=0}^{N-1}\sum_{j=i+1}^{N-1} c_{ij} \cdot x_{ij} minimizeZ=i=0N1j=i+1N1cijxij

约束条件

  1. 每个城市有且仅有两个邻接边(入度和出度之和为2):
    ∑ j = 0 , j < i N − 1 x j i + ∑ j = 0 , j > i N − 1 x i j = 2 , ∀ i = 0 , 1 , … , N − 1 \sum_{j=0, j < i}^{N-1} x_{ji} + \sum_{j=0, j > i}^{N-1} x_{ij} = 2, \quad \forall i = 0, 1, \ldots, N-1 j=0,j<iN1xji+j=0,j>iN1xij=2,i=0,1,,N1

  2. 防止子环的约束(作为惰性约束,通过回调函数动态添加):
    ∑ i , j ∈ S x i j ≤ ∣ S ∣ − 1. \sum_{i, j \in S} x_{ij} \leq |S| - 1. i,jSxijS1.
    (其中 S S S 是任意子集,表示子环中的城市集合。)

Python代码

  • 注意代码中的 tsp_model.update() 在Gurobi 12.0 中必须加,在 Gurobi 11.0 中可加可不加。(~~ 此处又是卡时间的一个小坑 ~~
import time
import math
import numpy as np
import gurobipy as gp
import matplotlib.pyplot as plt
from itertools import combinations,permutations
from gurobipy import *  # 使用gurobipy库
from scipy.spatial.distance import cdist

def generate_random_cities(num_cities):
    """生成随机的城市坐标及距离矩阵"""
    np.random.seed(3)  # 锁定随机种子以确保可重复性
    city_coordinates = np.random.rand(num_cities, 2)    # 生成随机城市坐标(0到1之间的浮点数)
    c = cdist(city_coordinates, city_coordinates, metric='euclidean') # 计算城市之间的欧几里得距离
    return c,city_coordinates

# 计算两个城市之间的距离
def distance(city_index1, city_index2, distance_matrix):
    """计算城市 city_index1 和 city_index2 之间的距离"""
    return distance_matrix[city_index1, city_index2]

def plot_route(city_coordinates, solution):
    """可视化城市和路径"""

    # 画出路径
    plt.plot(city_coordinates[solution][:, 0], city_coordinates[solution][:, 1], color='black', marker='o')
    plt.plot([city_coordinates[solution[0], 0], city_coordinates[solution[-1], 0]],
             [city_coordinates[solution[0], 1], city_coordinates[solution[-1], 1]], color='black', marker='o')  # 回到起点
    
    # 去掉坐标轴黑框
    ax = plt.gca()
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_color('none')
    ax.spines['bottom'].set_color('none')

    # 隐藏坐标轴刻度
    ax.xaxis.set_ticks_position('none')
    ax.yaxis.set_ticks_position('none')

    # 隐藏坐标轴刻度标签
    ax.set_xticks([]) 
    ax.set_yticks([])

    plt.show()

# 创建 Gurobi 模型
def create_model(num_cities, distance_matrix):
    """创建旅行商问题的 Gurobi 模型"""
    model = Model("Traveling Salesman Problem")
    
    # 定义变量:只使用单向变量 (i < j)
    city_pairs = list(combinations(range(num_cities), 2))
    vars = model.addVars(city_pairs, vtype = GRB.BINARY, name='x')
    
    # 每个城市的边数为 2
    model.addConstrs(vars.sum(c, '*') + vars.sum('*', c) == 2 for c in range(num_cities))

    # 设置目标函数:最小化总的旅行距离
    model.setObjective(quicksum(vars[i, j] * distance_matrix[i, j] for i, j in city_pairs), GRB.MINIMIZE)
    
    model.update()
	
    return model, vars

# 回调函数 - 用于消除子巡环
def subtourelim(model, where):
    """回调函数,用于切断子巡环"""
    if where == GRB.Callback.MIPSOL:
        vals = model.cbGetSolution(model._vars)  # 获取当前解中选择的边
        selected_edges = gp.tuplelist((i, j) for (i, j), val in vals.items() if val > 0.5)
        tour = find_shortest_subtour(selected_edges)  # 寻找短子巡环

        if len(tour) < len(capitals):
            
            pairs_tour = [(tour[i], tour[i+1]) if tour[i] < tour[i+1] else (tour[i+1], tour[i]) for i in range(len(tour) - 1)]
            if tour[-1] < tour[0]:
                pairs_tour.append((tour[-1],tour[0]))
            else:
                pairs_tour.append((tour[0],tour[-1]))
            # 对于子巡环中的每对城市,添加子巡环消除约束
            model.cbLazy(gp.quicksum(model._vars[i, j] for i, j in pairs_tour) <= len(pairs_tour) - 1)

# 寻找给定边的最短子巡环
def find_shortest_subtour(edges):
    unvisited = capitals[:]
    shortest_cycle = capitals[:]  # 初始占位,后续会替换
    while unvisited:
        this_cycle = []
        neighbors = unvisited
        
        while neighbors:
            current = neighbors[0]
            this_cycle.append(current)
            unvisited.remove(current)
            neighbors = [j for i, j in edges.select(current, '*') if j in unvisited] + [i for i, j in edges.select('*', current) if i in unvisited]
        if len(this_cycle) <= len(shortest_cycle):
            shortest_cycle = this_cycle  # 更新为新的最短子巡环
    return shortest_cycle

# 主程序
if __name__ == "__main__":
    start_time = time.time()  # 开始时间记录
    number_of_cities = 50  # 城市数量

    capitals = list(range(number_of_cities))

    # 生成随机城市坐标和距离矩阵
    distance_matrix,city_coordinates = generate_random_cities(number_of_cities)
    
    # 创建模型并优化
    tsp_model, vars = create_model(number_of_cities, distance_matrix)
    tsp_model._vars = vars
    tsp_model.Params.lazyConstraints = 1  # 启用懒约束
    tsp_model.optimize(subtourelim)  # 优化模型

    # 检查模型状态,输出结果
    if tsp_model.status == GRB.OPTIMAL:
        print("找到最优解!")
        selected_edges = [(i, j) for i, j in vars.keys() if vars[i, j].x > 0.5]
        shortest_cycle = find_shortest_subtour(gp.tuplelist(selected_edges))
        total_distance = tsp_model.ObjVal
        print('最优路径', shortest_cycle)
        print('最优长度', total_distance)
        plot_route(city_coordinates, shortest_cycle)
    else:
        print("未找到可行解或模型求解失败。")

    elapsed_time = time.time() - start_time  # 计算运行时间
    print(f"程序运行时间: {elapsed_time:.2f}秒")

求解模型3

  • 该模型来自于此处:https://github.com/Gurobi/modeling-examples/blob/master/traveling_salesman/tsp.ipynb。
  • 因为感觉该模型有些冗余,所以将该模型改写为模型2,然而还是原模型的求解效率高。

决策变量

  • x i j x_{ij} xij: 二进制变量,如果旅行者经过城市 i i i 和城市 j j j 之间的弧,则 x i j = 1 x_{ij} = 1 xij=1,否则 x i j = 0 x_{ij} = 0 xij=0
    (注意: x i j x_{ij} xij x j i x_{ji} xji 是两个独立的变量,表示相同的无向弧。)

目标函数

最小化总的旅行距离:
minimize Z = ∑ i = 0 N − 1 ∑ j = 0 , j ≠ i N − 1 c i j ⋅ x i j \text{minimize} \quad Z = \sum_{i=0}^{N-1}\sum_{j=0, j \neq i}^{N-1} c_{ij} \cdot x_{ij} minimizeZ=i=0N1j=0,j=iN1cijxij

约束条件

  1. 每个城市有且仅有两个邻接边(入度和出度之和为2):
    ∑ j = 0 , j ≠ i N − 1 x i j + ∑ j = 0 , j ≠ i N − 1 x j i = 2 , ∀ i = 0 , 1 , … , N − 1 \sum_{j=0, j \neq i}^{N-1} x_{ij} + \sum_{j=0, j \neq i}^{N-1} x_{ji} = 2, \quad \forall i = 0, 1, \ldots, N-1 j=0,j=iN1xij+j=0,j=iN1xji=2,i=0,1,,N1

  2. 双向路径对称性约束:
    x i j = x j i , ∀ i , j = 0 , 1 , … , N − 1 ,    i ≠ j x_{ij} = x_{ji}, \quad \forall i, j = 0, 1, \ldots, N-1, \; i \neq j xij=xji,i,j=0,1,,N1,i=j

  3. 防止子环的约束(作为惰性约束,通过回调函数动态添加):
    ∑ i , j ∈ S x i j ≤ ∣ S ∣ − 1. \sum_{i, j \in S} x_{ij} \leq |S| - 1. i,jSxijS1.
    (其中 S S S 是任意子集,表示子环中的城市集合。)

Python代码

import time
import numpy as np
import gurobipy as gp
import matplotlib.pyplot as plt
from itertools import combinations,permutations
from gurobipy import *  # 使用gurobipy库
from scipy.spatial.distance import cdist

def generate_random_cities(num_cities):
    """生成随机的城市坐标及距离矩阵"""
    np.random.seed(3)  # 锁定随机种子以确保可重复性
    city_coordinates = np.random.rand(num_cities, 2)    # 生成随机城市坐标(0到1之间的浮点数)
    c = cdist(city_coordinates, city_coordinates, metric='euclidean') # 计算城市之间的欧几里得距离
    return c,city_coordinates

# 计算两个城市之间的距离
def distance(city_index1, city_index2, distance_matrix):
    """计算城市 city_index1 和 city_index2 之间的距离"""
    return distance_matrix[city_index1, city_index2]

def plot_route(city_coordinates, solution):
    """可视化城市和路径"""

    # 画出路径
    plt.plot(city_coordinates[solution][:, 0], city_coordinates[solution][:, 1], color='black', marker='o')
    plt.plot([city_coordinates[solution[0], 0], city_coordinates[solution[-1], 0]],
             [city_coordinates[solution[0], 1], city_coordinates[solution[-1], 1]], color='black', marker='o')  # 回到起点
    
    # 去掉坐标轴黑框
    ax = plt.gca()
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_color('none')
    ax.spines['bottom'].set_color('none')

    # 隐藏坐标轴刻度
    ax.xaxis.set_ticks_position('none')
    ax.yaxis.set_ticks_position('none')

    # 隐藏坐标轴刻度标签
    ax.set_xticks([]) 
    ax.set_yticks([])

    plt.show()

# 创建 Gurobi 模型
def create_model(num_cities, distance_matrix):
    """创建旅行商问题的Gurobi模型"""
    
    # 创建模型
    tsp_model = Model("Traveling Salesman Problem")

    # 单向城市对
    Pairings = combinations(range(num_cities), 2)

    # 双向城市对
    city_pairs = list(permutations(range(num_cities), 2))

    # 添加变量:城市 i 和城市 j 是否相邻
    vars = tsp_model.addVars(city_pairs, vtype=GRB.BINARY, name='x')
    
    # 每个城市的边数为 2
    tsp_model.addConstrs(vars.sum(c, '*') == 2 for c in range(num_cities))
  
    # 无向边
    tsp_model.addConstrs(vars[i,j]==vars[j,i] for i,j in Pairings)

    # 设置目标函数:最小化2倍的总旅行距离
    tsp_model.setObjective(quicksum(vars[i, j] * distance(i, j, distance_matrix) for i,j in city_pairs), GRB.MINIMIZE)
    
    tsp_model.update()
    
    return tsp_model, vars

# 回调函数 - 用于消除子巡环
def subtourelim(model, where):
    """回调函数,用于切断子巡环"""
    if where == GRB.Callback.MIPSOL:
        vals = model.cbGetSolution(model._vars)  # 获取当前解中选择的边
        selected_edges = gp.tuplelist((i, j) for i, j in model._vars.keys() if vals[i, j] > 0.5)

        tour = find_shortest_subtour(selected_edges)  # 寻找短子巡环
        if len(tour) < len(capitals):
            # 对于子巡环中的每对城市,添加子巡环消除约束
            model.cbLazy(gp.quicksum(model._vars[i, j] for i, j in combinations(tour, 2)) <= len(tour) - 1)

# 寻找给定边的最短子巡环
def find_shortest_subtour(edges):
    unvisited = capitals[:]
    shortest_cycle = capitals[:]  # 初始占位,后续会替换
    while unvisited:
        this_cycle = []
        neighbors = unvisited
        
        while neighbors:
            current = neighbors[0]
            this_cycle.append(current)
            unvisited.remove(current)
            neighbors = [j for i, j in edges.select(current, '*') if j in unvisited]
        
        if len(this_cycle) <= len(shortest_cycle):
            shortest_cycle = this_cycle  # 更新为新的最短子巡环
    return shortest_cycle

# 主程序
if __name__ == "__main__":
    start_time = time.time()  # 开始时间记录
    number_of_cities = 50  # 城市数量

    capitals = list(range(number_of_cities))

    # 生成随机城市坐标和距离矩阵
    distance_matrix,city_coordinates = generate_random_cities(number_of_cities)
    
    # 创建模型并优化
    tsp_model, vars = create_model(number_of_cities, distance_matrix)
    tsp_model._vars = vars
    tsp_model.Params.lazyConstraints = 1  # 启用懒约束
    tsp_model.optimize(subtourelim)  # 优化模型

    # 检查模型状态,输出结果
    if tsp_model.status == GRB.OPTIMAL:
        print("找到最优解!")
        selected_edges = [(i, j) for i, j in vars.keys() if vars[i, j].x > 0.5]
        shortest_cycle = find_shortest_subtour(gp.tuplelist(selected_edges))
        total_distance = tsp_model.ObjVal/2
        print('最优路径', shortest_cycle)
        print('最优长度', total_distance)
        plot_route(city_coordinates, shortest_cycle)
    else:
        print("未找到可行解或模型求解失败。")

    elapsed_time = time.time() - start_time  # 计算运行时间
    print(f"程序运行时间: {elapsed_time:.2f}秒")

三个模型的优势与不足

模型1的优势与不足

  • 优势
    • 模型简单直观,易于实现。
    • 使用静态约束消除子环,适合初学者理解。
  • 不足
    • 静态约束可能导致松弛解质量较差,求解效率低。
    • 变量和约束数量较多。

模型2的优势与不足

  • 优势
    • 变量数量较少,约束较少。
  • 不足
    • 回调函数需要额外处理单向变量的双向性,效率略低。
    • 隐式无向性可能导致求解器无法充分利用对称性优化。

模型3的优势与不足

  • 优势
    • 显式对称约束帮助求解器更快识别问题结构,求解效率高。
    • 回调函数直接处理双向变量,效率更高。
    • 适合大规模问题。
  • 不足
    • 模型不简洁,变量数量较多( N × ( N − 1 ) N \times (N-1) N×(N1)),但通过显式约束弥补了效率损失。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++:多继承习题3

题目内容&#xff1a; 声明一个时间类Time&#xff0c;时间类中有3个私有数据成员(Hour&#xff0c;Minute&#xff0c;Second)和两个公有成员函数(SetTime和PrintTime)。要求&#xff1a; &#xff08;1&#xff09; SetTime根据传递的3个参数为对象设置时间&#xff1b; &a…

低代码系统-产品架构案例介绍、得帆云(八)

产品名称 得帆云DeCode低代码平台-私有化 得帆云DeMDM主数据管理平台 得帆云DeCode低代码平台-公有云 得帆云DePortal企业门户 得帆云DeFusion融合集成平台 得帆云DeHoop数据中台 名词 概念 云原生 指自己搭建的运维平台&#xff0c;区别于阿里云、腾讯云 Dehoop 指…

【Unity3D】实现Decal贴花效果,模拟战旗游戏地形效果

目录 一、基础版 二、Post Process 辉光Bloom效果 矩形渐隐 涉及知识点&#xff1a;Decal贴花、屏幕后处理Bloom、屏幕空间构建世界空间、ChracterController物体移动、Terrain地形创建 一、基础版 Unity 2019.4.0f1 普通渲染管线&#xff08;非URP、非HDRP&#xff09; UR…

实践网络安全:常见威胁与应对策略详解

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 引言 在数字化转型的浪潮中&#xff0c;网络安全的重要性已达到前所未有的高度。无论是个人用户、企业&#xff0c;还是政府机构…

UART、I2C和SPI对比

UARTSPII2C英文Universal Asynchronous Receive/TransmitSerial Peripheral InterfaceInner Integrated Communication通讯速度115200、38400 bit/s高达100M bit/s 100k、400k、1M、3.4M bit/s时钟同/异步性时钟异步时钟同步时钟同步接线方式3线(Rx、Tx、GND) 4线(MISO、…

开源项目Umami网站统计MySQL8.0版本Docker+Linux安装部署教程

Umami是什么&#xff1f; Umami是一个开源项目&#xff0c;简单、快速、专注用户隐私的网站统计项目。 下面来介绍如何本地安装部署Umami项目&#xff0c;进行你的网站统计接入。特别对于首次使用docker的萌新有非常好的指导、参考和帮助作用。 Umami的github和docker镜像地…

KIMI K1.5:用大语言模型扩展强化学习(论文翻译)

文章目录 KIMI K1.5技术报告摘要 1. 引言2. 方法&#xff1a;基于大语言模型的强化学习2.1 强化学习提示集整理2.2 长思维链监督微调2.3 强化学习2.3.1 问题设定2.3.2 策略优化2.3.3 长度惩罚2.3.4 采样策略2.3.5 训练方法的更多细节 2.4 长到短&#xff1a;短思维链模型的上下…

思科交换机telnet配置案例

目录 1.telnet简述2.网络拓扑3.设备说明4.网络配置4.1 电脑PC ip设置4.2 网络交换机telnet配置 5.小结 1.telnet简述 Telnet是远程登录服务的一个协议&#xff0c;该协议定义了远程登录用户与服务器交互的方式。它允许用户在一台联网的计算机上登录到一个远程分时系统中&#…

计算机毕业设计Django+Tensorflow音乐推荐系统 机器学习 深度学习 音乐可视化 音乐爬虫 知识图谱 混合神经网络推荐算法 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

基于蓝牙6.0的RSSI和UWB融合定位方法,可行性分析

融合RSSI&#xff08;接收信号强度指示&#xff09;和UWB&#xff08;超宽带&#xff09;两种技术进行蓝牙6.0定位是完全可行的&#xff0c;并且可以带来更高的定位精度和稳定性。本文给出分析和MATLAB仿真结果 文章目录 技术优势RSSIUWB融合的优势 实现方案数据融合算法硬件要…

【开源免费】基于Vue和SpringBoot的在线文档管理系统(附论文)

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

AI DeepSeek

DeepSeek 文字解析 上传图片解析 视乎结果出入很大啊&#xff0c;或许我们应该描述更加清楚自己的需求。

QT使用eigen

QT使用eigen 1. 下载eigen https://eigen.tuxfamily.org/index.php?titleMain_Page#Download 下载后解压 2. QT引入eigen eigen源码好像只有头文件&#xff0c;因此只需要引入头文件就好了 qt新建项目后。修改pro文件. INCLUDEPATH E:\222078\qt\eigen-3.4.0\eigen-3.…

mysql学习笔记-数据库其他调优策略

1、如何定位调优问题 用户的反馈&#xff08;主要&#xff09; 日志分析&#xff08;主要&#xff09; 服务器资源使用监控 数据库内部状况监控 2、调优的维度和步骤 第1步&#xff1a;选择适合的 DBMS 第2步&#xff1a;优化表设计 第3步&#xff1a;优化逻辑查询 第4步&am…

HTB:Forest[WriteUP]

连接至HTB服务器并启动靶机 分配IP&#xff1a;10.10.16.21 靶机IP&#xff1a;10.10.10.161 靶机Domain&#xff1a;forest.htb 目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端…

物业软件推动物业行业数字化转型 实现高效管理和优质客户体验

内容概要 在当今高速发展的数字化时代&#xff0c;物业软件的出现不仅使物业管理变得更加高效&#xff0c;也为行业转型提供了强大的支持。通过整合多种功能&#xff0c;物业软件显著提升了管理效率和客户体验。例如&#xff0c;在线收费和停车管理功能&#xff0c;让业主享受…

GO 库与框架篇

1. 需要重点掌握的库和框架? 输入输出: io,ioutil,fmt,bufio 字符处理: strings,bytes,strconv,regex,unicode,json 日期: 定时器-time.Tick,延时器-time.After/time.AfterFunc 数据库: database/sql 单元测试: testing 非类型安全操作: unsafe 同步:sync-同步操作,atomic-原子…

24-25出差交流体会-25-01-28

简洁版 如果发现自己走下坡路&#xff0c;工资下降等&#xff0c;如何办&#xff1f; &#xff08;环境因素等不在此文讨论范围&#xff0c;个人无法改变大环境。&#xff09; 多思考&#xff0c;是否是自身已经具备的能力在新模式下大幅贬值。 出路只有一条&#xff0c;提升自…

Linux 学习笔记__Day3

十八、设置虚拟机的静态IP 1、VMware的三种网络模式 安装VMware Workstation Pro之后&#xff0c;会在Windows系统中虚拟出两个虚拟网卡&#xff0c;如下&#xff1a; VMware提供了三种网络模式&#xff0c;分别是&#xff1a;桥接模式&#xff08;Bridged&#xff09;、NAT…

SOME/IP--协议英文原文讲解2

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 4.1 Speci…