def test_bad_weights(self, dim, graph):
     """Test if function raises a ``ValueError`` when a vector of node weights input to
     ``node_select`` is not of the same dimension as the input graph."""
     s = [0, 1]
     w = np.ones(dim - 1)
     with pytest.raises(ValueError, match="Number of node weights must match number of nodes"):
         clique.swap(s, graph, node_select=w)
    def test_swap_weight_tie(self, dim, monkeypatch):
        """Test if function performs correct swap operation using randomness to break ties during
        degree-based node selection. The input graph is a complete graph with the ``(dim - 1,
        dim - 3)`` and ``(dim - 2, dim - 4)`` edges removed. The starting clique is the first
        ``dim - 2`` nodes. This results in two candidate swap pairs: ``(dim - 1, dim - 3)`` and
        ``(dim - 2, dim - 4)``. This test gives the every node the same weight, so we expect that
        either pair should be selected randomly with equal probability. This test monkeypatches
        the ``np.random.choice`` call to guarantee that one of the nodes is picked during one run
        of ``swap`` and the another node is picked during the next run.
        """
        graph = nx.complete_graph(dim)
        graph.remove_edge(dim - 1, dim - 3)
        graph.remove_edge(dim - 2, dim - 4)
        s = list(range(dim - 2))
        weights = [1 for _ in range(dim)]

        patch_random_choice_1 = functools.partial(patch_random_choice, element=0)
        patch_random_choice_2 = functools.partial(patch_random_choice, element=1)

        with monkeypatch.context() as m:
            m.setattr(np.random, "choice", patch_random_choice_1)
            c1 = clique.swap(s, graph, node_select=weights)

        with monkeypatch.context() as m:
            m.setattr(np.random, "choice", patch_random_choice_2)
            c2 = clique.swap(s, graph, node_select=weights)

        assert c1 != c2
 def test_bad_node_select(self, dim):
     """Tests if function raises a ``ValueError`` when input an invalid ``node_select``
     argument"""
     graph = nx.barbell_graph(dim, 0)
     s = [0]
     with pytest.raises(ValueError, match="Node selection method not recognized"):
         clique.swap(s, graph, node_select="")
    def test_swap_degree_tie(self, dim, monkeypatch):
        """Test if function performs correct swap operation using randomness to break ties during
        degree-based node selection. Input graph is a fully connected graph. Additionally,
        a connection between node ``0`` and ``dim - 1`` is removed as well as a connection
        between node ``0`` and ``dim - 2``. A clique of the first ``dim - 2`` nodes is then
        input. In this case, C1 consists of nodes ``dim - 1`` and ``dim - 2``. As they have the
        same degree, they should be selected randomly with equal probability. This function
        monkeypatches the ``np.random.choice`` call to guarantee that one of the nodes is picked
        during one run of ``swap`` and the other node is picked during the next run.
        """
        graph = nx.complete_graph(dim)
        graph.remove_edge(0, dim - 1)
        graph.remove_edge(0, dim - 2)
        s = set(range(dim - 2))

        patch_random_choice_1 = functools.partial(patch_random_choice, element=0)
        patch_random_choice_2 = functools.partial(patch_random_choice, element=1)

        with monkeypatch.context() as m:
            m.setattr(np.random, "choice", patch_random_choice_1)
            c1 = clique.swap(s, graph, node_select="degree")

        with monkeypatch.context() as m:
            m.setattr(np.random, "choice", patch_random_choice_2)
            c2 = clique.swap(s, graph, node_select="degree")

        assert c1 != c2
 def test_swap(self, dim):
     """Test if function performs correct swap operation. Input is a complete graph with a
     connection between node ``0`` and ``dim - 1`` removed. An input clique of the first
     ``dim - 1`` nodes is then input, with the result being a different clique with the first
     node removed and the ``dim`` node added."""
     graph = nx.complete_graph(dim)
     graph.remove_edge(0, dim - 1)
     s = list(range(dim - 1))
     assert set(clique.swap(s, graph)) == set(range(1, dim))
 def test_swap_weight(self, dim):
     """Test if function performs correct swap operation when weight-based node selection is
     used. The input graph is a complete graph with the ``(dim - 1, dim - 3)`` and
     ``(dim - 2, dim - 4)`` edges removed. The starting clique is the first ``dim - 2`` nodes.
     This results in two candidate swap pairs: ``(dim - 1, dim - 3)`` and ``(dim - 2, dim - 4)``.
     Since node ``dim - 1`` has the largest weight, we expect to swap that in by removing node
     ``dim - 3``."""
     graph = nx.complete_graph(dim)
     graph.remove_edge(dim - 1, dim - 3)
     graph.remove_edge(dim - 2, dim - 4)
     s = list(range(dim - 2))
     weights = list(range(dim))
     result = set(clique.swap(s, graph, node_select=weights))
     expected = set(range(dim - 3)) | {dim - 1}
     assert result == expected
 def test_swap_degree(self, dim):
     """Test if function performs correct swap operation when degree-based node selection is
     used. Input graph is a lollipop graph, consisting of a fully connected graph with a
     single additional node connected to just one of the nodes in the graph. Additionally,
     a connection between node ``0`` and ``dim - 1`` is removed as well as a connection
     between node ``0`` and ``dim - 2``. A clique of the first ``dim - 2`` nodes is then
     input. In this case, C1 consists of nodes ``dim - 1`` and ``dim - 2``. However,
     node ``dim - 1`` has greater degree due to the extra node in the lollipop graph. This
     test confirms that the resultant swap is performed correctly."""
     graph = nx.lollipop_graph(dim, 1)
     graph.remove_edge(0, dim - 1)
     graph.remove_edge(0, dim - 2)
     s = list(range(dim - 2))
     result = set(clique.swap(s, graph, node_select="degree"))
     expected = set(range(1, dim - 2)) | {dim - 1}
     assert result == expected
 def test_input_valid_subgraph(self, dim):
     """Tests if function raises a ``ValueError`` when input is not a clique"""
     with pytest.raises(ValueError, match="Input is not a valid subgraph"):
         clique.swap([0, dim], nx.empty_graph(dim))