[基因遗传算法]进阶之四:实践VRPTW

news2024/12/23 16:28:52

参考资料:
《旅行商问题(TSP)、车辆路径问题(VRP,MDVRP,VRPTW)模型介绍》

本文对《基于GA算法解决VRPTW》的分析和思考.具体的代码可以参考
《Python实现(MD)VRPTW常见求解算法——遗传算法(GA)》 .


文章目录

  • 壹、VRPTW
    • 一. 定义类
    • 二、数据读取
    • 三. 构造初始解空间
    • 四、计算任意两点间的距离
    • 四、VRPTW的解的解码
    • 五. VRPTW的解码的代码
    • 六、计算适应度
    • 七、二元锦标赛
    • 八、基因的交叉和变异
    • 九、主程序

壹、VRPTW

由于VRP问题的持续发展,考虑需求点对于车辆到达的时间有所要求之下,在车辆途程问题之中加入时窗的限制,便成为带时间窗车辆路径问题(VRP with Time Windows, VRPTW)。带时间窗车辆路径问题(VRPTW)是在VRP上加上了客户的被访问的时间窗约束。在VRPTW问题中,除了行驶成本之外, 成本函数还要包括由于早到某个客户而引起的等待时间和客户需要的服务时间。在VRPTW中,车辆除了要满足VRP问题的限制之外,还必须要满足需求点的时窗限制,而需求点的时窗限制可以分为两种,一种是硬时窗(Hard Time Window),硬时窗要求车辆必须要在时窗内到达,早到必须等待,而迟到则拒收;另一种是软时窗(Soft Time Window),不一定要在时窗内到达,但是在时窗之外到达必须要处罚,以处罚替代等待与拒收是软时窗与硬时窗最大的不同
模型参考1
在这里插入图片描述
在这里插入图片描述

举例: 假设有一个仓库(会分隔为起始仓库和终点仓库,用0和n+1表示映射的ID),有多个快递员配备相同的车(车辆的容量为Q)。车辆的映射ID是从 1 , 2 , . . . k 1,2,...k 1,2,...k。对 n n n个顾客去配送物品,顾客的映射ID为从 1 , 2... n 1,2...n 1,2...n,每个顾客的需求为 q i q_i qi。每个顾客可以接受快递的时间窗口为 [ a i , b i ] [a_i,b_i] [aibi]。任意两个节点之间的成本总 c i j c_{ij} cij表示。

  • 顾客集合: 即需求节点的集合
  • n+1:终点仓库; 0:起点仓库;(本质是同一个,为了区分方向而设)
  • 所有的顶点: 顾客集合(多个需求节点)+depot(单个)
  • 车辆集合: 所有运货的车辆
  • 顾客时间窗口: 需求节点(被服务的时间), 类似于上门取件(快递)定在8-9点某个时间段.
  • 路径成本: 可能是距离成本,也可能是时间成本
  • y i k y_{ik} yik表示顾客 i i i制定给车辆 k k k服务.或者说由车辆 k k k配送节点 i i i的需求

☀️约束条件

  1. 每个节点只能访问一次(对应公式3.3)
  2. 对于车辆某k,除了终点仓库的其他任意节点到达节点 h h h的次数应等于节点 h h h到达除了起始仓库以外的任意节点的次数. (即出入节点 h h h的次数应该相等,对应公式3.4)–车不在任意需求节点停留。车总会返回仓库
  3. 对于车辆某k, 其服务的所有站点的所消耗车辆的空间容量应小于Q.(车容量限制,对应公式3.5)
  4. 车辆k在站点i到达的时间+节点i到节点j的时间+…<到达节点j的时间。(时间上的顺序性?),对应公式3.6
  5. 对于车辆k在节点i的到达时间,要满足硬时窗的约束。对应公式3.7

