def setUp(self):

        # create a demand assignment
        time_period = 1  # Only have one time period for static model
        # paths_list = TestDemandAssignment.model_manager.beats_api.get_path_ids()
        commodity_list = TestDemandAssignment.model_manager.beats_api.get_commodity_ids(
        )

        # rout_list is a dictionary of [path_id]:[link_1, ...]
        route_list = {}
        route_list[1L] = [0L, 1L]
        route_list[2L] = [0L, 2L]

        # Test used to validate the Demand_Assignment_Class
        # Creating the demand assignment for initialization
        self.demand_assignment = Demand_Assignment_class(route_list,
                                                         commodity_list,
                                                         time_period,
                                                         dt=time_period)
        demands = {}
        self.demand_value = np.zeros(time_period)
        self.demand_value1 = np.zeros(time_period)
        self.demand_value[0] = 20
        self.demand_value1[0] = 20
        demands[(1L, 1L)] = self.demand_value
        demands[(2L, 1L)] = self.demand_value1
        self.demand_assignment.set_all_demands(demands)
class TestDemandAssignment(unittest.TestCase):
    @classmethod
    def setUpClass(cls):

        # make Java connection
        cls.connection = Java_Connection()

        # create a static/bpr model manager
        this_folder = os.path.dirname(
            os.path.abspath(inspect.getfile(inspect.currentframe())))
        configfile = os.path.join(this_folder, os.path.pardir, 'configfiles',
                                  'seven_links.xml')
        bpr_coefficients = {
            0L: [1, 0, 0, 0, 1],
            1L: [1, 0, 0, 0, 1],
            2L: [5, 0, 0, 0, 5],
            3L: [2, 0, 0, 0, 2],
            4L: [2, 0, 0, 0, 2],
            5L: [1, 0, 0, 0, 1],
            6L: [5, 0, 0, 0, 5]
        }
        cls.model_manager = Link_Model_Manager_class(configfile, "static",
                                                     cls.connection, None,
                                                     "bpr", bpr_coefficients)

    def setUp(self):

        # create a demand assignment
        time_period = 1  # Only have one time period for static model
        # paths_list = TestDemandAssignment.model_manager.beats_api.get_path_ids()
        commodity_list = TestDemandAssignment.model_manager.beats_api.get_commodity_ids(
        )

        # rout_list is a dictionary of [path_id]:[link_1, ...]
        route_list = {}
        route_list[1L] = [0L, 1L]
        route_list[2L] = [0L, 2L]

        # Test used to validate the Demand_Assignment_Class
        # Creating the demand assignment for initialization
        self.demand_assignment = Demand_Assignment_class(route_list,
                                                         commodity_list,
                                                         time_period,
                                                         dt=time_period)
        demands = {}
        self.demand_value = np.zeros(time_period)
        self.demand_value1 = np.zeros(time_period)
        self.demand_value[0] = 20
        self.demand_value1[0] = 20
        demands[(1L, 1L)] = self.demand_value
        demands[(2L, 1L)] = self.demand_value1
        self.demand_assignment.set_all_demands(demands)

    def test_set_all_demands_on_path(self):
        self.demand_assignment.set_all_demands_on_path(
            1L, {1L: self.demand_value1})
