def alg_odlink_default(network_name, bool_display=True): data = read_data(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] matrix = gen_matrix(data) node_odlink_relation = matrix['node_odlink_relation'] node_oddemand = matrix['node_oddemand'] od_odlink_relation = matrix['od_odlink_relation'] start_time = time.time() x_odlink = cp.Variable(link_number * od_number) x_link = od_odlink_relation @ x_odlink objective = cp.Minimize( cp.sum(link_free * x_link) + cp.sum(link_free * para_a / (para_b + 1) * link_capacity * cp.power(x_link / link_capacity, para_b + 1))) constraints = [ x_odlink >= 0, node_odlink_relation @ x_odlink - node_oddemand == 0 ] result = cp.Problem( objective=objective, constraints=constraints).solve() # reltol=1e-15, abstol=1e-15 target_value = objective.value link_flow = od_odlink_relation @ x_odlink.value runtime = time.time() - start_time if bool_display: print('----alg_odlink_default----') print(f'target_value: {target_value}') print(f'link_flow: {link_flow}') print(f'runtime: {runtime}') print('--------')
def alg_route_default(network_name, bool_display=True): start_time = time.time() data = read_data_plus_route(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] od_route_incidence = data['od_route_incidence'] route_link_incidence = data['route_link_incidence'] route_number = data['route_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] x_route_flow = cp.Variable(route_number) x_link_flow = x_route_flow @ route_link_incidence objective = cp.Minimize(cp.sum(link_free * x_link_flow) + cp.sum( link_free * para_a / (para_b + 1) * link_capacity * cp.power(x_link_flow / link_capacity, para_b + 1))) constraints = [x_route_flow >= 0, od_route_incidence @ x_route_flow == od_demand] result = cp.Problem(objective=objective, constraints=constraints).solve() current_link_flow = x_link_flow.value optimal_value = objective.value if bool_display: print('----alg_route_default----') print(f"current_link_flow:{current_link_flow}") print(f"optimal_value:{optimal_value}") print(f'runtime:{time.time() - start_time}') print('----')
def algorithm_route_vi(data_with_route_variable, bool_display=True, bool_display_iteration=True): gp.setParam('OutputFlag', 0) link_node_pair = data_with_route_variable['link_node_pair'] link_capacity = data_with_route_variable['link_capacity'] link_free = data_with_route_variable['link_free_flow_time'] od_node_pair = data_with_route_variable['od_node_pair'] od_demand = data_with_route_variable['od_demand'] od_number = data_with_route_variable['od_number'] link_number = data_with_route_variable['link_number'] node_number = data_with_route_variable['node_number'] od_route_incidence = data_with_route_variable['od_route_incidence'] route_link_incidence = data_with_route_variable['route_link_incidence'] route_number = data_with_route_variable['route_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] def cal_objective_value_from_route_flow(route_flow): link_flow = route_flow @ route_link_incidence objective_value = (link_free * link_flow + link_free * para_a / (para_b + 1) * link_capacity * ( (link_flow / link_capacity) ** (para_b + 1))).sum() return objective_value def cal_route_time(cf): rf = cf / 1 lf = rf @ route_link_incidence lt = link_free * (1 + para_a * (lf ** para_b) / (link_capacity ** para_b)) rt = route_link_incidence @ lt ct = rt + 0 return ct od_route_number = od_route_incidence.sum(axis=1) initial_route_flow = (od_demand / od_route_number) @ od_route_incidence optimal_value = cal_objective_value_from_route_flow(initial_route_flow) current_route_flow = initial_route_flow tolerance = 1e-15 iteration_number = 5000 termination_bool = False optimum_bool = False iteration_index = 0 while not (termination_bool or optimum_bool): current_route_cost = cal_route_time(current_route_flow) matrix_h = np.eye(route_number) rho = 0.1 matrix_quadratic = matrix_h / 2 vector_quadratic = rho * current_route_cost.reshape([1, route_number]) - matrix_h @ current_route_flow m = gp.Model() var = m.addMVar(shape=route_number, lb=0.0) m.addConstr(od_route_incidence @ var == od_demand) m.setObjective(var @ matrix_quadratic @ var + vector_quadratic @ var, GRB.MINIMIZE) m.optimize() new_route_flow = var.x temp_value = cal_objective_value_from_route_flow(new_route_flow) if iteration_index != 0: gap = np.abs((temp_value - optimal_value) / optimal_value) else: gap = 1 if gap < tolerance: optimum_bool = True elif iteration_index == iteration_number: termination_bool = True optimal_value = temp_value current_route_flow = new_route_flow iteration_index += 1 if bool_display_iteration: print('----iteration_of_algorithm_route_vi----') print(f'iteration_index:{iteration_index}') print(f'gap:{gap}') print(f'optimal_value:{optimal_value}') print('--------') if bool_display: print('----algorithm_route_vi----') print(f'iteration_index:{iteration_index}') print(f'optimum_bool:{optimum_bool}') print(f'gap:{gap}') print(f'current_route_flow:{current_route_flow}') print(f'cost:{cal_route_time(current_route_flow)}') print(f'optimal_value:{optimal_value}') print('--------') return current_route_flow, optimal_value
# @Author : gzzang # @File : verification # @Project : traffic_assignment from preparation import read_data from preparation import set_parameter import pickle import numpy as np data = read_data() link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] with open('flow.pkl', 'rb') as f: current_link_flow = pickle.load(f) function_value = np.sum(link_free * current_link_flow) + np.sum( link_free * para_a / (para_b + 1) * link_capacity * np.power(current_link_flow / link_capacity, para_b + 1)) print(function_value)
def alg_odlink_fw_optimization(network_name, bool_display=True, bool_display_iteration=True): data = read_data(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] matrix = gen_matrix(data) node_odlink_relation = matrix['node_odlink_relation'] node_oddemand = matrix['node_oddemand'] od_odlink_relation = matrix['od_odlink_relation'] def cal_odlink_flow(current_odlink_flow): """ 根据路段时间计算基于最短路的全有全无路段流量 :param link_time: :return: """ def derivative(xx_odlink): return link_free * (1 + para_a * (od_odlink_relation @ xx_odlink / link_capacity)**para_b) @ od_odlink_relation x_odlink_flow = cp.Variable(link_number * od_number) odlink_derivative = derivative(current_odlink_flow) objective = cp.Minimize(odlink_derivative @ x_odlink_flow) constraints = [ x_odlink_flow >= 0, node_odlink_relation @ x_odlink_flow - node_oddemand == 0 ] cp.Problem(objective=objective, constraints=constraints).solve() return x_odlink_flow.value current_odlink_flow = cal_odlink_flow(np.zeros(link_number * od_number)) target_gap = 1e-7 iteration_number = 1000 termination_bool = False optimum_bool = False iteration_index = 0 while not (termination_bool or optimum_bool): optimal_vertex = cal_odlink_flow(current_odlink_flow) direction = optimal_vertex - current_odlink_flow current_odlink_flow, temp_value = algorithm_line_search( current_odlink_flow, direction, od_odlink_relation, link_free, para_a, para_b, link_capacity) if iteration_index == 0: gap = 1 else: gap = np.abs((temp_value - optimal_value) / optimal_value) if gap < target_gap: optimum_bool = True elif iteration_index == iteration_number: termination_bool = True optimal_value = temp_value iteration_index += 1 if bool_display_iteration: print('--------') print(f"gap:{gap}") print(f"iteration_index:{iteration_index}") print('--------') if bool_display: print('----alg_odlink_fw_optimization----') print(f"optimum_bool:{optimum_bool}") print(f"iteration_index:{iteration_index}") print(f"optimal_vertex:{optimal_vertex}") print(f"direction:{direction}") print(f'final:{current_odlink_flow}') print(f'value:{optimal_value}') print('--------')
def alg_link_fw_sp(network_name, bool_display=True, bool_display_iteration=True): data = read_data(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] g = ig.Graph() g.add_vertices(node_number) g.add_edges(link_node_pair) def cal_direction_link_flow(link_flow): """ 根据路段时间计算基于最短路的全有全无路段流量 :param link_flow: :return: """ def cal_link_time(link_flow): return link_free * (1 + para_a * (link_flow / link_capacity)**para_b) g.es['weight'] = cal_link_time(link_flow) optimal_link_flow = np.zeros_like(link_flow) for od, demand in zip(od_node_pair, od_demand): shortest_path_link_flow = np.zeros_like(link_flow) shortest_path_link_flow[g.get_shortest_paths( od[0], to=od[1], weights='weight', output='epath')[0]] = demand optimal_link_flow += shortest_path_link_flow return optimal_link_flow - link_flow start_time = time.time() current_link_flow = cal_direction_link_flow(np.zeros_like(link_free)) target_gap = 1e-7 iteration_number = 1000 termination_bool = False optimum_bool = False iteration_index = 0 while not (termination_bool or optimum_bool): direction_link_flow = cal_direction_link_flow(current_link_flow) current_link_flow, temp_value = algorithm_line_search_link( current_link_flow, direction_link_flow, link_free, para_a, para_b, link_capacity) if iteration_index == 0: gap = 1 else: gap = np.abs((temp_value - optimal_value) / optimal_value) if gap < target_gap: optimum_bool = True elif iteration_index == iteration_number: termination_bool = True optimal_value = temp_value iteration_index += 1 if bool_display_iteration: print() print(f"gap:{gap}") print(f"iteration_index:{iteration_index}") if bool_display: print('----alg_link_fw_sp----') print(f"direction_link_flow:{direction_link_flow}") print(f'final:{current_link_flow}') print(f'value:{optimal_value}') print('--------') print(f'runtime:{time.time() - start_time}')
def alg_link_cg(network_name, bool_display=True, bool_display_iteration=True, bool_route_result_output=False): data = read_data(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] g = ig.Graph() g.add_vertices(node_number) g.add_edges(link_node_pair) def cal_sp_of_one_od(link_flow, node_list): link_time = link_free * (1 + para_a * (link_flow / link_capacity)**para_b) g.es['weight'] = link_time node_incidence = np.zeros_like(link_flow, dtype=bool) node_incidence[g.get_shortest_paths(node_list[0], to=node_list[1], weights='weight', output='epath')[0]] = True return node_incidence start_time = time.time() initial_od_list_route_link_incidence = [] zero_link_flow = np.zeros_like(link_free) for one_pair_list in od_node_pair: sp_link_incidence = cal_sp_of_one_od(zero_link_flow, one_pair_list) initial_od_list_route_link_incidence.append( sp_link_incidence.reshape([1, link_number])) initial_route_link_incidence = np.vstack( initial_od_list_route_link_incidence) current_link_flow = od_demand @ initial_route_link_incidence current_od_list_route_link_incidence = initial_od_list_route_link_incidence iteration_number = 20 target_gap = 1e-20 termination_bool = False optimum_bool = False iteration_index = 0 while not (termination_bool or optimum_bool): for od_index, (one_route_link_incidence, one_pair_list) in enumerate( zip(current_od_list_route_link_incidence, od_node_pair)): sp_link_incidence = cal_sp_of_one_od(current_link_flow, one_pair_list) if not np.any( np.all(one_route_link_incidence == sp_link_incidence, axis=1)): current_od_list_route_link_incidence[od_index] = np.vstack( (one_route_link_incidence, sp_link_incidence)) route_link_incidence = np.vstack(current_od_list_route_link_incidence) od_route_number = np.array([ one_route_link_array.shape[0] for one_route_link_array in current_od_list_route_link_incidence ]) route_number = np.sum(od_route_number) od_route_incidence = np.zeros([od_number, route_number], dtype=bool) temp = 0 for od_index, value in enumerate(od_route_number): od_route_incidence[od_index, temp:(temp + value)] = True temp += value data_with_route_variable = data data_with_route_variable['od_route_incidence'] = od_route_incidence data_with_route_variable['route_link_incidence'] = route_link_incidence data_with_route_variable['route_number'] = route_link_incidence.shape[ 0] # current_route_flow, temp_value = algorithm_route_vi(data_with_route_variable, bool_display=False, # bool_display_iteration=False) # current_route_flow, temp_value = algorithm_route_mp(data_with_route_variable, bool_display=False) current_route_flow, temp_value = algorithm_route_msa( data_with_route_variable, bool_display=False) current_link_flow = current_route_flow @ route_link_incidence if iteration_index != 0: gap = np.abs((temp_value - optimal_value) / optimal_value) else: gap = 1 if gap < target_gap: optimum_bool = True elif iteration_index == iteration_number: termination_bool = True optimal_value = temp_value iteration_index += 1 if bool_display: if bool_display_iteration: print('----iteration_alg_link_cg_default----') print(f"iteration_index:{iteration_index}") print(f'gap:{gap}') print(f"od_route_number:{od_route_number}") print(f"current_link_flow:{current_link_flow}") print(f"optimal_value:{optimal_value}") print('--------') if bool_display: print('----alg_link_cg_default----') print(f'optimum_bool:{optimum_bool}') print(f'gap:{gap}') print(f"iteration_index:{iteration_index}") print(f"od_route_number:{od_route_number}") print(f"current_link_flow:{current_link_flow}") print(f"optimal_value:{optimal_value}") print(f'runtime:{time.time() - start_time}') print('--------') if bool_route_result_output: print('--------') print(f'bool_route_result_output:{bool_route_result_output}') print('--------') output_path = 'output' if not os.path.exists(output_path): os.makedirs(output_path) pd.DataFrame({ string: value for string, value in zip(( 'route_index', 'link_index'), np.nonzero(route_link_incidence)) }).to_csv(output_path + '/' + network_name + '_route_link_relation.csv', index=False) pd.DataFrame({ string: value for string, value in zip(( 'od_index', 'route_index'), np.nonzero(od_route_incidence)) }).to_csv(output_path + '/' + network_name + '_od_route_relation.csv', index=False)
def alg_route_msa(network_name, bool_display=True, bool_display_iteration=True): start_time = time.time() def cal_objective_value_from_route_flow(route_flow): link_flow = route_flow @ route_link_incidence objective_value = (link_free * link_flow + link_free * para_a / (para_b + 1) * link_capacity * ( (link_flow / link_capacity) ** (para_b + 1))).sum() return objective_value data = read_data_plus_route(network_name) link_node_pair = data['link_node_pair'] link_capacity = data['link_capacity'] link_free = data['link_free_flow_time'] od_node_pair = data['od_node_pair'] od_demand = data['od_demand'] od_number = data['od_number'] link_number = data['link_number'] node_number = data['node_number'] od_route_incidence = data['od_route_incidence'] route_link_incidence = data['route_link_incidence'] route_number = data['route_number'] parameter = set_parameter() para_a = parameter['a'] para_b = parameter['b'] od_route_number = od_route_incidence.sum(axis=1) current_route_flow = (od_demand / od_route_number) @ od_route_incidence optimal_value = cal_objective_value_from_route_flow(current_route_flow) tolerance = 1e-9 iteration_number = 1000 termination_bool = False optimum_bool = False iteration_index = 0 while not (termination_bool or optimum_bool): link_flow = current_route_flow @ route_link_incidence link_time = link_free * (1 + para_a * (link_flow ** 4) / (link_capacity ** 4)) route_time = route_link_incidence @ link_time od_route_time_incidence = np.inf * np.ones_like(od_route_incidence) od_route_time_incidence[od_route_incidence] = route_time od_minimal_route_time_index = od_route_time_incidence.argmin(axis=1) new_route_flow = np.zeros_like(current_route_flow) new_route_flow[od_minimal_route_time_index] = od_demand temp_route_flow = (iteration_index + 1) / (iteration_index + 2) * current_route_flow + 1 / ( iteration_index + 2) * new_route_flow temp_value = cal_objective_value_from_route_flow(temp_route_flow) if iteration_index != 0: gap = np.abs((temp_value - optimal_value) / optimal_value) else: gap = 1 if gap < tolerance: optimum_bool = True elif iteration_index == iteration_number: termination_bool = True current_route_flow = temp_route_flow optimal_value = temp_value iteration_index += 1 if bool_display_iteration: print('-----------------------------------') print(f"iteration_index:{iteration_index}") print(f"gap:{gap}") print(f"current_link_flow:{current_route_flow}") print(f"optimal_value:{optimal_value}") print('-----------------------------------') if bool_display: print('----alg_route_msa----') print(f"iteration_index:{iteration_index}") print(f"gap:{gap}") print(f"tolerance:{tolerance}") print(f"optimum_bool:{optimum_bool}") print(f"current_route_flow:{current_route_flow}") print(f"optimal_value:{optimal_value}") print(f'runtime:{time.time() - start_time}') print('--------')