Exemple #1
0
    def find_equilibrium(self,
                         solver_name='ustm',
                         composite=True,
                         solver_kwargs={}):
        if solver_name == 'ustm':
            solver_func = ustm.universal_similar_triangles_method
            starting_msg = 'Universal similar triangles method...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs[
                    'L_init'] = 0.1 * self.graph.max_path_length * self.total_od_flow / self.gamma
        elif solver_name == 'ugd':
            solver_func = ugd.universal_gradient_descent_method
            starting_msg = 'Universal gradient descent method...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs[
                    'L_init'] = 0.1 * self.graph.max_path_length * self.total_od_flow / self.gamma
        else:
            raise NotImplementedError('Unknown solver!')

        phi_big_oracle = oracles.PhiBigOracle(self.graph,
                                              self.graph_correspondences,
                                              gamma=self.gamma)
        h_oracle = oracles.HOracle(self.graph.free_flow_times,
                                   self.graph.capacities,
                                   rho=self.rho,
                                   mu=self.mu)
        primal_dual_calculator = dfc.PrimalDualCalculator(
            phi_big_oracle,
            h_oracle,
            self.graph.free_flow_times,
            self.graph.capacities,
            rho=self.rho,
            mu=self.mu)
        if composite == True:
            print('Composite optimization...')
            oracle = phi_big_oracle
            prox = h_oracle.prox
        else:
            print('Non-composite optimization...')
            oracle = phi_big_oracle + h_oracle

            def prox_func(grad, point, A):
                """
                Computes argmin_{t: t \in Q} <g, t> + A / 2 * ||t - p||^2
                    where Q - the feasible set {t: t >= free_flow_times},
                    A - constant, g - (sub)gradient vector, p - point at which prox is calculated
                """
                return np.maximum(point - grad / A, self.graph.free_flow_times)

            prox = prox_func
        print('Oracles created...')
        print(starting_msg)

        result = solver_func(oracle,
                             prox,
                             primal_dual_calculator,
                             t_start=self.graph.free_flow_times,
                             **solver_kwargs)
        #TODO: add equilibrium travel times between zones
        return result
Exemple #2
0
    def find_equilibrium(self,
                         solver_name='ustf',
                         solver_kwargs={},
                         verbose=False):
        if solver_name == 'fwa':
            solver_func = fwa.frank_wolfe_algorithm
            starting_msg = 'Frank-Wolfe algorithm...'
        elif solver_name == 'ustf':
            solver_func = ustf.universal_similar_triangles_function
            starting_msg = 'Universal similar triangles function...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs[
                    'L_init'] = self.graph.max_path_length**0.5 * self.total_od_flow
        elif solver_name == 'ugd':
            solver_func = ugd.universal_gradient_descent_function
            starting_msg = 'Universal gradient descent...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs['L_init'] = 1.0
        elif solver_name == 'sd':
            solver_func = ugd.universal_gradient_descent_function
            starting_msg = 'Subgradient descent...'
        elif solver_name == 'uagmsdr':
            solver_func = uagmsdr.UAGMsDR
            starting_msg = 'Universal Accelerated Gradient Method with Small-Dimensional Relaxation...'
        else:
            raise NotImplementedError('Unknown solver!')

        if solver_name in ['ugd', 'ustf', 'sd', 'uagmsdr']:
            prox_h = ProxH(self.graph.freeflow_times,
                           self.graph.capacities,
                           mu=self.mu,
                           rho=self.rho)

        phi_big_oracle = oracles.PhiBigOracle(self.graph,
                                              self.graph_correspondences)
        primal_dual_calculator = dfc.PrimalDualCalculator(
            phi_big_oracle,
            self.graph.freeflow_times,
            self.graph.capacities,
            mu=self.mu,
            rho=self.rho)
        if verbose:
            print('Oracles created...')
            print(starting_msg)

        if solver_name == 'fwa':
            result = solver_func(phi_big_oracle,
                                 primal_dual_calculator,
                                 t_start=self.graph.freeflow_times,
                                 verbose=verbose,
                                 **solver_kwargs)
        else:
            result = solver_func(phi_big_oracle,
                                 prox_h,
                                 primal_dual_calculator,
                                 t_start=self.graph.freeflow_times,
                                 verbose=verbose,
                                 **solver_kwargs)

        return result