☀️目标函数:所有车辆轨迹的成本
☀️思考:

  1. 解空间的设置,包含了解的存在性。所以,解空间一定要全。
  2. 解的编码,根据约束条件获得解的编码。
  3. 根据解码后的解,求目标函数,适应度。
  4. 根据基因遗传算法,逐步优化解

参考模型2
在这里插入图片描述
在这里插入图片描述

一. 定义类

定义解的结构,需求节点的结构,depot的结构,model的属性结构.


# 数据结构:解
class Sol():
    def __init__(self):
        self.obj=None # 目标函数值
        self.fit = 0
        self.node_no_seq=[] # 解的编码
        self.route_list=[] # 解的解码
        self.timetable_list=[] # 车辆访问各点的时间
        self.route_distance = None
# 数据结构:需求节点
class Node():
    def __init__(self):
        self.id=0 # 节点id
        self.x_coord=0 # 节点平面横坐标
        self.y_cooord=0  # 节点平面纵坐标
        self.demand=0 # 节点需求
        self.start_time=0 # 节点开始服务时间
        self.end_time=1440 # 节点结束服务时间
        self.service_time=0 # 单次服务时长
        self.vehicle_speed = 0 # 行驶速度
# 数据结构:车场节点
class Depot():
    def __init__(self):
        self.id=0 # 节点id
        self.x_coord=0 # 节点平面横坐标
        self.y_cooord=0  # 节点平面纵坐标
        self.start_time=0 # 节点开始服务时间
        self.end_time=1440 # 节点结束服务时间
        self.v_speed = 0 # 行驶速度
        self.v_cap = 80 # 车辆容量

二、数据读取

demand.csv
在这里插入图片描述
depot.csv
在这里插入图片描述
定义def readCSVFile(demand_file,depot_file,model):函数后.测试一下

model=Model()
demand_file="demand.csv"
depot_file="depot.csv"
readCSVFile(demand_file,depot_file,model) #运行,没有return

查看结果:
在这里插入图片描述

三. 构造初始解空间

同《实践CVRP》中的一摸一样

# 3.构造初始解
def genInitialSol(model):
    node_no_seq=copy.deepcopy(model.demand_id_list)
    for i in range(model.popsize):
        random.shuffle(node_no_seq)
        sol=Sol()
        sol.node_no_seq=copy.deepcopy(node_no_seq)
        model.sol_list.append(sol) 

四、计算任意两点间的距离

# 4.初始化参数:计算距离矩阵时间矩阵及初始信息素
def calDistanceTimeMatrix(model):
    for i in range(len(model.demand_id_list)):
        from_node_id = model.demand_id_list[i]#需求节点1
        for j in range(i + 1, len(model.demand_id_list)):
            to_node_id = model.demand_id_list[j]#需求节点2
            dist = math.sqrt((model.demand_dict[from_node_id].x_coord - model.demand_dict[to_node_id].x_coord) ** 2
                             + (model.demand_dict[from_node_id].y_coord - model.demand_dict[to_node_id].y_coord) ** 2)
            #求节点1和节点2之间的距离,并保存
            model.distance_matrix[from_node_id, to_node_id] = dist
            model.distance_matrix[to_node_id, from_node_id] = dist
            #节点1和节点2之间的时间距离=路程距离/速度,并保存
            model.time_matrix[from_node_id,to_node_id] = math.ceil(dist/model.depot.v_speed)
            model.time_matrix[to_node_id,from_node_id] = math.ceil(dist/model.depot.v_speed)
        # depot和节点1之间的距离,时间距离,并保存
        dist = math.sqrt((model.demand_dict[from_node_id].x_coord - model.depot.x_coord) ** 2 +
                         (model.demand_dict[from_node_id].y_coord - model.depot.y_coord) ** 2)
        model.distance_matrix[from_node_id, model.depot.id] = dist
        model.distance_matrix[model.depot.id, from_node_id] = dist
        model.time_matrix[from_node_id,model.depot.id] = math.ceil(dist/model.depot.v_speed)
        model.time_matrix[model.depot.id,from_node_id] = math.ceil(dist/model.depot.v_speed)