Beispiel #3
0
    def test_model_manager(self):

        api = TestMN.model_manager.beats_api

        comm_id = 1L
        time_horizon = 3600.0
        demand_dt = 1200.0
        demand_n = int(time_horizon / demand_dt)

        # create a demand assignment
        commodity_list = api.get_commodity_ids()

        # rout_list is a dictionary of [path_id]:[link_1, ...]
        route_list = {
            1L: [0L, 1L, 3L, 6L],
            2L: [0L, 2L, 4L, 6L],
            3L: [0L, 1L, 5L]
        }

        # Test used to validate the Demand_Assignment_Class# Creating the demand assignment for initialization
        demand_assignment = Demand_Assignment_class(route_list, commodity_list,
                                                    demand_n, demand_dt)
        demand_assignment.set_all_demands({
            (1L, comm_id): [1000, 1000, 1000],
            (2L, comm_id): [0, 0, 0],
            (3L, comm_id): [0, 0, 0]
        })

        TestMN.model_manager.evaluate(demand_assignment, time_horizon)
    def setUpClass(cls):

        # make Java connection
        cls.connection = Java_Connection()

        # create a static/bpr model managers
        this_folder = os.path.dirname(
            os.path.abspath(inspect.getfile(inspect.currentframe())))
        configfile = os.path.join(this_folder, os.path.pardir, 'configfiles',
                                  'seven_links.xml')
        bpr_coefficients = {
            0L: [1, 0, 0, 0, 1],
            1L: [1, 0, 0, 0, 1],
            2L: [5, 0, 0, 0, 5],
            3L: [2, 0, 0, 0, 2],
            4L: [2, 0, 0, 0, 2],
            5L: [1, 0, 0, 0, 1],
            6L: [5, 0, 0, 0, 5]
        }
        cls.model_manager = Link_Model_Manager_class(configfile, "static",
                                                     cls.connection, None,
                                                     "bpr", bpr_coefficients)

        api = cls.model_manager.beats_api

        time_period = 1  # Only have one time period for static model
        paths_list = list(api.get_path_ids())
        commodity_list = list(api.get_commodity_ids())
        route_list = {}

        for path_id in paths_list:
            route_list[path_id] = api.get_subnetwork_with_id(
                path_id).get_link_ids()

        # Test used to validate the Demand_Assignment_Class
        # Creating the demand assignment for initialization
        cls.demand_assignments = Demand_Assignment_class(route_list,
                                                         commodity_list,
                                                         time_period,
                                                         dt=time_period)
        demands = {}
        demand_value = np.zeros(time_period)
        demand_value1 = np.zeros(time_period)
        demand_value[0] = 2
        demand_value1[0] = 2
        demands[(1L, 1L)] = demand_value
        demands[(2L, 1L)] = demand_value1
        demands[(3L, 1L)] = demand_value
        cls.demand_assignments.set_all_demands(demands)

        # create link states
        cls.link_states = cls.model_manager.traffic_model.Run_Model(
            cls.demand_assignments)
Beispiel #5
0
def line_search(model_manager, x_assignment, x_vector, y_assignment, y_vector, d_vector, eps, timer = None):
    # alfa = 0 corresponds to when assignment is equal to original assignment x_assignment
    sampling_dt = x_assignment.get_dt()
    T = sampling_dt * x_assignment.get_num_time_step()

    g0 = g_function(model_manager, x_assignment, T, d_vector, timer = timer)

    # alfa = 1 corresponds to when assignment is equal to all_or_nothing assignment y_assignment
    g1 = g_function(model_manager, y_assignment, T, d_vector,timer = timer)

    if (g0 > 0 and g1 > 0) or (g0 < 0 and g1 < 0):
        if np.abs(g0) <= np.abs(g1):
            return 0
        else:
            return 1

    l, r = 0, 1

    # Initializing the demand assignment
    commodity_list = x_assignment.get_commodity_list()
    num_steps = x_assignment.get_num_time_step()
    path_list = x_assignment.get_path_list()

    while r-l > eps:
        m = (l+r)/2
        m_vector = x_vector + m * d_vector
        m_assignment = Demand_Assignment_class(path_list, commodity_list, num_steps, sampling_dt)
        m_assignment.set_all_demands(x_assignment.get_all_demands())
        m_assignment.set_demand_with_vector(m_vector)
        g_m = g_function(model_manager, m_assignment, T, d_vector,timer = timer)

        if (g_m < 0 and np.abs(g_m) > eps and g1 > 0) or (g_m > 0 and np.abs(g_m) > eps and g1 < 0):
            l = copy(m)
            g0 = copy(g_m)
        elif (g_m < 0 and np.abs(g_m) > eps and g0 > 0) or (g_m > 0 and np.abs(g_m) > eps and g0 < 0):
            r = copy(m)
            g1 = copy(g_m)
        else: return m

    return l
Beispiel #6
0
    T = 3600  # Time horizon of interest
    sim_dt = 4.0  # Duration of one time_step for the traffic model

    sampling_dt = 4  # Duration of time_step for the solver, in this case it is equal to sim_dt
    model_manager = Link_Model_Manager_class(configfile, connection.gateway, "mn", sim_dt, "bpr", coefficients)

    #Estimating bpr coefficients with beats
    num_links = model_manager.beats_api.get_num_links()
    avg_travel_time = np.zeros(num_links)

    num_coeff = 5

    for i in range(num_links):
        fft= (model_manager.beats_api.get_link_with_id(long(i)).getFull_length() \
          / model_manager.beats_api.get_link_with_id(long(i)).get_ffspeed_mps())/3600
        coefficients[long(i)] = np.zeros(num_coeff)
        coefficients[i][0] = copy(fft)
        coefficients[i][4] = copy(fft*0.15)
    route = {}
    route['1'] = [0, 3, 4, 5]
    route['2'] = [0, 2, 4, 5]
    route['3'] = [1, 3, 4, 5]
    od = list(model_manager.beats_api.get_od_info())
    num_steps = int(T / sampling_dt)
    # Initializing the demand assignment
    commodity_list = list(model_manager.beats_api.get_commodity_ids())
    assignment = Demand_Assignment_class(route, commodity_list, num_steps, sampling_dt)
    model = MN_Model_Class(model_manager.beats_api, connection.gateway)
    model.Run_Model(assignment, None,T, False)
    #print model.get_total_demand()
    connection.close()