Exemple #3
0
def model_solve(graph,
                graph_correspondences,
                total_od_flow,
                solver_name='ustf',
                gamma=1.0,
                mu=0.25,
                rho=1.0,
                epsilon=1e-3,
                max_iter=1000,
                verbose=False):
    if solver_name == 'ustf':
        solver_func = ustf.universal_similar_triangles_function
        phi_small_solver_func = pss.PhiSmallSolver
        starting_msg = 'Universal similar triangles function...'
    elif solver_name == 'ugd':
        solver_func = ugd.universal_gradient_descent_function
        phi_small_solver_func = ug_pss.UnivGradPhiSmallSolver
        starting_msg = 'Universal gradient descent...'
    else:
        print('Define function!')

    #L_init = 1.0
    L_init = 0.1 * graph.max_path_length * total_od_flow / gamma
    phi_small_solver = phi_small_solver_func(graph.free_flow_times,
                                             graph.capacities,
                                             rho=rho,
                                             mu=mu)

    phi_big_oracle = oracles.PhiBigOracle(graph,
                                          graph_correspondences,
                                          gamma=gamma)
    primal_dual_calculator = dfc.PrimalDualCalculator(phi_big_oracle,
                                                      graph.free_flow_times,
                                                      graph.capacities,
                                                      rho=rho,
                                                      mu=mu)
    if verbose:
        print('Oracles created...')
        print(starting_msg)
    result = solver_func(phi_big_oracle,
                         phi_small_solver,
                         primal_dual_calculator,
                         graph.free_flow_times,
                         L_init,
                         max_iter=max_iter,
                         epsilon=epsilon,
                         verbose=verbose)

    #t_average_w = phi_big_oracle.time_av_w_matrix(t_result)
    return result
Exemple #4
0
    def __init__(self, data_reader, mu=0.25, rho=0.15):
        self.graph = tg.TransportGraph(data_reader)
        self.graph_correspondences = data_reader.graph_correspondences
        self.mu = mu
        self.rho = rho

        self.t = torch.tensor(self.graph.freeflow_times, requires_grad=True)
        self.grad_sum = torch.zeros(self.t.size())
        self.phi_big_oracle = oracles.PhiBigOracle(self.graph,
                                                   self.graph_correspondences)
        self.primal_dual_calculator = dfc.PrimalDualCalculator(
            self.phi_big_oracle,
            self.graph.freeflow_times,
            self.graph.capacities,
            mu=self.mu,
            rho=self.rho)
Exemple #5
0
    def find_equilibrium(self,
                         solver_name='ustm',
                         composite=True,
                         solver_kwargs={},
                         base_flows=None):
        if solver_name == 'fwm':
            solver_func = fwm.frank_wolfe_method
            starting_msg = 'Frank-Wolfe method...'
        elif solver_name == 'ustm':
            solver_func = ustm.universal_similar_triangles_method
            starting_msg = 'Universal similar triangles method...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs[
                    'L_init'] = self.graph.max_path_length**0.5 * self.total_od_flow
        elif solver_name == 'ugd':
            solver_func = ugd.universal_gradient_descent_method
            starting_msg = 'Universal gradient descent method...'
            if not 'L_init' in solver_kwargs:
                solver_kwargs[
                    'L_init'] = self.graph.max_path_length**0.5 * self.total_od_flow
        elif solver_name == 'wda':
            solver_func = wda.weighted_dual_averages_method
            starting_msg = 'Weighted dual averages method...'
        elif solver_name == 'sd':
            solver_func = sd.subgradient_descent_method
            starting_msg = 'Subgradient descent method...'
        else:
            raise NotImplementedError('Unknown solver!')

        phi_big_oracle = oracles.PhiBigOracle(self.graph,
                                              self.graph_correspondences)
        h_oracle = oracles.HOracle(self.graph.freeflow_times,
                                   self.graph.capacities,
                                   rho=self.rho,
                                   mu=self.mu)
        primal_dual_calculator = dfc.PrimalDualCalculator(
            phi_big_oracle,
            h_oracle,
            self.graph.freeflow_times,
            self.graph.capacities,
            rho=self.rho,
            mu=self.mu,
            base_flows=base_flows)
        if composite == True or solver_name == 'fwm':
            if not solver_name == 'fwm':
                print('Composite optimization...')
            oracle = phi_big_oracle
            prox = h_oracle.prox
        else:
            print('Non-composite optimization...')
            oracle = phi_big_oracle + h_oracle

            def prox_func(grad, point, A):
                """
                Computes argmin_{t: t \in Q} <g, t> + A / 2 * ||t - p||^2
                    where Q - the feasible set {t: t >= free_flow_times},
                    A - constant, g - (sub)gradient vector, p - point at which prox is calculated
                """
                return np.maximum(point - grad / A, self.graph.freeflow_times)

            prox = prox_func
        print('Oracles created...')
        print(starting_msg)

        if solver_name == 'fwm':
            result = solver_func(oracle,
                                 primal_dual_calculator,
                                 t_start=self.graph.freeflow_times,
                                 **solver_kwargs)
        else:
            result = solver_func(oracle,
                                 prox,
                                 primal_dual_calculator,
                                 t_start=self.graph.freeflow_times,
                                 **solver_kwargs)
        #getting travel times of every non-zero trips between zones:
        result['zone travel times'] = {}
        for source in self.graph_correspondences:
            targets = self.graph_correspondences[source]['targets']
            travel_times, _ = self.graph.shortest_distances(
                source, targets, result['times'])
            #mapping nodes' indices to initial nodes' names:
            source_nodes = [self.inds_to_nodes[source]] * len(targets)
            target_nodes = list(map(self.inds_to_nodes.get, targets))
            result['zone travel times'].update(
                zip(zip(source_nodes, target_nodes), travel_times))
        return result