四、VRPTW的解的解码

在CVRP中,我们通过对TSP解的切割,获得了CVRP的解. 那么我们如何获得VRPTW的解呢?
节点的ID序列:[3,→4,→2,→0,→1,→9→8→7→6→5] ,设depot的ID号为:d1 .这个序列(TSP的一个解)在解码后(满足相关约束条件后)得到一个总路径距离最小的(VRPTW)解.
假设该序列,就考虑满足约束条件而言,VRPTW可有(多个)路径规划.甚至会存在sol3下的极限情况(不限制回depot的情况下).换而言之,sol3是必定满足约束条件的.

  • sol1=[3→4→d1,2→0→1→d1,9→8→d1,7→6→5]
  • sol2=[3→d1, 4→2→0→1→d1,9→8→7→6→5]
  • Sol3=[3→d1,4→d1,2→d1,0→d1,1→d1,9→d1,8→d1,7→d1,6→d1,5→d1]

因此序列,就满足约束条件而言,会存在一至多个路径规划, 我们在所有的路径规划中,选择总的路径距离最小的规划,当作我们对这列序号的解码.也就是解码存在唯一性.-----这是不限制车辆的次数的情况下.
那么思考:如果限制车辆的次数, 如果该序列在限制条件的约束下,如果找不到一个路径规划怎么办? 那么是否考虑该序列的循环情况的解呢?比如
L1=[3,→4,→2,→0,→1,→9→8→7→6→5]没有路径规划,而L2=[4,→2,→0,→1,→9→8→7→6→5–>3]存在路径规划,是否能将L1的解码后的解映射为L2的解码后的解呢??

那么如何解码呢?
1.设置解的字典Pred中所有需求节点的初始映射值为d1(depot),用于保存解的顺序结构.
2. 设置解的距离字典V={(3,inf),(4,inf),…,(5,inf)},表示该节点到结束路径规划所需要的最小距离成本(或其他成本). 这个成本的初始值为inf(正无穷),并特设v(depot)=0.
3. 对于序列L1中的节点,我们顺序判断,节点是否可以为所有后续节点的前导节点.而对于一个(需求)节点的后续节点,有两种分类(先假设成立):
注意到i表示节点n_1, j表示节点n_2;n_1的前一个是n_4, 而n_2的前一个是n_3

  • depot仓库节点(类似于sol2的形式):(n1_=n_2)
    Depot(起点)->n_1(n_2)==>depot(终点)

    ①时间约束:
    节点的最早到达时间arrival=max(depot的开始服务时间+depot致节点的移动时间,
    该节点的开始服务时间)
    节点的最早离开时间departure=到达时间(上公式)+该节点的服务时间
    距离成本cost=仓库到该节点的距离的2倍(一去一回)
    ②容量约束:
    累加需求(这只该节点的需求)<车容量 且 节点离开时间<=节点服务的结束时间
    ③路径的最小化:采用狄利克雷最小距离的方法
    前导节点(当前节点的来源):如果为depot, 则前面的行程为0,即V(d1)=0.
    比较{前导节点+cost(前导,当前), 记录的当前节点的成本}
    如果前者更小,则更新当前节点的成本,并更新Pred[当前节点]=前导节点

    第一步必定完成了depot→n_1(3)→depot. v(3)=0+cost,pred[3]=d1

  • 需求节点(类似于sol1的形式):(n_1!=n_2)
    Depot[n_4]→3[n_1] ==n_3[3]→n_2[4]

    ①时间约束
    后续节点到达时间arrival=max(离开时间+当前节点至后续节点的移动时间,
    后续节点的服务开始时间)
    后续离开时间departure=到达时间+后续节点的服务时间
    距离成本=成本-当前节点返回depot的成本+当前节点至后续节点的距离成本+后续节点返回depot的成本.
    ②容量约束
    累计需求(到当前节点的需求+后续节点的需求)< 车容量
    后续节点的离开时间<=后续极点的服务结束时间
    ③路径的最小化:采用狄利克雷最小距离的方法.同理

