def _get_sorted_solutions_indexes(selected_sections_matrix, nb_journeys_to_find, idx_of_jrny_must_keep): """ The entry is a 2D array where its lines are journeys, its columns are (non) chosen sections """ logger = logging.getLogger(__name__) """ Get a matrix which illustrate all possible non ordered combinations of t elements from n elements where n >= t with their indexes. Let's say we'd like to find all combinations of 2 elements from a set of 3. selected_journeys_matrix will be like: [[0,1] [0,2] [1,2]] """ # Allocation of memory shape = (nCr(selected_sections_matrix.shape[0], nb_journeys_to_find), nb_journeys_to_find) selected_journeys_matrix = np.empty(shape, dtype=np.uint16) def f(pair): i, c = pair selected_journeys_matrix[i] = c # replace line by line from itertools import izip map(f, izip(xrange(shape[0]), gen_all_combin(selected_sections_matrix.shape[0], nb_journeys_to_find))) """ We should cut out those combinations that don't contain must-keep journeys """ def _contains(idx_selected_jrny): return set(idx_selected_jrny).issuperset(idx_of_jrny_must_keep) selected_journeys_matrix = selected_journeys_matrix[ np.apply_along_axis(_contains, 1, selected_journeys_matrix) ] selection_matrix = np.zeros((selected_journeys_matrix.shape[0], selected_sections_matrix.shape[0])) """ Given selected_journeys_matrix: [[0,1] [0,2] [1,2]] selection_matrix will be like: [[1,1,0], -> the first one and the second are chosen, etc... [1,0,1], [0,1,1]] """ # http://stackoverflow.com/questions/20103779/index-2d-numpy-array-by-a-2d-array-of-indices-without-loops selection_matrix[np.arange(selected_journeys_matrix.shape[0])[:, None], selected_journeys_matrix] = 1 res_pool = np.dot(selection_matrix, selected_sections_matrix) """ Get number of sections(or tranfers) for every solution """ nb_sections = np.sum(res_pool, axis=1) """ integrity shows at which point a solution(chosen journeys) covers sections. 0 means a solution covers all sections 1 means a solutions covers almost all sections but 1 is missing 2 means 2 sections are missing .... etc """ integrity = res_pool.shape[1] - np.array([np.count_nonzero(r) for r in res_pool]) """ We want to find the solutions covers as many sections as possible which has less sections(less transfer to do) """ the_best_idx = np.lexsort((nb_sections, integrity))[0] # sort by integrity then by nb_sections best_indexes = np.where( np.logical_and(nb_sections == nb_sections[the_best_idx], integrity == integrity[the_best_idx]) )[0] logger.debug("Best Itegrity: {0}".format(integrity[the_best_idx])) logger.debug("Best Nb sections: {0}".format(nb_sections[the_best_idx])) return best_indexes, selection_matrix
def _get_sorted_solutions_indexes(selected_sections_matrix, nb_journeys_to_find): """ The entry is a 2D array where its lines are journeys, its columns are (non) chosen sections """ logger = logging.getLogger(__name__) """ Get a matrix which illustrate all possible non ordered combinations of t elements from n elements where n >= t with their indexes. Let's say we'd like to find all combinations of 2 elements from a set of 3. selected_journeys_matrix will be like: [[0,1] [0,2] [1,2]] """ selected_journeys_matrix = np.array(list(gen_all_combin(selected_sections_matrix.shape[0], nb_journeys_to_find))) selection_matrix = np.zeros((selected_journeys_matrix.shape[0], selected_sections_matrix.shape[0])) """ Given selected_journeys_matrix: [[0,1] [0,2] [1,2]] selection_matrix will be like: [[1,1,0], -> the first one and the second are chosen, etc... [1,0,1], [0,1,1]] """ # http://stackoverflow.com/questions/20103779/index-2d-numpy-array-by-a-2d-array-of-indices-without-loops selection_matrix[np.arange(selected_journeys_matrix.shape[0])[:, None], selected_journeys_matrix] = 1 res_pool = np.dot(selection_matrix, selected_sections_matrix) """ Get number of sections(or tranfers) for every solution """ nb_sections = np.sum(res_pool, axis=1) """ integrity shows at which point a solution(chosen journeys) covers sections. 0 means a solution covers all sections 1 means a solutions covers almost all sections but 1 is missing 2 means 2 sections are missing .... etc """ integrity = res_pool.shape[1] - np.array([np.count_nonzero(r) for r in res_pool]) """ We want to find the solutions covers as many sections as possible which has less sections(less transfer to do) """ the_best_idx = np.lexsort((nb_sections, integrity))[0] # sort by integrity then by nb_sections best_indexes = np.where(np.logical_and(nb_sections == nb_sections[the_best_idx], integrity == integrity[the_best_idx]))[0] logger.debug("Best Itegrity: {0}".format(integrity[the_best_idx])) logger.debug("Best Nb sections: {0}".format(nb_sections[the_best_idx])) return best_indexes, selection_matrix