Beispiel #7
0
    sampling_dt = 4  # Duration of time_step for the solver, in this case it is equal to sim_dt
    model_manager_beats = BeATS_Model_Manager_class(configfile,
                                                    connection.gateway, sim_dt)
    route = {}
    route['1'] = [0, 3, 4, 5]
    route['2'] = [0, 2, 4, 5]
    route['3'] = [1, 3, 4, 5]
    demand = {}
    demand['1'] = [100]
    demand['2'] = [100]
    demand['3'] = [100]
    od = list(model_manager_beats.beats_api.get_od_info())
    num_steps = int(T / sampling_dt)

    # Initializing the demand assignment
    commodity_list = list(model_manager_beats.beats_api.get_commodity_ids())
    assignment = Demand_Assignment_class(route, commodity_list, num_steps,
                                         sampling_dt)
    assignment.set_all_demands(demand)
    #  model_manager.beats_api.get_link_with_id(long(i)).get_ffspeed_mps())/3600
    #print assignment.print_all()
    #print assignment.get_commodity_list()
    #print assignment.get_path_list()
    model = Abstract_Traffic_Model_class(model_manager_beats.beats_api)
    eval = model_manager_beats.evaluate(assignment, T, initial_state=None)

    #print eval.get_all_path_costs()
    # kill jvm

    connection.close()
            route['2'] = [0, 2, 4, 5]
            route['3'] = [1, 3, 4, 5]
            demand = {}
            demand[('1','1')] = [10]
            demand[('2','1')] = [10]
            demand[('3','1')] = [10]
            path_ids = ['1', '2', '3']
            comm_ids = [1, 1, 1]
            demands_1 = [d]
            demands_2 =[20-d]
            demands_3 = [20]
            od = list(model_manager.beats_api.get_od_info())
            num_steps = int(T / sampling_dt)
            # Initializing the demand assignment
            commodity_list = list(model_manager.beats_api.get_commodity_ids())
            assignment = Demand_Assignment_class(route, commodity_list, num_steps, sampling_dt)
            sortedD = collections.OrderedDict(sorted(demand.items(), key=lambda t: t[0]))
            #assignment.set_all_demands(sortedD)
            assignment.set_all_demands_on_path_comm(path_ids[0], comm_ids[0], demands_1)
            assignment.set_all_demands_on_path_comm(path_ids[1], comm_ids[1], demands_2)
            assignment.set_all_demands_on_path_comm(path_ids[2], comm_ids[2], demands_3)
            #print assignment.get_path_list().keys()
            #print assignment.get_commodity_list()

            model = Static_Model_Class(model_manager.beats_api)
            path_costs = model_manager.evaluate(assignment,T, initial_state = None)
            #outfile = 'ctm/ctm_' +str(d) +'.txt'
            #outfile = 'pq/pq_' + str(d) + '.txt'
            #path_costs.print_all()
            outfile = 'static/static_' +str(d) +'_' +str(b) +'.txt'
            path_costs.write_path_info(outfile)
Beispiel #9
0
        sampling_dt = 4  # Duration of time_step for the solver, in this case it is equal to sim_dt
        model_manager_beats = BeATS_Model_Manager_class(
            configfile, connection.gateway, sim_dt)
        route = {}
        route['1'] = [0, 3, 4, 5]
        route['2'] = [0, 2, 4, 5]
        route['3'] = [1, 3, 4, 5]

        od = list(model_manager_beats.beats_api.get_od_info())
        num_steps = int(T / sampling_dt)

        # Initializing the demand assignment
        commodity_list = list(
            model_manager_beats.beats_api.get_commodity_ids())
        assignment = Demand_Assignment_class(route, commodity_list, num_steps,
                                             sampling_dt)
        d_1 = d
        d_2 = 20 - d
        d_3 = 20
        demand_1 = np.ones(num_steps) * d
        demand_2 = np.ones(num_steps) * d_2
        demand_3 = np.ones(num_steps) * d_3

        assignment.set_all_demands_on_path_comm('1', 1, demand_1)
        assignment.set_all_demands_on_path_comm('2', 1, demand_2)
        assignment.set_all_demands_on_path_comm('3', 1, demand_3)
        eval = model_manager_beats.evaluate(assignment, T, initial_state=None)

        #print eval.get_all_path_costs()
        # kill jvm
        write_file = 'pq_' + str(d) + '.txt'