五. VRPTW的解码的代码

  • 根据序列列表和Pred(节点映射到前导节点), 书写其route的列表形式
# 5.根据Split结果,提取路径
def extractRoutes(node_no_seq,Pred,model):
    route_list = []
    route = [model.depot.id]
    label = Pred[node_no_seq[0]]#初始标签为仓库标签
    for node_id in node_no_seq:
        # 如果需求节点的前导节点为depot,则将需求节点放入route
        if Pred[node_id] == label:
            route.append(node_id)
        else:
            # 需求界定的前导节点为depot,则将depot放入route
            route.append(model.depot.id)
            route_list.append(route)#将rout放入route表
            route = [model.depot.id,node_id]#开创新route,放入depot和需求节点
            label = Pred[node_id]#当前节点的后续接待你作为标签
    route.append(model.depot.id)
    route_list.append(route)
    #[[-1,2,3,8,-1],
    #[-1,1,0,4,6,-1],
    #[-1,5,7,9,-1] ] route_list
    return route_list
  • 更据chapter 四的思想,对解进行解码(切割), 并获得路径的列表形式.

## 6.对某个解进行分割
def splitRoutes(node_no_seq,model):
    depot=model.depot# 仓库
    V={id:float('inf') for id in model.demand_id_list}
    # demand_id_list:需求节点id集合
    # V:将需求节点id--映射--->[成本] ,初始值为正无穷
    V[depot.id]=0
    Pred={id:depot.id for id in model.demand_id_list}
    # Pred:需求节点id--映射-->depot,(固定值,表明可从任何需求节点返回depot)
    for i in range(len(node_no_seq)):
        n_1=node_no_seq[i] #节点1(ID)
        demand=0
        departure=0 #离开?
        j=i
        cost=0#成本?
        while True:
            n_2 = node_no_seq[j]#节点2(ID),可与节点1相同
            demand = demand + model.demand_dict[n_2].demand#累加节点2的需求
            if n_1 == n_2:
                # 如果节点1和节点2相同
                # 比较{节点1的服务开始时间, 仓库的服务开始时间+仓库到节点1的时间}的大小,从而确定节点2的最早到达时间
                arrival= max(model.demand_dict[n_2].start_time,
                             depot.start_time+model.time_matrix[depot.id,n_2])
                # 节点2的最早离开时间=最早到达时间+节点2的服务时间
                departure=arrival+model.demand_dict[n_2].service_time
                # depot-->n_2的距离成本
                cost = model.distance_matrix[depot.id, n_2] * 2
            else:
                # 在节点1和节点2不相同的时候
                n_3=node_no_seq[j-1]#n_2的前面索引的一个
                # n_3==n_1
                arrival= max(departure+model.time_matrix[n_3,n_2],#(节点1)离开时间+节点3到节点2的行驶时间
                             model.demand_dict[n_2].start_time)#节点2的服务时间
                # 离开时间=到达时间+节点2的服务时间
                departure=arrival+model.demand_dict[n_2].service_time
                # 成本=原距离成本-节点3到depot的距离+节点3到节点2的距离+节点2到depot的距离
                cost = cost - model.distance_matrix[n_3, depot.id] + model.distance_matrix[n_3, n_2] + \
                       model.distance_matrix[n_2, depot.id]
            if demand<=model.depot.v_cap and departure<= model.demand_dict[n_2].end_time:
                #如果累加需求<=车的容量 且 离开时间<节点2的服务结束时间
                if departure+model.time_matrix[n_2,depot.id]  <= depot.end_time:
                    # 离开时间+节点2到达仓库的时间<=仓库的结束时间
                    n_4=node_no_seq[i-1] if i-1>=0 else depot.id
                    # 如果i不是最后一个节点,则n_4为n_1的前一个节点,否则为仓库
                    if V[n_4]+cost <= V[n_2]:
                        V[n_2]=V[n_4]+cost
                        Pred[n_2]=i-1
                    j=j+1
            else:
                break
            if j==len(node_no_seq):
                break
    route_list= extractRoutes(node_no_seq,Pred,model)
    return route_list


