第1问和第2问的区别
第一问的时候拼货只发生在公司内部,所以两个公司需要分别构建图,求解两次
第二问的时候,拼货可以在公司之间发生,所以将两次的货物合起来,求解一次
代码
import numpy as np
import pandas as pd
import kaiwu as kw
import kaiwu.qubo as kq
from utils import SubQuboSolver # 根据参考论文实现
def kw_integer(name):
return kq.Integer(name, 0, 3) # 根据实际情况调整
class CIMSolver:
def __init__(self):
"""初始化参数"""
self.num_node = 6
self.time_limit = 7
self.dis = None
self.price_rent = np.array([5000, 3000])
self.capacity_v = np.array([12, 5])
self.price_v = np.zeros((2, self.num_node, self.num_node))
self.storage = None
self.demand = None
self.price_air = 10000
self.ising_model = None
def prepare_data(self):
"""载入数据,可以粘贴到文件或者代码硬编码"""
self.dis = pd.read_csv("data/D.csv", header=None, index_col=None).to_numpy()
self.price_v[0] = pd.read_csv("data/PA.csv", header=None,
index_col=None).to_numpy()
self.price_v[1] = pd.read_csv("data/PB.csv", header=None,
index_col=None).to_numpy()
self.storage = pd.read_csv("data/storage.csv", header=None,
index_col=None).to_numpy()
self.demand = pd.read_csv("data/demand.csv", header=None,
index_col=None).to_numpy()
def prepare_model(self):
"""QUBO建模"""
num_vehicle = kq.ndarray((self.time_limit, 2,
self.num_node, self.num_node), "n", kw_integer)
vehicle = kq.ndarray((self.time_limit, 2,
self.num_node, self.num_node), "x", kw_integer)
air = kq.ndarray((self.num_node, self.num_node), "f", kw_integer)
air_cost = air.sum() * self.price_air
# 剪枝,减少变量数
for i in range(self.num_node):
for j in range(self.num_node):
if i == j:
num_vehicle[:, :, i, j] = 0
vehicle[:, :, i, j] = 0
air[i, j] = 0
for t in range(self.time_limit):
for k in range(self.num_type):
if t + self.dis[i, j] >= self.time_limit:
num_vehicle[t, k, i, j] = 0
vehicle[t, k, i, j] = 0
tmp = num_vehicle * self.price_rent[None, :, None, None]
vehicle_rent_cost = tmp.sum(axis=1)* self.dis[np.newaxis, :]
vehicle_rent_cost = vehicle_rent_cost.sum()
vehicle_cost = (num_vehicle * self.price_v[None, :]).sum()
constr_c_slack = kq.ndarray((self.time_limit, 2,
self.num_node, self.num_node), "c_slk", kw_integer)
# 松弛变量可以通过ALM求解去掉
capacity_limit = num_vehicle * self.capacity_v[None, :, None, None]
constr_capacity = (vehicle - capacity_limit + constr_c_slack) ** 2
constr_capacity = constr_capacity.sum()
constr_e_slack = kq.ndarray((1, self.num_node), "e_slk", kw_integer)
trans_out = np.zeros((self.time_limit,
self.num_node, self.num_node), dtype=object)
for t in range(self.time_limit):
for i in range(self.num_node):
for j in range(self.num_node):
if t-self.dis[i, j] >= 0:
trans_out[t, i, j] += vehicle[t-self.dis[i, j], :, i, j].sum()
if t > 0:
trans_out[t] += trans_out[t - 1]
constr_equ = (self.storage - air.sum(axis=1)[None, :] + trans_out.sum(axis=2)\
- vehicle.sum(axis=(1,3)) + constr_e_slack) ** 2
constr_equ = constr_equ.sum()
constr_demand = trans_out[-1].sum(axis=0) + air.sum(axis=1) - \
vehicle.sum(axis=(0, 1, 3)) - self.demand
constr_demand = (constr_demand ** 2).sum()
obj = air_cost + vehicle_cost
constr = constr_capacity + constr_equ + constr_demand
qubo_made = kq.make(obj + 100 * constr)
self.ising_model = kq.qubo_model_to_ising_model(qubo_made)
def solve(self):
"""求解"""
self.prepare_data()
self.prepare_model()
ising_mat = self.ising_model.get_ising()["ising"]
worker = SubQuboSolver()
output = worker.solve(ising_mat)
# Sort the results
opt = kw.sampler.optimal_sampler(ising_mat, output, bias=0, negtail_ff=False)
# Select the best solution
cim_best = opt[0][0]
# If the linear term variable is -1, perform a flip
cim_best = cim_best * cim_best[-1]
return cim_best
if __name__ == "__main__":
kw.init
solver = CIMSolver()
solver.solve()
总结
电商平台迅速发展加剧了对高效物流配送的需求,采用量子计算技术来优化运输策略是一个有效的方案。 通过求解QUBO模型,物流公司能够更有效地规划路线、选择运输方式,以降低成本并提升消费者满意度。