1. 介绍
cspy是一个有约束条件下生成最短路的一个算法包,它是好几个列生成开源算法包中用于列生成算法的基础算法包,主要是用于生成新的列。最开始用于公交司机调度问题,后面被广泛用于交通相关的问题中。
cspy是基于networkx的,性能上堪忧啊,可以考虑进行改造。算法清单包括:
BiDirectional: Bidirectional and monodirectional algorithms
Tabu Heuristic Tabu Search
GreedyElim Greedy Elimination Procedure
GRASP GRASP
PSOLGENT Particle Swarm Optimization with combined Local and Global Expanding Neighbourhood Topology (PSOLGENT)
2. 简单例子
首先要定义DiGraph,其中需要定义n_res变量。
然后G中的每一条边都要定义res_cost和weight属性,其中res_cost是numpy.array类型,用于资源约束;而weight是float,是最优化的目标函数
from cspy import Tabu
from networkx import DiGraph
from numpy import array
G = DiGraph(directed=True, n_res=2)
G.add_edge('Source', 'A', res_cost=array([1, 1]), weight=1)
G.add_edge('Source', 'B', res_cost=array([1, 1]), weight=1)
G.add_edge('A', 'C', res_cost=array([1, 1]), weight=1)
G.add_edge('B', 'C', res_cost=array([2, 1]), weight=-1)
G.add_edge('C', 'D', res_cost=array([1, 1]), weight=-1)
G.add_edge('D', 'E', res_cost=array([1, 1]), weight=1)
G.add_edge('D', 'F', res_cost=array([1, 1]), weight=1)
G.add_edge('F', 'Sink', res_cost=array([1, 1]), weight=1)
G.add_edge('E', 'Sink', res_cost=array([1, 1]), weight=1)
max_res, min_res = [5, 5], [0, 0]
tabu = Tabu(G, max_res, min_res)
tabu.run()
print(tabu.path)
3. 自定义例子
有的时候,资源约束需要自定义(比如time windows约束),下面是个例子:
from numpy import array
def REF_custom(cumulative_res, edge, **kwargs):
new_res = array(cumulative_res)
head_node, tail_node, egde_data = edge[0:3]
new_res[0] += 1
# Travel time
new_res[1] += edge_data['travel_time']
return new_res
使用的时候,增加一个REF:
tabu = Tabu(G, max_res, min_res, REF=jane_REF)