六、计算适应度

  • 要使路径最小话,因此对于一个规划来说,要求得其总距离.
# 7.计算路径费用
def calTravelCost(route_list,model):
    #[[-1,2,3,8,-1],
    #[-1,1,0,4,6,-1],
    #[-1,5,7,9,-1] ] route_list,举例
    timetable_list=[]
    route_distance = []
    total_distance=0
    for route in route_list:
        timetable=[]
        distance = 0
        for i in range(len(route)):
            if i == 0:
                depot_id=route[i]#每个route的第一个为depot
                next_node_id=route[i+1]
                travel_time=model.time_matrix[depot_id,next_node_id]#depot至后续节点的时间
                departure=max(model.depot.start_time,
                              model.demand_dict[next_node_id].start_time-travel_time)
                #离开时间=max(仓库的服务开始时间,后续节点的服务开始时间-路程时间)
                timetable.append((departure,departure))
            elif 1<= i <= len(route)-2:
                #i:从第一个需求节点到倒数第二个需求节点
                last_node_id=route[i-1]#前导节点
                current_node_id=route[i]#当前节点
                current_node = model.demand_dict[current_node_id]#当前节点的需求
                travel_time=model.time_matrix[last_node_id,current_node_id]#移动时间距离
                arrival=max(timetable[-1][1]+travel_time,current_node.start_time)
                #到达时间=max([上一组的]离开时间+行驶时间, 当前节点的服务开始时间)
                departure=arrival+current_node.service_time
                #离开时间=到达时间+当前节点的服务时间
                timetable.append((arrival,departure))
                #当前节点的(到达时间,离开时间)保存
                distance += model.distance_matrix[last_node_id, current_node_id]
                #累计距离
            else:
                last_node_id = route[i - 1]#倒数第二个节点(最后一个需求节点)
                depot_id=route[i]#后续节点为仓库
                travel_time = model.time_matrix[last_node_id,depot_id]#行驶时间
                departure = timetable[-1][1]+travel_time#离开时间
                timetable.append((departure,departure))
                distance +=model.distance_matrix[last_node_id,depot_id]#累计距离
        total_distance += distance#总距离
        route_distance.append(distance)#每段的距离保存
        timetable_list.append(timetable)#每段的时间集,保存[[(,)(,)],[(,)]]
    return timetable_list,total_distance,route_distance
  • 计算整个种群的适应度

# 8.计算适应度
def calFit(model):
    #calculate fit value:fit=Objmax-obj
    max_obj=-float('inf')
    best_sol=Sol()#record the local best solution
    best_sol.obj=float('inf')

    for sol in model.sol_list:
        node_no_seq=sol.node_no_seq
        sol.route_list= splitRoutes(node_no_seq, model)
        sol.timetable_list,sol.obj, sol.route_distance = calTravelCost(sol.route_list, model)
        if sol.obj > max_obj:
            max_obj = sol.obj
        if sol.obj < best_sol.obj:
            best_sol = copy.deepcopy(sol)
    #calculate fit value
    for sol in model.sol_list:
        sol.fit = max_obj-sol.obj
    #update the global best solution
    if best_sol.obj<model.best_sol.obj:
        model.best_sol=best_sol

七、二元锦标赛

同CVRP一样

八、基因的交叉和变异

因为,交叉和变异都是基于基因的变化,而不是解码后的变化. 因此, 其函数同前面CVRP完全一样.

九、主程序

其结构顺序是基于基因遗传算法思想的,这个没有改变,则运行框架不变.

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

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

相关文章

JVM调优手段

JDK提供命令工具 jstat 是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据&#xff0c;在没有 GUI图形界面&#xff0c;只提供了纯文本控制台环境的服务器上&#xff0c;它将是运行期定位虚拟…