def Modified_Projection_Method_Solver(model_manager,
                                      T,
                                      sampling_dt,
                                      max_iter=1000,
                                      display=1,
                                      stop=2):

    # In this case, x_k is a demand assignment object that maps demand to paths
    # Constructing the x_0, the initial demand assignment, where all the demand for an OD is assigned to one path
    # We first create a list of paths from the traffic_scenario
    path_list = dict()
    od = model_manager.beats_api.get_od_info()
    num_steps = int(T / sampling_dt)

    # Initializing the demand assignment
    commodity_list = list(model_manager.beats_api.get_commodity_ids())
    x_k_assignment = Demand_Assignment_class(path_list, commodity_list,
                                             num_steps, sampling_dt)

    # Populating the Demand Assignment, based on the paths associated with ODs
    for o in od:
        count = 0
        comm_id = o.get_commodity_id()

        demand_api = [
            item * 3600 for item in o.get_total_demand_vps().getValues()
        ]
        demand_api = np.asarray(demand_api)
        demand_size = len(demand_api)
        demand_dt = o.get_total_demand_vps().getDt()

        # Before assigning the demand, we want to make sure it can be properly distributed given the number of
        # Time step in our problem
        if (sampling_dt > demand_dt
                or demand_dt % sampling_dt > 0) and (demand_size > 1):
            print "Demand specified in xml cannot not be properly divided among time steps"
            return
        #if demand_size > num_steps or num_steps % len(demand_api) != 0:
        #print "Demand specified in xml cannot not be properly divided among time steps"
        #return

        for path in o.get_subnetworks():
            path_list[path.getId()] = path.get_link_ids()
            demand = np.zeros(num_steps)
            x_k_assignment.set_all_demands_on_path_comm(
                path.getId(), comm_id, demand)

    # x_interm is the initial solution: Step 0
    x_k_assignment, start_cost = all_or_nothing(model_manager, x_k_assignment,
                                                od, None,
                                                sampling_dt * num_steps)

    # row parameter used in the modified projection method
    row = 1

    for i in range(max_iter):
        # Step 1: Determining X_bar
        # get coefficients for cost function
        coefficients = get_cost_function_coefficients(model_manager, T, row,
                                                      x_k_assignment,
                                                      x_k_assignment)
        x_bar_assignment = Path_Based_Frank_Wolfe_Solver(
            model_manager, T, sampling_dt, cost_function, coefficients)
        #print (cost_function(x_bar_assignment,coefficients))

        # Step 2: Determining x_k=1
        new_coefficients = get_cost_function_coefficients(
            model_manager, T, row, x_bar_assignment, x_k_assignment)
        new_x_k_assignment = Path_Based_Frank_Wolfe_Solver(
            model_manager, T, sampling_dt, cost_function, new_coefficients)
        #print (cost_function(new_x_k_assignment, new_coefficients))

        # Step 3
        # Calculating the error
        x_k_assignment_vector = np.asarray(x_k_assignment.vector_assignment())
        new_x_k_assignment_vector = np.asarray(
            new_x_k_assignment.vector_assignment())

        error = max(np.abs(x_k_assignment_vector - new_x_k_assignment_vector))
        print "MPM iteration: ", i, ", error: ", error
        if error < stop:
            print "Stop with error: ", error
            return new_x_k_assignment

        # Otherwise, we update x_k_assignment and go back to step 1
        x_k_assignment.set_demand_with_vector(new_x_k_assignment_vector)
