def test_assert_feasible__contiguity(): with pytest.raises(ValueError) as exc_info: # nodes 0 and 1 are not connected ... adj = csr_matrix(np.array([[0, 0], [0, 0]])) # ... but assigned to the same region --> not feasible labels = np.array([0, 0]) util.assert_feasible(labels, adj) assert "not spatially contiguous" in str(exc_info)
def test_assert_feasible__number_of_regions(): with pytest.raises(ValueError) as exc_info: adj = csr_matrix(np.array([[0, 1], [1, 0]])) # nodes 0 and 1 are connected ... labels = np.array([0, 0]) # ... and assigned to the same region # but this is not feasible under the condition n_regions = 2 n_regions = 2 util.assert_feasible(labels, adj, n_regions=n_regions) assert "The number of regions is" in str(exc_info)
def test_assert_feasible__pass_disconnected(): adj = csr_matrix(np.array([[0, 0], [0, 0]])) # nodes 0 and 1 are not connected ... labels = np.array([0, 1]) # ... and assigned to different regions try: util.assert_feasible(labels, adj) util.assert_feasible(labels, adj, n_regions=2) except ValueError: pytest.fail()
def test_assert_feasible__number_of_regions(): with pytest.raises(ValueError) as exc_info: adj = csr_matrix(np.array([[0, 1], [1, 0]])) # nodes 0 and 1 are connected ... labels = np.array([0, 0]) # ... and assigned to the same region # but this is not feasible under the condition n_regions = 2 n_regions = 2 util.assert_feasible(labels, adj, n_regions=n_regions) assert "The number of regions is" in str(exc_info.value)
def fit_from_scipy_sparse_matrix( self, adj, attr, n_regions, initial_labels=None, objective_func=ObjectiveFunctionPairwise()): """ Perform the AZP algorithm as described in [OR1995]_. The resulting region labels are assigned to the instance's :attr:`labels_` attribute. Parameters ---------- adj : :class:`scipy.sparse.csr_matrix` Adjacency matrix representing the contiguity relation. attr : :class:`numpy.ndarray` Array (number of areas x number of attributes) of areas' attributes relevant to clustering. n_regions : `int` Number of desired regions. initial_labels : :class:`numpy.ndarray` or None, default: None One-dimensional array of labels at the beginning of the algorithm. If None, then a random initial clustering will be generated. objective_func : :class:`region.objective_function.ObjectiveFunction`, default: ObjectiveFunctionPairwise() The objective function to use. """ if attr.ndim == 1: attr = attr.reshape(adj.shape[0], -1) self.allow_move_strategy.attr_all = attr self.objective_func = objective_func # step 1 if initial_labels is not None: assert_feasible(initial_labels, adj, n_regions) initial_labels_gen = separate_components(adj, initial_labels) else: initial_labels_gen = generate_initial_sol(adj, n_regions) labels = -np.ones(adj.shape[0]) for labels_comp in initial_labels_gen: comp_idx = np.where(labels_comp != -1)[0] adj_comp = sub_adj_matrix(adj, comp_idx) labels_comp = labels_comp[comp_idx] attr_comp = attr[comp_idx] self.allow_move_strategy.start_new_component( labels_comp, attr_comp, self.objective_func, comp_idx) labels_comp = self._azp_connected_component( adj_comp, labels_comp, attr_comp) labels[comp_idx] = labels_comp self.n_regions = n_regions self.labels_ = labels
def test_assert_feasible__pass_connected(): adj = csr_matrix(np.array([[0, 1], [1, 0]])) # nodes 0 and 1 are connected ... labels = np.array([0, 0]) # ...and (case 1) assigned to the same region try: util.assert_feasible(labels, adj) util.assert_feasible(labels, adj, n_regions=1) except ValueError: pytest.fail() labels = np.array([0, 1]) # ...and (case 2) assigned to different regions try: util.assert_feasible(labels, adj) util.assert_feasible(labels, adj, n_regions=2) except ValueError: pytest.fail()