博球一看,CSDN与你共观世界杯

2022卡塔尔世界杯不知不觉已接近尾声&#xff0c;不仅让人感叹&#xff0c;乌拉圭&#xff0c;巴西&#xff0c;葡萄牙都已淘汰&#xff0c;四强诞生分别是阿根廷&#xff0c;法国&#xff0c;摩洛哥&#xff0c;克罗地亚&#xff0c;非常期待梅西和魔笛的对决&#xff0c;也希…

电子学会2020年12月青少年软件编程(图形化)等级考试试卷(三级)答案解析

目录 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 二、判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 三、编程题【该题由测评师线下评分】&#xff08;共3题&#xff0c;共30分&#xff09; 青少年软件…

【云计算与大数据技术】虚拟化简介及虚拟化的分类讲解(图文解释 超详细)

一、虚拟化简介 1&#xff1a;什么是虚拟化 虚拟化是指计算机元件在虚拟的基础上而不是在真实的、独立的物理硬件基础上运行。这种以优化资源、简化软件的重新配置过程为目的的解决方案就是虚拟化技术 虚拟化架构就是在一个物理硬件机器上同时运行多个不同应用的独立的虚拟系…

r语言中对LASSO回归,Ridge岭回归和弹性网络Elastic Net模型实现|视频

Glmnet是一个通过惩罚最大似然关系拟合广义线性模型的软件包。正则化路径是针对正则化参数λ的值网格处的lasso或Elastic Net&#xff08;弹性网络&#xff09;惩罚值计算的。 最近我们被客户要求撰写关于LASSO的研究报告&#xff0c;包括一些图形和统计输出。该算法非常快&am…

电子学会2020年12月青少年软件编程(图形化)等级考试试卷(四级)答案解析

目录 一、单选题&#xff08;共15题&#xff0c;每题2分&#xff0c;共30分&#xff09; 二、判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 三、编程题【该题由测评师线下评分】&#xff08;共4题&#xff0c;共50分&#xff09; 青少年软件…

51单片机——LED 点阵点亮一个点,小白详解

LED点阵介绍&#xff1a; LED点阵是由发光二极管排列组成的显示器件&#xff0c;在我们生活中的电器中随处可见&#xff0c;被广泛用于汽车报站器&#xff0c;广告屏等。 通常用用较多的是8*8点阵&#xff0c;然后使用多个8*8点阵组成不同分辨率的LED点阵显示屏&#xff0c;比如…

kubernetes--kube-proxy组件深入理解

文章目录kube-proxy的工作原理netfilter的运行机制ipvs和iptables有什么区别&#xff1f;iptables在网络栈的hook点更多&#xff0c;而ipvs的hook点很少iptables的hook点ipvs的hook点如何切换&#xff1f;ipvs安装为何推荐ipvs&#xff1f;为什么iptables或者ipvs在每个节点上都…

面试官:你会几种分布式 ID 生成方案???

1. 为什么需要分布式 ID 对于单体系统来说&#xff0c;主键 ID 常用主键自动的方式进行设置。这种 ID 生成方法在单体项目是可行的&#xff0c;但是对于分布式系统&#xff0c;分库分表之后就不适应了。比如订单表数据量太大了&#xff0c;分成了多个库&#xff0c;如果还采用…

基于java+springboot+mybatis+vue+mysql的福聚苑社区团购

项目介绍 随着互联网的发展&#xff0c;各种团购模式也越来越多&#xff0c;尤其是最近几年的社区团购模式更是如火如荼的在进行着&#xff0c;我了能够让大家品味到更多的瓜果蔬菜&#xff0c;我们通过java语言&#xff0c;springboot框架、前端vue技术、数据库mysql开发了本…

使用Hilt搭建隔离层架构