Beispiel #11
0
    def decomposed_solver(self,
                          T,
                          sampling_dt,
                          solver_function,
                          ods=None,
                          max_iter=50,
                          stop=1e-2):
        from mpi4py import MPI

        sim_time = 0
        comm_time = 0

        # MPI Directives
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()
        size = comm.Get_size()

        # We first start by initializing an initial solution/ demand assignment
        if ods == None:
            num_steps = T / sampling_dt
            od_temp = list(
                self.model_manager.get_OD_Matrix(
                    num_steps, sampling_dt).get_all_ods().values())
        else:
            od_temp = ods

        od = np.asarray(
            sorted(od_temp,
                   key=lambda h: (h.get_origin(), h.get_destination())))

        # Determine which subset of od to be addressed by the current process
        n = len(od)

        if n < size and rank >= size:
            print "Number of ods is smaller than number of process. This process will not run solver"
            return None, None

        local_n_c = math.ceil(float(n) / size)  # local step but ceiled
        local_n = n / size
        remainder = n % size

        if (rank < remainder):
            local_a = math.ceil(rank * local_n_c)
            local_b = math.ceil(min(local_a + local_n_c, n))
            local_n = local_n_c
        else:
            local_a = math.ceil((remainder) * local_n_c +
                                (rank - remainder) * local_n)
            local_b = math.ceil(min(local_a + local_n, n))

        # The set of ods to use for the particular subproblem
        print "rank :", rank, " solving for od's ", local_a, " through ", local_b - 1
        od_subset = od[int(local_a):int(local_b)]

        num_steps = int(T / sampling_dt)
        path_list = dict()
        commodity_list = list(
            self.model_manager.otm_api.scenario().get_commodity_ids())
        init_assignment = Demand_Assignment_class(path_list, commodity_list,
                                                  num_steps, sampling_dt)

        # We start with an initial Demand assignment with demands all equal to zeros
        count = 0
        path_index = 0
        for i in range(len(od)):
            comm_id = od[i].get_comm_id()
            od_path_list = od[i].get_path_list()
            path_list.update(od_path_list)

            for key in od_path_list.keys():
                if count >= local_a and count < local_b:
                    demand = np.zeros(num_steps)
                else:
                    demand = np.ones(num_steps)

                init_assignment.set_all_demands_on_path_comm(
                    key, comm_id, demand)
                path_index += 1

            #print "rank: ", rank, " ", od[count].get_origin_node_id(), od[count].get_destination_node_id()
            count += 1

        # vector for previous iteration solution
        #start_time1 = timeit.default_timer()
        prev_vector = np.asarray(init_assignment.vector_assignment())
        #print prev_vector
        # indices in solution vector corresponding to other ods other than the current subset
        out_od_indices = np.nonzero(prev_vector)
        #print out_od_indices
        prev_vector = np.zeros(len(prev_vector))
        init_assignment.set_demand_with_vector(prev_vector)

        #elapsed1 = timeit.default_timer() - start_time1
        #print "Initializing indices too ", elapsed1

        # Initial solution with all_or_nothing assignment
        init_assignment, path_costs, temp_sim_time = all_or_nothing(
            self.model_manager, init_assignment, od, None,
            sampling_dt * num_steps)
        x_k_vector = np.zeros(len(prev_vector))
        sim_time = sim_time + temp_sim_time

        prev_vector = np.asarray(init_assignment.vector_assignment())

        #print "Prev_vector ", prev_vector

        for i in range(max_iter):
            display = 0
            if rank == 0: display = 1

            #start_time1 = timeit.default_timer()

            x_i_assignment, x_i_vector, temp_sim_time, temp_comm_time = solver_function(
                self.model_manager,
                T,
                sampling_dt,
                od_subset,
                None,
                assignment=init_assignment,
                display=display)

            sim_time = sim_time + temp_sim_time
            comm_time = comm_time + temp_comm_time

            #elapsed1 = timeit.default_timer() - start_time1
            #print "Decomposition Iteration took ", elapsed1

            # if rank==0: print "rank ", rank, " prev sol vec: ", x_i_vector

            # First zero out all elements in results not corresponding to current odsubset
            x_i_vector[out_od_indices] = 0

            #writer.writerow(np.asarray(out_od_indices))
            #writer.writerow(prev_vector)

            start_time1 = timeit.default_timer()

            # Combine the x_i_vectors with all_reduce directive into x_k_vector
            comm.Allreduce(x_i_vector, x_k_vector, op=MPI.SUM)

            elapsed1 = timeit.default_timer() - start_time1

            comm_time = comm_time + elapsed1
            #print "Communication took ", elapsed1

            # if rank==0: print "rank ", rank, " comb sol vec: ", x_k_vector

            #writer.writerow(x_k_vector)
            # print x_k_vector[od_indices]

            # Calculate error and if error is below predifined level stop

            # All_or_Nothing Assignment for the whole od
            # z_k_assignment, z_k_path_costs = all_or_nothing(self.model_manager, assignment, od, None, T)
            # z_k_vector = np.asarray(z_k_assignment.vector_assignment())
            # z_k_cost_vector = np.asarray(z_k_path_costs.vector_path_costs())

            prev_error = -1
            count = 0
            rep = 5

            error = round(np.linalg.norm(x_k_vector - prev_vector, 1), 4)
            # error = np.abs(np.dot(z_k_cost_vector,  z_k_vector- x_k_vector) /
            # np.dot(z_k_vector, z_k_cost_vector))

            # keeping track of the error values seen
            if (prev_error == -1):
                prev_error = error
            elif (prev_error == error):
                count += 1
                if rank == 0: print "count is now ", count
            else:
                prev_error = error
                count = 1

            if error < stop or count >= rep:
                if rank == 0:
                    if count >= rep:
                        print "error did not change ", count, " iterations"
                    print "Decomposition stop with error: ", error
                #csv_file.close()
                init_assignment.set_demand_with_vector(x_k_vector)
                return init_assignment, x_k_vector, sim_time, comm_time

            # Change assignment with current x_k_vector
            # start_time1 = timeit.default_timer()

            init_assignment.set_demand_with_vector(x_k_vector)

            # elapsed1 = timeit.default_timer() - start_time1
            #print "Setting Demand took ", elapsed1

            if rank == 0:
                print "Decomposition Iteration ", i, " error: ", error
            prev_vector = copy(x_k_vector)

        #csv_file.close()
        return init_assignment, x_k_vector, sim_time, comm_time
