예제 #1
0
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('----')
예제 #3
0
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
예제 #4
0
# @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)
예제 #5
0
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}')
예제 #7
0
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)
예제 #8
0
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('--------')