软件工具 | Python调用运筹优化求解器(一):以CVRPVRPTW为例
目录
- 1. 引言
- 2. 求解器介绍
- 3. 基础语言
- 3.1 创建模型
- 3.2 添加变量
- 3.3 添加目标函数
- 3.4 添加约束
- 3.5 设置参数
- 3.6 求解
- 4. 数学模型
- 4.1 [CVRP数学模型](https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw)
- 4.2 [VRPTW数学模型](https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItuecw)
- 5. 完整代码
- 5.1 Python调用Gurobi求解CVRP
- 5.2 Python调用Gurobi求解VRPTW
- 5.3 Python调用COPT求解CVRP
- 5.4 Python调用COPT求解VRPTW
- 5.5 Python调用SCIP求解CVRP
- 5.6 Python调用SCIP求解VRPTW
- 7. 测试案例
- 8. 测试参数
- 9. 测试结果
- 9.1 CVRP求解结果汇总
- 9.2 VRPTW求解结果汇总
- 9.3 上界下降曲线对比(以CVRP为例)
- 9.5 车辆路径可视化(以CVRP为例)
- c101-31(Gurobi)
- c201-31(Gurobi)
- r101-31(Gurobi)
- 10. 小节
欢迎关注个人微信公众号:Python助力交通
1. 引言
优化求解器是解决复杂工程问题不可或缺的工具,可以帮助我们验证模型的正确性、理解决策变量的耦合关系、获取最优决策方案(合适规模条件下)。小编搜罗了网上关于各类常见(其实并不常见)的优化求解器介绍的帖子:
- 优化求解器资源盘点
- 干货 | 运筹学、数学规划、离散优化求解器大PK,总有一款适合你
- 【学界】运筹学数学规划|离散优化求解器大搜罗
- 除了Gurobi /SCIP,国内外还有哪些优化求解器?
- 开源线性规划求解器(Linear Programming solver)LP_Solve和CLP的PK
- 有哪些简便好用的解凸优化的工具箱或者包?
- 开源建模框架+开源求解器 | 使用pyomo建模框架实现交通物流优化问题的求解
除了以上求解器外,还有一些针对特定问题而量身定制高效率求解器:
- VRP问题求解器
- 基于求解器的路径规划算法实现及性能分析
- 智能优化算法工具包scikit-opt介绍及vrp问题求解评测(一)
- Python主要智能优化算法库汇总
今天的主题是以CVRP和VRPTW问题为例,分享Python调用运筹优化求解器(Gurobi、COPT、SCIP)的教程。
2. 求解器介绍
(1)Gurobi
Gurobi是由美国 Gurobi Optimization 公司开发新一代大规模优化器,提供 C++, Java, Python, .Net, Matlab 和R等多种接口,支持求解以下模型:
(1)连续和混合整数线性问题
(2)凸目标或约束连续和混合整数二次问题
(3)非凸目标或约束连续和混合整数二次问题
(4)含有对数、指数、三角函数、高阶多项式目标或约束,以及任何形式的分段约束的非线性问题
(5)含有绝对值、最大值、最小值、逻辑与或非目标或约束的非线性问题
(2)COPT
杉数求解器COPT(Cardinal Optimizer)是杉数自主研发的针对大规模优化问题的高效数学规划求解器套件,也是支撑杉数端到端供应链平台的核心组件,是目前同时具备大规模混合整数规划、线性规划(单纯形法和内点法)、半定规划、(混合整数)二阶锥规划以及(混合整数)凸二次规划和(混合整数)凸二次约束规划问题求解能力的综合性能数学规划求解器,为企业应对高性能求解的需求提供了更多选择。COPT支持所有主流编程接口:C、C++、C#、Python、Julia、Java、AMPL、GAMS、Pyomo、PuLP、CVXPY。
(3)SCIP
SCIP起源于ZIB(Zuse Institute Berlin),由Tobias Achterberg奠定整个框架,是目前用于混合整数规划(MIP)和混合整数非线性规划(MINLP)的最快的非商业解算器之一,它允许用户对求解过程进行全面控制,支持自定义搜索树中的各个模块,在分支限界(Branch and Bound)过程中添加变量等功能。SCIP支持Python Java AMPL GAMS MATLAB等编程语言。
3. 基础语言
3.1 创建模型
# gurobi
cvrp_model = Model('cvrp')
# copt
env = Envr()
cvrp_model = env.createModel('cvrp')
# scip
cvrp_model = Model('cvrp')
3.2 添加变量
# gurobi
x = cvrp_model.addVar(vtype=GRB.BINARY, name='x') # 单个变量
X = cvrp_model.addVars(N, N, K, vtype=GRB.BINARY, name='X[i,j,k]') # 多个变量
# copt
x = cvrp_model.addVars(vtype=COPT.BINARY, name='x') # 单个变量
X = cvrp_model.addVars(N, N, K, vtype=COPT.BINARY, nameprefix='X[i,j,k]') # 多个变量
# scip
X[i,j,k] = cvrp_model.addVar(vtype="B", name=f"x({i},{j},{k})") # 单个变量(貌似只能添加单个变量)
3.3 添加目标函数
# gurobi
cvrp_model.setObjective( quicksum(X[i,j,k] * cost[i,j] for i in N for j in N for k in K), GRB.MINIMIZE)
# copt
cvrp_model.setObjective(quicksum(X[i, j, k] * cost[i, j] for i in N for j in N for k in K), sense=COPT.MINIMIZE)
# scip
cvrp_model.setObjective( quicksum(X[i,j,k] * cost[i,j] for i in N for j in N for k in K),'minimize' )
3.4 添加约束
# gurobi
cvrp_model.addConstr() # 单个约束
cvrp_model.addConstrs() # 多个约束
# copt
cvrp_model.addConstr() # 单个约束
cvrp_model.addConstrs() # 多个约束
# scip
cvrp_model.addCons() # 单个约束
cvrp_model.addConss() # 多个约束
3.5 设置参数
# gurobi
cvrp_model.setParam(GRB.Param.LogFile, './gurobi_r101-31.log') # 保存日志
cvrp_model.Params.TimeLimit = 1200 # 设置求解时间
# copt
cvrp_model.setLogFile('./copt_r101-31.log') # 保存日志
cvrp_model.param.timelimit = 1200 # 设置求解时间
# scip
cvrp_model.setLogfile('./scip_r101-31.log') # 保存日志
cvrp_model.setRealParam('limits/time', 1200) # 设置求解时间
3.6 求解
# gurobi
cvrp_model.optimize()
# copt
cvrp_model.solve()
# scip
cvrp_model.optimize()
4. 数学模型
4.1 CVRP数学模型
4.2 VRPTW数学模型
5. 完整代码
5.1 Python调用Gurobi求解CVRP
import xlsxwriter
import math
import pandas as pd
import matplotlib.pyplot as plt
from gurobipy import Model,quicksum,GRB
def read_input(filename):""":param filename: 数据文件路径:return:"""df = pd.read_csv(filename)x_coord = { df['id'][i]:df['x_coord'][i] for i in range(df.shape[0]) } # 节点横坐标y_coord = { df['id'][i]:df['y_coord'][i] for i in range(df.shape[0]) } # 节点纵坐标demand = { df['id'][i]:df['demand'][i] for i in range(df.shape[0]) } # 节点需求cost = {}N = df['id'].tolist()for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )cost[f_n,t_n] = distreturn N,cost,demand,x_coord,y_coorddef build_model(N,K,depot,CAP,cost,demand):""":param N: 网络节点集合:param K: 车队集合:param depot: 配送中心id:param CAP: 车辆容量:param cost: 网络弧费用集合:param demand: 网络节点需求集合:return:"""cvrp_model = Model('cvrp')# 添加变量X = cvrp_model.addVars(N, N, K, vtype=GRB.BINARY, name='X[i,j,k]')Y = cvrp_model.addVars(N, K, vtype=GRB.BINARY, name='Y[i,k]')U = cvrp_model.addVars(N, K, vtype=GRB.INTEGER, name='U[i,k]')# 设置目标函数cvrp_model.setObjective( quicksum(X[i,j,k] * cost[i,j] for i in N for j in N for k in K), GRB.MINIMIZE)# 添加约束# 需求覆盖约束cvrp_model.addConstrs( quicksum(Y[i,k] for k in K) == 1 for i in N[1:] )# 车辆启用约束cvrp_model.addConstr( quicksum(Y[depot,k] for k in K) == len(K) )# 车辆流平衡约束cvrp_model.addConstrs( quicksum(X[i,j,k] for j in N ) == quicksum(X[j,i,k] for j in N ) for i in N for k in K )# 车辆路径限制cvrp_model.addConstrs( quicksum(X[i,j,k] for j in N) == Y[i,k] for i in N for k in K )# 车辆容量约束cvrp_model.addConstrs( quicksum(Y[i,k] * demand[i] for i in N) <= CAP for k in K )# 破圈约束cvrp_model.addConstrs( U[i,k] - U[j,k] + CAP * X[i,j,k] <= CAP - demand[i] for i in N[1:] for j in N[1:] for k in K )cvrp_model.addConstrs( U[i,k] <= CAP for i in N[1:] for k in K)cvrp_model.addConstrs( U[i,k] >= demand[i] for i in N[1:] for k in K )return cvrp_model,X,Y,Udef draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()def save_file(route_list,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')row = 2for route in route_list:ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))row += 1wb.close()if __name__ == '__main__':filename = './datasets/CVRP/r101-31.csv'N, cost, demand, x_coord, y_coord = read_input(filename)depot = N[0]K = list(range(1,10))CAP = 80cvrp_model, X, Y, U = build_model(N, K, depot, CAP, cost, demand)cvrp_model.setParam(GRB.Param.LogFile, './gurobi_r101-31.log')cvrp_model.Params.TimeLimit = 1200cvrp_model.optimize()route_list = []for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if X[depot, j, k].x > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if X[cur_node, j, cur_k].x > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute_list.append(route)print("最优路径距离:", cvrp_model.objVal)print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, cvrp_model.objVal)
5.2 Python调用Gurobi求解VRPTW
import math
import pandas as pd
import matplotlib.pyplot as plt
import xlsxwriter
from gurobipy import GRB,Model,quicksum,tupledict,tuplelistdef read_input(filename):""":param filename: 数据文件路径:return:"""N = [] #所有节点Q = {} #节点需求TT = {} #节点旅行时间ET = {} #节点最早开始服务时间LT = {} #节点最晚结束服务时间ST = {} #节点服务时间x_coord = {} # 节点横坐标y_coord = {} # 节点纵坐标Cost={}df = pd.read_csv(filename)for i in range(df.shape[0]):id = df['id'][i]N.append(id)x_coord[id] = df['x_coord'][i]y_coord[id] = df['y_coord'][i]Q[id] = df['demand'][i]ET[id] = df['start_time'][i]LT[id] = df['end_time'][i]ST[id] = df['service_time'][i]for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )Cost[f_n,t_n] = distTT[f_n,t_n] = dist/1 # 假设速度为1return N,Q,TT,ET,LT,ST,Cost,x_coord,y_coorddef build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K):""":param N: 所有节点集合,其中N[0]为车场:param Q: 节点需求集合:param TT: 旅行时间:param ET: 节点最早开始服务时间:param LT:节点最晚结束服务时间:param ST: 节点服务时间:param CAP: 车辆容量:param Cost: 旅行费用:param K: 车队:return:"""C = N[1:] #需求节点M=10**5depot = N[0]# 创建模型vrptw_model=Model()# 添加变量X = vrptw_model.addVars(N,N,K,vtype=GRB.BINARY,name='X(i,j,k)')T = vrptw_model.addVars( N,K,vtype=GRB.CONTINUOUS,lb=0,name='T[i,k]')# 设置目标函数z1 = quicksum( Cost[i,j]*X[i,j,k] for i in N for j in N for k in K if i!=j)vrptw_model.setObjective(z1,GRB.MINIMIZE)# 车辆起点约束vrptw_model.addConstrs(quicksum(X[depot, j, k] for j in N) == 1 for k in K)# 车辆路径连续约束vrptw_model.addConstrs( quicksum(X[i,j,k] for j in N if j!=i)==quicksum(X[j,i,k] for j in N if j!=i) for i in C for k in K)# 车辆终点约束vrptw_model.addConstrs(quicksum(X[j, depot, k] for j in N) == 1 for k in K)# 需求服务约束vrptw_model.addConstrs( quicksum(X[i,j,k] for k in K for j in N if j!=i)==1 for i in C)# 车辆容量约束vrptw_model.addConstrs( quicksum(Q[i]*X[i,j,k] for i in C for j in N if i!=j)<=CAP for k in K )# 时间窗约束vrptw_model.addConstrs( T[i,k]+ST[i]+TT[i,j]-(1-X[i,j,k])*M<=T[j,k] for i in C for j in C for k in K if i!=j )vrptw_model.addConstrs( T[i,k] >= ET[i] for i in N for k in K)vrptw_model.addConstrs( T[i,k] <= LT[i] for i in N for k in K)return vrptw_model,X,T
def draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()
def save_file(route_list,route_timetable,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')ws.write(1,2,'时刻')row = 2for id,route in enumerate(route_list):ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))timetable_str = [str(i) for i in route_timetable[id]]ws.write(row,2,'-'.join(timetable_str))row += 1wb.close()
if __name__=='__main__':filename = './data/r101.csv'N, Q, TT, ET, LT, ST, Cost,x_coord,y_coord = read_input(filename)depot = N[0]K = list(range(1, 30))CAP = 80vrptw_model,X,T = build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K)vrptw_model.setParam(GRB.Param.LogFile, './log/gurobi_r101.log')vrptw_model.Params.TimeLimit = 1500vrptw_model.optimize()route_list = []route_timetable = []# 提取车辆路径for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if X[depot, j, k].x > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if X[cur_node, j, cur_k].x > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute.insert(0,k)route_list.append(route)# 提取车辆的时刻点for route in route_list:k = route[0]timetable = []for i in route[1:]:timetable.append(T[i,k].x)route_timetable.append(timetable)print("最优路径距离:", vrptw_model.objVal)print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, route_timetable, vrptw_model.objVal)
5.3 Python调用COPT求解CVRP
import xlsxwriter
import math
import pandas as pd
import matplotlib.pyplot as plt
from coptpy import *
def read_input(filename):""":param filename: 数据文件路径:return:"""df = pd.read_csv(filename)x_coord = { df['id'][i]:df['x_coord'][i] for i in range(df.shape[0]) } # 节点横坐标y_coord = { df['id'][i]:df['y_coord'][i] for i in range(df.shape[0]) } # 节点纵坐标demand = { df['id'][i]:df['demand'][i] for i in range(df.shape[0]) } # 节点需求cost = {}N = df['id'].tolist()for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )cost[f_n,t_n] = distreturn N,cost,demand,x_coord,y_coord
def build_model(N,K,depot,CAP,cost,demand):# 创建求解环境env = Envr()# 创建求解模型cvrp_model = env.createModel('cvrp')# 添加决策变量X = cvrp_model.addVars(N, N, K, vtype=COPT.BINARY, nameprefix='X[i,j,k]')Y = cvrp_model.addVars(N, K, vtype=COPT.BINARY, nameprefix='Y[i,k]')U = cvrp_model.addVars(N, K, vtype=COPT.INTEGER, nameprefix='U[i,k]')# 设置目标函数cvrp_model.setObjective(quicksum(X[i, j, k] * cost[i, j] for i in N for j in N for k in K), sense=COPT.MINIMIZE)# 添加约束# 需求覆盖约束cvrp_model.addConstrs(quicksum(Y[i, k] for k in K) == 1 for i in N[1:])# 车辆启用约束cvrp_model.addConstr(quicksum(Y[depot, k] for k in K) == len(K))# 车辆流平衡约束cvrp_model.addConstrs(quicksum(X[i, j, k] for j in N) == quicksum(X[j, i, k] for j in N) for i in N for k in K)# 车辆路径限制cvrp_model.addConstrs(quicksum(X[i, j, k] for j in N) == Y[i, k] for i in N for k in K)# 车辆容量约束cvrp_model.addConstrs(quicksum(Y[i, k] * demand[i] for i in N) <= CAP for k in K)# 破圈约束cvrp_model.addConstrs(U[i, k] - U[j, k] + CAP * X[i, j, k] <= CAP - demand[i] for i in N[1:] for j in N[1:] for k in K)cvrp_model.addConstrs(U[i, k] <= CAP for i in N[1:] for k in K)cvrp_model.addConstrs(U[i, k] >= demand[i] for i in N[1:] for k in K)return cvrp_model, X, Y, U
def draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()
def save_file(route_list,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')row = 2for route in route_list:ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))row += 1wb.close()
if __name__ == '__main__':filename = './datasets/CVRP/r101-31.csv'N, cost, demand, x_coord,y_coord = read_input(filename)depot = N[0]K = list(range(1,10))CAP = 80cvrp_model, X, Y, U = build_model(N, K, depot, CAP, cost, demand)cvrp_model.param.timelimit = 1200cvrp_model.setLogFile('./copt_r101-31.log')cvrp_model.solve()route_list = []for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if X[depot, j, k].x > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if X[cur_node, j, cur_k].x > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute_list.append(route)print("最优路径距离:", cvrp_model.objval)print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, cvrp_model.objval)
5.4 Python调用COPT求解VRPTW
import math
import pandas as pd
import matplotlib.pyplot as plt
import xlsxwriter
from coptpy import Envr,COPT,quicksumdef read_input(filename):""":param filename: 数据文件路径:return:"""N = [] #所有节点Q = {} #节点需求TT = {} #节点旅行时间ET = {} #节点最早开始服务时间LT = {} #节点最晚结束服务时间ST = {} #节点服务时间x_coord = {} # 节点横坐标y_coord = {} # 节点纵坐标Cost={}df = pd.read_csv(filename)for i in range(df.shape[0]):id = df['id'][i]N.append(id)x_coord[id] = df['x_coord'][i]y_coord[id] = df['y_coord'][i]Q[id] = df['demand'][i]ET[id] = df['start_time'][i]LT[id] = df['end_time'][i]ST[id] = df['service_time'][i]for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )Cost[f_n,t_n] = distTT[f_n,t_n] = dist/1 # 假设速度为1return N,Q,TT,ET,LT,ST,Cost,x_coord,y_coord
def build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K):""":param N: 所有节点集合,其中N[0]为车场:param Q: 节点需求集合:param TT: 旅行时间:param ET: 节点最早开始服务时间:param LT:节点最晚结束服务时间:param ST: 节点服务时间:param CAP: 车辆容量:param Cost: 旅行费用:param K: 车队:return:"""C = N[1:] #需求节点M=10**5depot = N[0]# 创建求解环境env = Envr()# 创建求解模型vrptw_model = env.createModel('vrptw')# 添加决策变量X = vrptw_model.addVars(N, N, K, vtype=COPT.BINARY, nameprefix='X[i,j,k]')T = vrptw_model.addVars( N,K,vtype=COPT.CONTINUOUS,lb=0,nameprefix='T[i,k]')# 设置目标函数vrptw_model.setObjective(quicksum(X[i, j, k] * Cost[i, j] for i in N for j in N for k in K), sense=COPT.MINIMIZE)# 车辆起点约束vrptw_model.addConstrs(quicksum(X[depot, j, k] for j in N) == 1 for k in K)# 车辆路径连续约束vrptw_model.addConstrs(quicksum(X[i, j, k] for j in N if j != i) == quicksum(X[j, i, k] for j in N if j != i) for i in C for k in K)# 车辆终点约束vrptw_model.addConstrs(quicksum(X[j, depot, k] for j in N) == 1 for k in K)# 需求服务约束vrptw_model.addConstrs(quicksum(X[i, j, k] for k in K for j in N if j != i) == 1 for i in C)# 车辆容量约束vrptw_model.addConstrs(quicksum(Q[i] * X[i, j, k] for i in C for j in N if i != j) <= CAP for k in K)# 时间窗约束vrptw_model.addConstrs(T[i, k] + ST[i] + TT[i, j] - (1 - X[i, j, k]) * M <= T[j, k] for i in C for j in C for k in K if i != j)vrptw_model.addConstrs(T[i, k] >= ET[i] for i in N for k in K)vrptw_model.addConstrs(T[i, k] <= LT[i] for i in N for k in K)return vrptw_model, X, T
def draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()
def save_file(route_list,route_timetable,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')ws.write(1,2,'时刻')row = 2for id,route in enumerate(route_list):ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))timetable_str = [str(i) for i in route_timetable[id]]ws.write(row,2,'-'.join(timetable_str))row += 1wb.close()
if __name__=='__main__':filename = './data/r101.csv'N, Q, TT, ET, LT, ST, Cost,x_coord,y_coord = read_input(filename)depot = N[0]K = list(range(1, 30))CAP = 80vrptw_model,X,T = build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K)vrptw_model.setLogFile('./log/copt_c201.log')vrptw_model.param.timelimit = 1500vrptw_model.solve()route_list = []route_timetable = []# 提取车辆路径for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if X[depot, j, k].x > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if X[cur_node, j, cur_k].x > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute.insert(0,k)route_list.append(route)# 提取车辆的时刻点for route in route_list:k = route[0]timetable = []for i in route[1:]:timetable.append(T[i,k].x)route_timetable.append(timetable)print("最优路径距离:", vrptw_model.objval)print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, route_timetable, vrptw_model.objval)
5.5 Python调用SCIP求解CVRP
import xlsxwriter
import math
import pandas as pd
import matplotlib.pyplot as plt
from pyscipopt import Model, quicksum, multidictdef read_input(filename):""":param filename: 数据文件路径:return:"""df = pd.read_csv(filename)x_coord = { df['id'][i]:df['x_coord'][i] for i in range(df.shape[0]) } # 节点横坐标y_coord = { df['id'][i]:df['y_coord'][i] for i in range(df.shape[0]) } # 节点纵坐标demand = { df['id'][i]:df['demand'][i] for i in range(df.shape[0]) } # 节点需求cost = {}N = df['id'].tolist()for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )cost[f_n,t_n] = distreturn N,cost,demand,x_coord,y_coorddef build_model(N,K,depot,CAP,cost,demand):""":param N: 网络节点集合:param K: 车队集合:param depot: 配送中心id:param CAP: 车辆容量:param cost: 网络弧费用集合:param demand: 网络节点需求集合:return:"""cvrp_model = Model('cvrp')# 添加变量X = {}Y = {}U = {}# 创建变量 X[i,j,k]for i in N:for j in N:for k in K:X[i,j,k] = cvrp_model.addVar(vtype="B", name=f"x({i},{j},{k})")# 创建变量 Y[i,k]for i in N:for k in K:Y[i,k] = cvrp_model.addVar(vtype="B", name=f"y({i},{k})")# 创建辅助变量U[i,k]for i in N:for k in K:U[i,k] = cvrp_model.addVar(vtype="I", name=f"u({i},{k})")# 设置目标函数cvrp_model.setObjective( quicksum(X[i,j,k] * cost[i,j] for i in N for j in N for k in K),'minimize' )# 添加约束# 需求覆盖约束cvrp_model.addConss( quicksum(Y[i,k] for k in K) == 1 for i in N[1:] )# 车辆启用约束cvrp_model.addCons( quicksum(Y[depot,k] for k in K) == len(K) )# 车辆流平衡约束cvrp_model.addConss( quicksum(X[i,j,k] for j in N ) == quicksum(X[j,i,k] for j in N ) for i in N for k in K )# 车辆路径限制cvrp_model.addConss( quicksum(X[i,j,k] for j in N) == Y[i,k] for i in N for k in K )# 车辆容量约束cvrp_model.addConss( quicksum(Y[i,k] * demand[i] for i in N) <= CAP for k in K )# 破圈约束cvrp_model.addConss( U[i,k] - U[j,k] + CAP * X[i,j,k] <= CAP - demand[i] for i in N[1:] for j in N[1:] for k in K )cvrp_model.addConss( U[i,k] <= CAP for i in N[1:] for k in K)cvrp_model.addConss( U[i,k] >= demand[i] for i in N[1:] for k in K )return cvrp_model, X, Y, Udef draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()
def save_file(route_list,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')row = 2for route in route_list:ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))row += 1wb.close()
if __name__ == '__main__':filename = './datasets/CVRP/r101-31.csv'N, cost, demand, x_coord, y_coord = read_input(filename)depot = N[0]K = list(range(1,10))CAP = 80cvrp_model, X, Y, U = build_model(N, K, depot, CAP, cost, demand)# cvrp_model.setRealParam('limits/gap', 0.1) # 求解gap为10%cvrp_model.setRealParam('limits/time', 1200) # 求解时间为1800scvrp_model.setLogfile('./scip_r101-31.log')cvrp_model.optimize()route_list = []for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if cvrp_model.getVal(X[depot, j, k]) > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if cvrp_model.getVal(X[cur_node, j, cur_k]) > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute_list.append(route)print("最优路径距离:", cvrp_model.getObjVal())print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, cvrp_model.getObjVal())
5.6 Python调用SCIP求解VRPTW
import math
import pandas as pd
import matplotlib.pyplot as plt
import xlsxwriter
from pyscipopt import Model, quicksumdef read_input(filename):""":param filename: 数据文件路径:return:"""N = [] #所有节点Q = {} #节点需求TT = {} #节点旅行时间ET = {} #节点最早开始服务时间LT = {} #节点最晚结束服务时间ST = {} #节点服务时间x_coord = {} # 节点横坐标y_coord = {} # 节点纵坐标Cost={}df = pd.read_csv(filename)for i in range(df.shape[0]):id = df['id'][i]N.append(id)x_coord[id] = df['x_coord'][i]y_coord[id] = df['y_coord'][i]Q[id] = df['demand'][i]ET[id] = df['start_time'][i]LT[id] = df['end_time'][i]ST[id] = df['service_time'][i]for f_n in N:for t_n in N:dist = math.sqrt( (x_coord[f_n]-x_coord[t_n])**2 + (y_coord[f_n] - y_coord[t_n])**2 )Cost[f_n,t_n] = distTT[f_n,t_n] = dist/1 # 假设速度为1return N,Q,TT,ET,LT,ST,Cost,x_coord,y_coord
def build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K):""":param N: 所有节点集合,其中N[0]为车场:param Q: 节点需求集合:param TT: 旅行时间:param ET: 节点最早开始服务时间:param LT:节点最晚结束服务时间:param ST: 节点服务时间:param CAP: 车辆容量:param Cost: 旅行费用:param K: 车队:return:"""C = N[1:] #需求节点M=10**5depot = N[0]# 创建模型vrptw_model=Model()X = {}T = {}# 创建变量 X[i,j,k]for i in N:for j in N:for k in K:X[i, j, k] = vrptw_model.addVar(vtype="B", name=f"x({i},{j},{k})")# 创建变量 T[i,k]for i in N:for k in K:T[i, k] = vrptw_model.addVar(vtype="I", name=f"t({i},{k})")# 设置目标函数vrptw_model.setObjective(quicksum(X[i, j, k] * Cost[i, j] for i in N for j in N for k in K), 'minimize')# 车辆起点约束# 车辆起点约束vrptw_model.addConss(quicksum(X[depot, j, k] for j in N) == 1 for k in K)# 车辆路径连续约束vrptw_model.addConss(quicksum(X[i, j, k] for j in N if j != i) == quicksum(X[j, i, k] for j in N if j != i) for i in C for k in K)# 车辆终点约束vrptw_model.addConss(quicksum(X[j, depot, k] for j in N) == 1 for k in K)# 需求服务约束vrptw_model.addConss(quicksum(X[i, j, k] for k in K for j in N if j != i) == 1 for i in C)# 车辆容量约束vrptw_model.addConss(quicksum(Q[i] * X[i, j, k] for i in C for j in N if i != j) <= CAP for k in K)# 时间窗约束vrptw_model.addConss(T[i, k] + ST[i] + TT[i, j] - (1 - X[i, j, k]) * M <= T[j, k] for i in C for j in C for k in K if i != j)vrptw_model.addConss(T[i, k] >= ET[i] for i in N for k in K)vrptw_model.addConss(T[i, k] <= LT[i] for i in N for k in K)return vrptw_model, X, T
def draw_routes(route_list,x_coord,y_coord):for route in route_list:path_x = []path_y = []for n in route:path_x.append(x_coord[n])path_y.append(y_coord[n])plt.plot(path_x, path_y,linewidth=0.5, marker='s',ms=5)plt.show()
def save_file(route_list,route_timetable,total_cost):wb = xlsxwriter.Workbook('路径方案.xlsx')ws = wb.add_worksheet()ws.write(0,0,'总费用')ws.write(0,1,total_cost)ws.write(1,0,'车辆')ws.write(1,1,'路径')ws.write(1,2,'时刻')row = 2for id,route in enumerate(route_list):ws.write(row,0,route[0])route_str = [str(i) for i in route[1:]]ws.write(row,1,'-'.join(route_str))timetable_str = [str(i) for i in route_timetable[id]]ws.write(row,2,'-'.join(timetable_str))row += 1wb.close()
if __name__=='__main__':filename = './data/c201.csv'N, Q, TT, ET, LT, ST, Cost,x_coord,y_coord = read_input(filename)depot = N[0]K = list(range(1, 30))CAP = 80vrptw_model,X,T = build_model(N,Q,TT,ET,LT,ST,Cost,CAP,K)vrptw_model.setLogfile('./log/scip_c101.log')vrptw_model.setRealParam('limits/time', 2000) # 求解时间为1800svrptw_model.optimize()route_list = []route_timetable = []# 提取车辆路径for k in K:route = [depot]cur_node = depotcur_k = Nonefor j in N[1:]:if vrptw_model.getVal(X[depot, j, k]) > 0:cur_node = jcur_k = kroute.append(j)N.remove(j)breakif cur_k is None:continuewhile cur_node != depot:for j in N:if vrptw_model.getVal(X[cur_node, j, cur_k]) > 0:cur_node = jroute.append(j)if j != depot:N.remove(j)breakroute.insert(0,k)route_list.append(route)# 提取车辆的时刻点for route in route_list:k = route[0]timetable = []for i in route[1:]:timetable.append(vrptw_model.getVal(T[i,k]))route_timetable.append(timetable)print("最优路径距离:", vrptw_model.getObjVal())print("最优路径使用车辆数:", len(route_list))draw_routes(route_list, x_coord, y_coord)save_file(route_list, route_timetable, vrptw_model.getObjVal())
7. 测试案例
本期从solomon数据集中选择了c101,c201,cr101三个算例用于测评。
CVRP问题数据结构如下(保留30个节点):
VRPTW问题数据结构如下(保留100个节点):
8. 测试参数
软件版本号:
Gurbi:9.5.1
SCIP:8.0.0
COPT:5.0.1
CVRP相关参数设置:
车辆容量:80
车队规模:10
客户节点:30
求解时间:1200s
VRPTW相关参数设置:
车辆容量:80
车队规模:30
客户节点:100
求解时间:1500s
9. 测试结果
9.1 CVRP求解结果汇总
对于CVRP问题,在相同的求解时间下,Gurobi在求解质量方面有最好的表现,COPT比SCIP略差。
9.2 VRPTW求解结果汇总
对于VRPTW问题,在相同的求解时间下,Gurobi可以找到不错的优化解,而COPT和SCIP并未找到初始解。
9.3 上界下降曲线对比(以CVRP为例)
从上界下降曲线可以看出,Gurobi找到的初始可行解的质量最好,且收敛性最好,而COPT和SCIP的初始解质量相差不大,收敛性不如Gurobi。
9.5 车辆路径可视化(以CVRP为例)
c101-31(Gurobi)
c201-31(Gurobi)
r101-31(Gurobi)
10. 小节
根据以上测试结果,Gurobi的求解性能远优于SCIP和COPT,作为后起之秀COPT已经接近SCIP水平(最新版的COPT尚未测试,也许性能有更大提升)。
虽然求解器可以直接对数学模型进行求解,但仅在小规模案例上具有较好的性能,对于大规模问题仍需要设计更高效的算法。
小编后续将继续分享VRP问题系列求解算法,并将其求解效果与上述求解器进行比较。
相关文章:
软件工具 | Python调用运筹优化求解器(一):以CVRPVRPTW为例
目录 1. 引言2. 求解器介绍3. 基础语言3.1 创建模型3.2 添加变量3.3 添加目标函数3.4 添加约束3.5 设置参数3.6 求解 4. 数学模型4.1 [CVRP数学模型](https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw)4.2 [VRPTW数学模型](https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItue…...
如何在JAVA中实现网络编程?
在Java中实现网络编程通常需要使用Java提供的网络编程库——Java Networking API。Java Networking API支持常见的TCP和UDP协议,包括Socket、ServerSocket、DatagramSocket等类,通过这些类,我们可以创建、连接、监听和传输数据。 下面是在Ja…...
【redis】redis的缓存过期淘汰策略
【redis】redis的缓存过期淘汰策略 文章目录 【redis】redis的缓存过期淘汰策略前言一、面试题二、redis内存满了怎么办?1、redis默认内存是多少?在哪查看?如何修改?在conf配置文件中可以查看 修改,内存默认是0redis的默认内存有…...
ASP.NET动态Web开发技术第8章
第8章ASP.NET数据访问 一.预习笔记 1.SqlDataSource控件 SqlDataSource数据源控件支持连接SQL关系数据库,它使用SQL命令来检索和修改数据。通常将SqlDataSource数据源控件与数据绑定控件一起使用。 属性1:ID:当前数据源控件的唯一标识符 …...
【旋转编码器如何工作以及如何将其与Arduino一起使用】
在本教程中,我们将学习旋转编码器的工作原理以及如何将其与Arduino一起使用。您可以观看以下视频或阅读下面的书面教程。 1. 概述 旋转编码器是一种位置传感器,用于确定旋转轴的角度位置。它根据旋转运动产生模拟或数字电信号。 有许多不同类型的旋转编码器按输出信号或传感…...
Tre靶场通关过程(linpeas使用+启动项编辑器提权)
Tre靶场通关 通过信息收集获得到了普通用户账号密码,利用PEASS-ng的linpeas脚本进行提权的信息收集,根据已有信息进行提权。 靶机下载地址: https://download.vulnhub.com/tre/Tre.zip 信息收集 靶机IP探测:192.168.0.129 a…...
java多线程下
ThreadLocal ThreadLocal 有什么用?通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢?JDK 中自带的ThreadLocal类正是为了解决这样的问题。 ThreadLocal类主要解决的就…...
使用无标注的数据训练Bert
文章目录 1、准备用于训练的数据集2、处理数据集3、克隆代码4、运行代码5、将ckpt模型转为bin模型使其可在pytorch中运用 Bert官方仓库:https://github.com/google-research/bert 1、准备用于训练的数据集 此处准备的是BBC news的数据集,下载链接&…...
《Netty》从零开始学netty源码(五十二)之PoolThreadCache
PoolThreadCache Netty有一个大的公共内存容器PoolArena,用来管理从操作系统中获得的内存,在高并发下如果所有线程都去这个大容器获取内存它的压力是非常大的,所以Netty为每个线程建立了一个本地缓存,即PoolThreadCacheÿ…...
放弃40k月薪的程序员工作,选择公务员,我来分享一下看法
我有一个朋友,拒绝了我为他提供的4万薪水的工作,去了一个体制内的银行,做程序员,即使薪水减半。他之前在北京一家大公司做程序员,一个月30k。当我开始创业时,我拉他来和我一起干,但那时我们太小…...
【MybatisPlus】高级版可视化、可配置 自动生成代码
今天看别人使用了一个更加智能的生成代码工具,可视化、可配置策略,非常方便,配置一次,在哪都可以使用,也不会跟项目藕合下面简单说一下使用方式。 1、介绍mybatis-plus-generator-ui 主要是封装了mybatis-plus-gener…...
【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现
【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现 提示:最近开始在【图像分割】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【图像分割】【深度学习】Windows10下f-BRS官方代码Pytorch实现前言f-BRS模型运行环境安装1.下载源码并…...
2023/5/4总结
刷题: 第二周任务 - Virtual Judge (vjudge.net) 这一题用到了素筛,然后穷举即可 #include<stdio.h> #define Maxsize 500000 int a[Maxsize]; long long b[Maxsize]; long long max0; int sushu() {a[0]a[1]0;int i,j,k;for(i2,k0;i<Maxsize;i){if(a[i…...
electron+vue3全家桶+vite项目搭建【17】pinia状态持久化
文章目录 引入问题演示实现效果展示、实现步骤1.封装状态初始化函数2.封装状态更新同步函数3.完整代码 引入 上一篇文章我们已经实现了electron多窗口中,pinia的状态同步,但你会发现,如果我们在一个窗口里面修改了状态,然后再打开…...
java基础入门-05-【面向对象进阶(static继承)】
Java基础入门-05-【面向对象进阶(static&继承)】 13、面向对象进阶(static&继承)1.1 如何定义类1.2 如何通过类创建对象1.3 封装1.3.1 封装的步骤1.3.2 封装的步骤实现 1.4 构造方法1.4.1 构造方法的作用1.4.2 构造方法的…...
day12 IP协议与ethernet协议
目录 IP包头 IP网的意义 IP数据报的格式 IP数据报分片 以太网包头(链路层协议) IP包头 IP网的意义 当互联网上的主机进行通信时,就好像在一个网络上通信一样,看不见互联的各具体的网络异构细节; 如果在这种覆盖…...
蓝牙耳机哪款性价比高?2023蓝牙耳机性价比排行
随着蓝牙耳机的使用愈发频繁,蓝牙耳机产品也越来越多,蓝牙耳机的功能、价格、外观设计等都不尽相同。接下来,我来给大家推荐几款性价比高的蓝牙耳机,感兴趣的朋友一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 参考价:…...
关于C语言的一些笔记
文章目录 May4,2023常量问题基本数据类型补码printf的字符格式控制关于异或、异或的理解赋值运算i和i的区别关系运算符 May5,2023逻辑运算中‘非’的理解逗号运算运算符的优先级问题三目运算 摘自加工于C技能树 May4,2023 常量问题 //定义常量 const float PI; PI…...
【Python入门知识】NumPy数组迭代及连接
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 数组迭代 迭代意味着逐一遍历元素,当我们在 numpy 中处理多维数组时, 可以使用 python 的基本 for 循环来完成此操作。 如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。 实例 迭…...
我们公司的面试,有点不一样!
我们公司的面试,有点不一样! 朋友们周末愉快,我是鱼皮。因为我很屑,所以大家也可以叫我屑老板。 自从我发了自己创业的文章和视频后,收到了很多小伙伴们的祝福,真心非常感谢! 不得不说&#…...
C++之初识STL—vector
文章目录 STL基本概念使用STL的好处容器vector1.vector容器简介2.vector对象的默认构造函数3.vector对象的带参构造函数4.vector的赋值5.vector的大小6.vector容器的访问方式7.vector的插入 STL基本概念 STL(Standard Template Library,标准模板库)STL 从广义上分为: 容器(con…...
资讯汇总230503
230503 12:21 【放松身心亲近自然 自驾露营成旅游新风尚】今年“五一”假期,我国旅游业的快速恢复催生自驾露营休闲游、短途游、夜游等新型旅游产品提质升级。快速发展的新兴旅游业态,在促进旅游消费、培育绿色健康生活方式等方面发挥了积极作用…...
C++之编程规范
目录 谷歌C风格指南:https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/ 编码规则: • 开闭原则:软件对扩展是开放的,对修改是关闭的 • 防御式编程:简单的说就是程序不能崩溃 •…...
ChatGPT做PPT方案,10组提示词方案!
今天我们要搞定的PPT内容是: 活动类型:节日活动、会员活动、新品活动分析类型:用户分析、新品立项、项目汇报内容类型:内容规划、品牌策划 用到的工具: mindshow 邀请码 6509097ChatGPT传送门(免费使用…...
分布式夺命12连问
分布式理论 1. 说说CAP原则? CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)这3个基本…...
sourceTree离线环境部署
目录 1、下载sourceTree安装包,打开之后弹出注册界面(需要去国外网站注册)2、使用技术手段跳过注册步骤3、打开安装包进行安装 注:建议提前安装好git 1、下载sourceTree安装包,打开之后弹出注册界面(需要去…...
6.1.1 图:基本概念
一,基本概念 1.基本定义 (1)图的定义 顶点集不可以是空集,但边集可以是空集。 (2) 有向图的表示: 圆括号 无向图的表示: 尖括号 简单图、多重图: 简单图:…...
SlickEdit for Windows and Linux crack
SlickEdit for Windows and Linux crack 现在可以在“新建注释”对话框中对颜色进行排序,使调色板中的颜色阵列看起来更符合逻辑。 在拆分或扩展行注释时添加了撤消步骤,这样您只需点击“撤消”一次即可撤消行注释扩展。 已更新VHDL颜色编码,…...
ChatGPT实现stackoverflow 解释
stackoverflow 解释 ChatGPT 公开服务以来,程序员们无疑是最早深入体验和"测试"的一批人。出色的效果也引发了一系列知识产权上的争议。著名的 stackoverflow 网站,就宣布禁止用户使用 ChatGPT 生成的内容来回答问题,一经发现&…...
第五章 作业(123)【编译原理】
第五章 作业【编译原理】 前言推荐第五章 作业123 随堂练习课前热身04-17随堂练习04-17课前热身04-24 最后 前言 2023-5-3 22:12:46 以下内容源自《【编译原理】》 仅供学习交流使用 推荐 第四章 作业(123)【编译原理】 第五章 作业 1 1.令文法G为…...
超炫的网站/网络推广策划方案怎么写
1:java 的最大特点及实现原理跨平台实现原理:java首先利用文本编辑器编写java源程序,源文件的后缀名为.java;再利用编译器(javac)将程序编译为字节码文件,字节码文件的后缀名.class;…...
360度全景网站的公司/友情链接发布网
转自:https://blog.csdn.net/longfei_2010/article/details/79785320 1、编辑(Editing) Ctrl Space 基本的代码完成(类、方法、属性) Ctrl Alt Space 快速导入任意类 Ctrl Shift Enter 语句完成 Ctrl P 参数信息…...
wordpress讨论吧/市场调研报告范文3000字
LP Wizard10.5破解笔记: 首先下载完安装包(附破解包)后解压会有两个文件夹, 1.先运行一次Crack.vbs,路径空着 2.点LPWizard_mib.exe安装软件,安装到默认路径,不安装license。 3.再运行一次Crack…...
家具制作网站/新型实体企业100强
这个错误通常是由于卷积层(Convolutional layer)的输入通道数与卷积核(Convolutional kernel)的通道数不匹配导致的。具体地说,卷积核的通道数应该与输入 tensor 的通道数相同。 在你的代码中,卷积层的卷积…...
石家庄栾城区建设局网站/沈阳百度seo排名优化软件
2019独角兽企业重金招聘Python工程师标准>>> 5.5 进入编辑模式 i 在当前字符插入字符 I行首 a在当前字符后插入字符 A行末 o在当前往下插入新的一行 O行上 在空白文档中写入一段文字并保存。 输入vim demo.txt直接回车进入一般模式。然后按 “i” 字母进入编辑模式&…...
做装饰画的行业网站/深圳推广公司有哪些
在一万英尺的天空一跃而下感受肾上腺素飙升带来的快感嗯没错,就是这种感觉如果跳伞是你人生TO DO LIST中的一个空白项,那就不要再犹豫了,将这项空白填充起来,就能够发现,在天空中的这段时间,将会是自己未来…...