Beispiel #12
0
    def parallel_solver(self, T, sampling_dt, solver_function, ods=None):
        from mpi4py import MPI

        # MPI Directives
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()
        size = comm.Get_size()

        sim_time = 0
        comm_time = 0

        #rank = 0
        #size = 2

        # We first start by initializing an initial solution/ demand assignment
        if ods == None:
            num_steps = T / sampling_dt
            od_temp = list(
                self.model_manager.get_OD_Matrix(
                    num_steps, sampling_dt).get_all_ods().values())
        else:
            od_temp = ods

        od = np.asarray(
            sorted(od_temp,
                   key=lambda h: (h.get_origin(), h.get_destination())))

        n = len(od)

        if n < size and rank >= size:
            print "Number of ods is smaller than number of process. This process will not run solver"
            return None, None

        local_n_c = math.ceil(float(n) / size)  # local step but ceiled
        local_n = n / size
        remainder = n % size

        if (rank < remainder):
            local_a = math.ceil(rank * local_n_c)
            local_b = math.ceil(min(local_a + local_n_c, n))
            local_n = local_n_c
        else:
            local_a = math.ceil((remainder) * local_n_c +
                                (rank - remainder) * local_n)
            local_b = math.ceil(min(local_a + local_n, n))

        # The set of ods to use for the particular subproblem
        print "Solving for od's ", local_a, " through ", local_b - 1
        od_subset = od[int(local_a):int(local_b)]

        #Want to save the solutions obtained per iteration on each processor
        #outputfile = 'Dec_output' + str(rank) + '.csv'
        #csv_file = open(outputfile, 'wb')
        #writer = csv.writer(csv_file)

        num_steps = int(T / sampling_dt)
        path_list = dict()
        commodity_list = list(
            self.model_manager.otm_api.scenario().get_commodity_ids())
        init_assignment = Demand_Assignment_class(path_list, commodity_list,
                                                  num_steps, sampling_dt)
        # We start with an initial Demand assignment with demands all equal to zeros
        count = 0
        path_index = 0
        for i in range(len(od)):
            comm_id = od[i].get_comm_id()
            od_path_list = od[i].get_path_list()
            path_list.update(od_path_list)

            for key in od_path_list.keys():
                if count >= local_a and count < local_b:
                    demand = np.zeros(num_steps)
                else:
                    demand = np.ones(num_steps)

                init_assignment.set_all_demands_on_path_comm(
                    key, comm_id, demand)
                path_index += 1

            #print "rank: ", rank, " ", od[count].get_origin_node_id(), od[count].get_destination_node_id()
            count += 1

        # vector used to calculated the indices not touched by the current subproblem and used to reinitialize
        # the initial demand assignment
        #start_time1 = timeit.default_timer()
        init_vector = np.asarray(init_assignment.vector_assignment())
        #print prev_vector
        # indices in solution vector corresponding to other ods other than the current subset
        if size == 1: out_od_indices = None
        else: out_od_indices = np.asarray(np.nonzero(init_vector)[0])
        init_vector = np.zeros(len(init_vector))
        init_assignment.set_demand_with_vector(init_vector)

        display = 0
        if rank == 0: display = 1

        timer = None
        if rank == 0:
            timer = [
                0
            ]  #Variable used to time the path costs evaluation just for processor rank 0
        # x_assignment, x_vector = solver_function(self.model_manager, T, sampling_dt, od_subset, out_od_indices,
        #                                          init_assignment, display = display, timer = timer)

        x_assignment, x_vector, sim_time, comm_time = solver_function(
            self.model_manager,
            T,
            sampling_dt,
            od_subset,
            out_od_indices,
            init_assignment,
            display=display)

        # if rank == 0 and timer is not None: print "Total Path Evaluation took: ", timer[0]

        return x_assignment, x_vector, sim_time, comm_time