在我们的日常编码的过程中&#xff0c;常常会遇到这种需求。例如&#xff1a;这个版本我们使用okhttp作为网络通信库&#xff0c;如果下个版本我们想要用volley作为网络通信库&#xff0c;那该怎么办呢&#xff1f;我们总不能对使用okhttp的地方一个个改成volley吧&#xff01;…

上班都在刷的Java八股文,老板都想要一份?

今天心血来潮刷刷牛客看到这&#xff0c;小伙在上班刷八股文被老板逮到&#xff01;真行啊&#xff0c;结果还让他给老板也发一份&#xff0c;感觉过不了多久就跟老板一起提桶跑路了 说到这&#xff0c;我最近也整理了GitHub上高标星的面试八股文&#xff0c;这种金九银十的节骨…

Java并发编程之Condition await/signal原理剖析

Java并发编程之Condition await/signal原理剖析 文章目录Java并发编程之Condition await/signal原理剖析Condition与Lock的关系Condition实现原理await()实现分析signal()实现分析Condition接口与Object监听器的区别Condition与Lock的关系 Condition本身也是⼀个接口&#xff…

OpenStack的简单部署

OpenStack的简单部署 文章目录OpenStack的简单部署一、OpenStack概述二、环境准备三、搭建流程1. 更新 & 升级2. 安装好用的vim VimForCpp3. 安装必要依赖4. 关闭防火墙、核心防护、NetworkManager5. 配置静态IP地址6.配置yum源7. 安装时间同步服务8. 使用packstack 一键部…

C罗老矣,我的程序人生还有多远

☆ 随着12月11号摩洛哥1-0葡萄牙比赛的结束&#xff0c;不仅说明葡萄牙对要结束本届卡塔尔世界杯了&#xff0c;就连C罗此生的世界杯之旅也将画上句号了。 ☆ 37岁的球星本该是人生最璀璨的阶段&#xff0c;但在足球生涯中&#xff0c;这已经是大龄了。不禁让我想到&#xff0c…

机器视觉(五):机器视觉与世界杯

11月22日晚上&#xff0c;球迷再次为阿根廷而惋惜。在当天晚上进行的世界杯小组赛C组首轮比赛中&#xff0c;阿根廷队1:2不敌沙特阿拉伯队&#xff0c;爆出了本届世界杯开赛至今最大的冷门。 天台好冷不仅如此&#xff0c;阿根廷队全场比赛总计被吹罚了10次越位&#xff0c;刷新…

SpringMVC(一) 构建项目

SpringMVC(一) 构建项目 1.创建项目 创建一个空的Maven项目 删除src目录&#xff0c;将新建的项目作为一个工作空间使用&#xff0c;然后在里面创建Module。 2.创建Module 选中刚才创建的项目&#xff0c;右键创建Module 选择Java语言的Maven 项目 3.添加SpringMVC依赖 在…

1-48-mysql-基础篇-DML-select

1-mysql-基础篇&#xff1a; 推荐网站 mysql&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/ 算法&#xff1a;https://www.cs.usfca.edu/~galles/visualization/about.html 数据库 1、数据库概述相关 1、 数据库的相关概念 DB&#xff1a;数据库&#xff08;Data…

git 多用户配置(公司/个人)

背景 张三是一个程序员&#xff0c;他的英文名叫 outlaw&#xff0c;emial: outlaw163.com。 张三入职了一家公司&#xff0c;公司给张三的企业邮箱是 zhangsancompany.com 这一次&#xff0c;他 0 元购了一台新笔记本&#xff0c;需要配置一下 git git 账号配置 配置全局用…

微信公众号开发,获取openid,授权登录 WeChat-official-account-openid

微信公众号开发 功能&#xff1a;自动登录&#xff0c;获取个人信息&#xff0c;上传图片 超多麻烦的情况&#xff0c;怎样获取openid呢&#xff1f; 以下我给大家提供源码&#xff0c;文本&#xff0c;视频资料 保证让你看了就明白哈 look效果 1.拉起用户授权 2.后台获取到…