def create_households(self, land, demand): # calculate the fleet and household size table fleet_array = np.array([freq for fleet, freq in self.fleet_freq]) size_array = np.array([freq for size, freq in self.size_freq]) # fill the joint fleet-hhsize table using proportional fitting table = self._proportional_fit(fleet_array, size_array) # calculate the number of households hhnum = int(round(table.sum())) # calculate the number of workers # if the size of a household is one, this one person is a worker # if the size of a household is larger than one, there a two workers wknum = sum(((2 if size > 3 else size) * freq for size, freq in self.size_freq)) # calculate the number of students, all the other persons are students stnum = sum(((0 if size < 3 else size - 2) * freq for size, freq in self.size_freq)) # assign random activity program to the households program_freq = dict(((demand.programs[id_], freq) for id_, freq in self.prog_freq)) programs = self._get_assignments(program_freq, hhnum) # assign random dwelling unit to the households residences = self._get_assignments(land.get_capacities("home"), hhnum) # assign random work place to the workers offices = self._get_assignments(land.get_capacities("work"), wknum) # assgin random school to the students schools = self._get_assignments(land.get_capacities("school"), stnum) # create iterator for activity programs it_program = iter(programs) # create iterators for all the locations it_residence, it_office, it_school = iter(residences), iter(offices), iter(schools) # create a household pool for i, j in ndrange(*table.shape): # create households with the same size and fleet for _ in xrange(int(round(table[i, j]))): self.add_household(self.size_freq[j][0], self.fleet_freq[i][0], demand, it_program, it_residence, it_office, it_school)
def _proportional_fit(self, row_sum, col_sum, tolerance=0.01): n_row, n_col = row_sum.size, col_sum.size # convert to matrices row_sum.shape = (n_row, 1) col_sum.shape = (1, n_col) # the row sum and column sum should be equal assert row_sum.sum() == col_sum.sum( ), 'Row subsum and column subsum are not equal.' # initialize a table table = np.ones([n_row, n_col]) # this table is a upper triangular matrix for i, j in ndrange(n_row, n_col): if i > j: table[i, j] = 0.0 row_err = float('+inf') # check convergence criteria while row_err > tolerance: # row proportional fitting table = row_sum * (table / table.sum(1).reshape(n_row, 1)) # column proportional fitting table = col_sum * (table / table.sum(0).reshape(1, n_col)) # calculate the differences row_diff = table.sum(1).reshape(n_row, 1) - row_sum row_err = (row_diff * row_diff).sum() return table
def create_households(self, land, demand): # calculate the fleet and household size table fleet_array = np.array([freq for fleet, freq in self.fleet_freq]) size_array = np.array([freq for size, freq in self.size_freq]) # fill the joint fleet-hhsize table using proportional fitting table = self._proportional_fit(fleet_array, size_array) # calculate the number of households hhnum = int(round(table.sum())) # calculate the number of workers # if the size of a household is one, this one person is a worker # if the size of a household is larger than one, there a two workers wknum = sum(((2 if size > 3 else size) * freq for size, freq in self.size_freq)) # calculate the number of students, all the other persons are students stnum = sum(((0 if size < 3 else size - 2) * freq for size, freq in self.size_freq)) # assign random activity program to the households program_freq = dict( ((demand.programs[id_], freq) for id_, freq in self.prog_freq)) programs = self._get_assignments(program_freq, hhnum) # assign random dwelling unit to the households residences = self._get_assignments(land.get_capacities("home"), hhnum) # assign random work place to the workers offices = self._get_assignments(land.get_capacities("work"), wknum) # assgin random school to the students schools = self._get_assignments(land.get_capacities("school"), stnum) # create iterator for activity programs it_program = iter(programs) # create iterators for all the locations it_residence, it_office, it_school = iter(residences), iter( offices), iter(schools) # create a household pool for i, j in ndrange(*table.shape): # create households with the same size and fleet for _ in xrange(int(round(table[i, j]))): self.add_household(self.size_freq[j][0], self.fleet_freq[i][0], demand, it_program, it_residence, it_office, it_school)
def _proportional_fit(self, row_sum, col_sum, tolerance=0.01): n_row, n_col = row_sum.size, col_sum.size # convert to matrices row_sum.shape = (n_row, 1) col_sum.shape = (1, n_col) # the row sum and column sum should be equal assert row_sum.sum() == col_sum.sum(), 'Row subsum and column subsum are not equal.' # initialize a table table = np.ones([n_row, n_col]) # this table is a upper triangular matrix for i, j in ndrange(n_row, n_col): if i > j: table[i,j] = 0.0 row_err = float('+inf') # check convergence criteria while row_err > tolerance: # row proportional fitting table = row_sum * (table / table.sum(1).reshape(n_row, 1)) # column proportional fitting table = col_sum * (table / table.sum(0).reshape(1, n_col)) # calculate the differences row_diff = table.sum(1).reshape(n_row, 1) - row_sum row_err = (row_diff*row_diff).sum() return table