def all_or_nothing(model_manager, assignment, od, initial_state=None, T=None):
    sampling_dt = assignment.get_dt()

    # Initializing the demand assignment
    commodity_list = assignment.get_commodity_list()
    num_steps = assignment.get_num_time_step()
    path_list = assignment.get_path_list()

    start_time1 = timeit.default_timer()

    path_costs = model_manager.evaluate(assignment, T, initial_state)
    #path_costs.print_all_in_seconds()
    elapsed1 = timeit.default_timer() - start_time1

    # if timer is not None:
    #     timer[0] = timer[0] + elapsed1
    #     print ("Timer is now  %s seconds" % timer[0])

    # print "path_eval took: ", elapsed1

    # Below we initialize the all_or_nothing assignment
    y_assignment = Demand_Assignment_class(path_list, commodity_list,
                                           num_steps, sampling_dt)

    y_assignment.set_all_demands(assignment.get_all_demands())

    # For each OD, we are going to move its demand to the shortest path at current iteration
    count = 0
    #start_time1 = timeit.default_timer()

    start_time1 = timeit.default_timer()
    for o in od:
        count += 1
        min_cost = 0
        comm_id = o.get_comm_id()
        od_path_list = o.get_path_list()

        for i in range(num_steps):
            min_path_id = -1
            for path_id in od_path_list.keys():

                #Check if the current entry in not zero, make it zero
                if y_assignment.get_demand_at_path_comm_time(
                        path_id, comm_id, i) > 0:
                    y_assignment.set_demand_at_path_comm_time(
                        path_id, comm_id, i, 0)

                if min_path_id == -1:
                    min_path_id = path_id
                    min_cost = path_costs.get_cost_at_path_comm_time(
                        min_path_id, comm_id, i)
                elif min_cost > path_costs.get_cost_at_path_comm_time(
                        path_id, comm_id, i):
                    min_path_id = path_id
                    min_cost = path_costs.get_cost_at_path_comm_time(
                        min_path_id, comm_id, i)

            # Putting all the demand on the minimum cost path
            demand = o.get_demand()[i]
            y_assignment.set_demand_at_path_comm_time(min_path_id, comm_id, i,
                                                      demand)

    #print "All_or_nothing for ", count, " ods"

    #elapsed1 = timeit.default_timer() - start_time1
    #print ("Changing Demand assignment took  %s seconds" % elapsed1)

    #y_assignment.print_all()
    return y_assignment, path_costs, elapsed1
def Method_of_Successive_Averages_Solver(model_manager,
                                         T,
                                         sampling_dt,
                                         od=None,
                                         od_out_indices=None,
                                         init_assignment=None,
                                         max_iter=1000,
                                         display=1,
                                         stop=1e-2):

    # In this case, x_k is a demand assignment object that maps demand to paths
    # Constructing the x_0, the initial demand assignment, where all the demand for an OD is assigned to one path

    sim_time = 0
    comm_time = 0

    num_steps = int(T / sampling_dt)

    # If no subset of od provided, get od from the model manager
    if od is None:
        od = list(model_manager.get_OD_Matrix(num_steps, sampling_dt))

    # Initializing the demand assignment only if the assignment variable is None
    if init_assignment is None:
        # We first create a list of paths from the traffic_scenario
        path_list = dict()
        commodity_list = list(
            model_manager.otm_api.scenario().get_commodity_ids())
        init_assignment = Demand_Assignment_class(path_list, commodity_list,
                                                  num_steps, sampling_dt)

        # Populating the Demand Assignment, based on the paths associated with ODs
        for o in od:
            comm_id = o.get_comm_id()
            od_path_list = o.get_path_list()
            path_list.update(od_path_list)
            for key in od_path_list.keys():
                demand = np.zeros(num_steps)
                init_assignment.set_all_demands_on_path_comm(
                    key, comm_id, demand)

        assignment, start_cost, temp_sim_time = all_or_nothing(
            model_manager, init_assignment, od, None, sampling_dt * num_steps)
        sim_time = sim_time + temp_sim_time

    # Only call the first all or nothing if the given assignment is empty (all zeros)
    else:
        init_vector = np.asarray(init_assignment.vector_assignment())

        if np.count_nonzero(init_vector) == 0:
            assignment, start_cost, temp_sim_time = all_or_nothing(
                model_manager, init_assignment, od, None,
                sampling_dt * num_steps)
            sim_time = sim_time + temp_sim_time
        else:
            commodity_list = init_assignment.get_commodity_list()
            num_steps = init_assignment.get_num_time_step()
            path_list = init_assignment.get_path_list()
            assignment = Demand_Assignment_class(path_list, commodity_list,
                                                 num_steps, sampling_dt)
            assignment.set_all_demands(init_assignment.get_all_demands())

    prev_error = -1
    assignment_vector_to_return = None
    x_assignment_vector = None

    if od_out_indices is not None:
        from mpi4py import MPI
        comm = MPI.COMM_WORLD
        temp_vector = np.asarray(assignment.vector_assignment())
        x_assignment_vector = np.zeros(len(temp_vector))

        # First zero out the values corresponding to other subproblems
        temp_vector[od_out_indices] = 0

        # Combine assignment from all subproblems into ass_vector
        start_time1 = timeit.default_timer()
        comm.Allreduce(temp_vector, x_assignment_vector, op=MPI.SUM)
        elapsed1 = timeit.default_timer() - start_time1

        comm_time = comm_time + elapsed1

        # Update assignment with the combine assignment vector
        assignment.set_demand_with_vector(x_assignment_vector)

    for i in range(max_iter):

        #start_time2 = timeit.default_timer()
        # All_or_nothing assignment
        y_assignment, current_path_costs, temp_sim_time = all_or_nothing(
            model_manager, assignment, od, None, sampling_dt * num_steps)
        sim_time = sim_time + temp_sim_time

        #elapsed2 = timeit.default_timer() - start_time2
        #print ("All_or_Nothing took %s seconds" % elapsed2)
        #current_path_costs.print_all()

        # Calculating the error
        current_cost_vector = np.asarray(
            current_path_costs.vector_path_costs())

        if x_assignment_vector is None:
            x_assignment_vector = np.asarray(assignment.vector_assignment())

        # When in parallel strategy, the y_assignment_vector has to be combined from all subproblems
        # If we are doing the parallel strategy, then od_out_indices is not None
        if od_out_indices is not None:
            from mpi4py import MPI
            comm = MPI.COMM_WORLD
            y_temp_vector = np.asarray(y_assignment.vector_assignment())
            y_assignment_vector = np.zeros(len(y_temp_vector))

            # First zero out the values corresponding to other subproblems
            y_temp_vector[od_out_indices] = 0

            # Combine assignment from all subproblems into ass_vector
            start_time1 = timeit.default_timer()
            # Combine assignment from all subproblems into ass_vector
            comm.Allreduce(y_temp_vector, y_assignment_vector, op=MPI.SUM)
            elapsed1 = timeit.default_timer() - start_time1
            if comm_time is not None: comm_time = comm_time + elapsed1
            comm_time = comm_time + elapsed1
            #if display == 1: print ("Communication took  %s seconds" % elapsed1)

        else:
            y_assignment_vector = np.asarray(y_assignment.vector_assignment())

        error = round(
            np.abs(
                np.dot(current_cost_vector,
                       y_assignment_vector - x_assignment_vector) /
                np.dot(y_assignment_vector, current_cost_vector)), 4)

        #error = distance_to_Nash(assignment,current_path_costs,od)

        if prev_error == -1 or prev_error > error:
            prev_error = error
            assignment_vector_to_return = copy(x_assignment_vector)

        if error < stop:
            if display == 1: print "MSA Stop with error: ", error
            return assignment, x_assignment_vector, sim_time, comm_time

        if display == 1: print "MSA iteration: ", i, ", error: ", error

        d_assignment = y_assignment_vector - x_assignment_vector

        #Step size equals t0 1/k, where k is the iteration number
        s = 1 / (i + 1)

        x_assignment_vector = x_assignment_vector + s * d_assignment
        assignment.set_demand_with_vector(x_assignment_vector)

        #elapsed2 = timeit.default_timer() - start_time2
        #print ("One Iteration took %s seconds" % elapsed2)
        # current_path_costs.print_all()

    assignment.set_demand_with_vector(assignment_vector_to_return)
    return assignment, assignment_vector_to_return, sim_time, comm_time