diff --git a/Qommunity/samplers/hierarchical/advantage_sampler/advantage_sampler.py b/Qommunity/samplers/hierarchical/advantage_sampler/advantage_sampler.py index d5cfacc30..ac5f03607 100644 --- a/Qommunity/samplers/hierarchical/advantage_sampler/advantage_sampler.py +++ b/Qommunity/samplers/hierarchical/advantage_sampler/advantage_sampler.py @@ -11,8 +11,8 @@ def __init__( resolution: float = 1, community: list | None = None, use_weights: bool = True, - version: str = "Advantage_system5.4", - region: str = "eu-central-1", + version: str | None = None, + region: str | None = None, num_reads: int = 100, chain_strength: float | None = None, use_clique_embedding: bool = False, @@ -28,9 +28,19 @@ def __init__( self.chain_strength = chain_strength self.use_clique_embedding = use_clique_embedding self._use_weights = use_weights - weight = "weight" if use_weights else None - network = Network(G, resolution=resolution, weight=weight, community=community) + + if not hasattr(self, "_full_modularity_matrix"): + self._full_modularity_matrix = Network( + G, resolution=resolution, weight=weight, community=community + ).calculate_full_modularity_matrix() + network = Network( + G, + resolution=resolution, + weight=weight, + community=community, + full_modularity_matrix=self._full_modularity_matrix, + ) problem = CommunityDetectionProblem( network, communities=2, one_hot_encoding=False ) diff --git a/Qommunity/samplers/regular/dqm_sampler/dqm_sampler.py b/Qommunity/samplers/regular/dqm_sampler/dqm_sampler.py index 1a834bce3..0e584fa01 100644 --- a/Qommunity/samplers/regular/dqm_sampler/dqm_sampler.py +++ b/Qommunity/samplers/regular/dqm_sampler/dqm_sampler.py @@ -1,4 +1,4 @@ -from QHyper.solvers.quantum_annealing.dqm import DQM +from QHyper.solvers.quantum_annealing.dwave.dqm import DQM from QHyper.problems.community_detection import Network, CommunityDetectionProblem import networkx as nx from ..regular_sampler import RegularSampler diff --git a/Qommunity/searchers/hierarchical_searcher/hierarchical_searcher.py b/Qommunity/searchers/hierarchical_searcher/hierarchical_searcher.py index 348a3cd53..b241b0ba0 100644 --- a/Qommunity/searchers/hierarchical_searcher/hierarchical_searcher.py +++ b/Qommunity/searchers/hierarchical_searcher/hierarchical_searcher.py @@ -137,7 +137,7 @@ def _hierarchical_search_recursion( if not community: community = [*range(self.sampler.G.number_of_nodes())] - if len(community) == 1: + if len(community) < 2: return [community] if level == 1 and division_tree == []: @@ -153,10 +153,16 @@ def _hierarchical_search_recursion( ) print("===========================================") - self.sampler.update_community(community) - sample = self.sampler.sample_qubo_to_dict() - - c0, c1 = self._split_dict_to_lists(sample, community) + try: + self.sampler.update_community(community) + sample = self.sampler.sample_qubo_to_dict() + c0, c1 = self._split_dict_to_lists(sample, community) + except Exception as e: + if verbosity >= 1: + print( + f"[WARNING] Skipping community {community} at level {level} due to error: {e}" + ) + return [community] if verbosity >= 2: print("Base community:", community, sep="\n") diff --git a/demo.ipynb b/demo.ipynb index 26ceb8362..333c15239 100644 --- a/demo.ipynb +++ b/demo.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -36,17 +36,17 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from Qommunity.samplers.hierarchical.advantage_sampler import AdvantageSampler\n", - "from Qommunity.searchers.hierarchical_community_searcher import (\n", - " HierarchicalCommunitySearcher,\n", + "from Qommunity.searchers.hierarchical_searcher.hierarchical_searcher import (\n", + " HierarchicalSearcher,\n", ")\n", "\n", "advantage = AdvantageSampler(G)\n", - "searcher = HierarchicalCommunitySearcher(advantage)" + "searcher = HierarchicalSearcher(advantage)" ] }, { @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -85,8 +85,8 @@ "Base community:\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", - "[14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", - "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 19, 21]\n", + "[0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]\n", + "[8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "===========================================\n", "\n", "Stopping community detection\n" @@ -95,11 +95,11 @@ { "data": { "text/plain": [ - "[[14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33],\n", - " [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 19, 21]]" + "[[0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21],\n", + " [8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]]" ] }, - "execution_count": 25, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -119,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -133,85 +133,78 @@ "Base community:\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", - "[0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]\n", - "[2, 8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", + "[0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]\n", + "[8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 15 nodes, level of recursion: 2\n", + "Calculations for graph with 16 nodes, level of recursion: 2\n", "===========================================\n", "Base community:\n", - "[0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]\n", + "[0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21]\n", "Community division:\n", + "[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21]\n", "[4, 5, 6, 10, 16]\n", - "[0, 1, 3, 7, 11, 12, 13, 17, 19, 21]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 5 nodes, level of recursion: 3\n", + "Calculations for graph with 11 nodes, level of recursion: 3\n", "===========================================\n", "Base community:\n", - "[4, 5, 6, 10, 16]\n", + "[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21]\n", "Community division:\n", - "[4, 5, 6, 10, 16]\n", "[]\n", + "[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 10 nodes, level of recursion: 3\n", + "Calculations for graph with 5 nodes, level of recursion: 3\n", "===========================================\n", "Base community:\n", - "[0, 1, 3, 7, 11, 12, 13, 17, 19, 21]\n", + "[4, 5, 6, 10, 16]\n", "Community division:\n", "[]\n", - "[0, 1, 3, 7, 11, 12, 13, 17, 19, 21]\n", + "[4, 5, 6, 10, 16]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 19 nodes, level of recursion: 2\n", + "Calculations for graph with 18 nodes, level of recursion: 2\n", "===========================================\n", "Base community:\n", - "[2, 8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", + "[8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", - "[2, 9, 24, 25, 27, 28, 31]\n", - "[8, 14, 15, 18, 20, 22, 23, 26, 29, 30, 32, 33]\n", + "[8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33]\n", + "[23, 24, 25, 27, 28, 31]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 7 nodes, level of recursion: 3\n", + "Calculations for graph with 12 nodes, level of recursion: 3\n", "===========================================\n", "Base community:\n", - "[2, 9, 24, 25, 27, 28, 31]\n", + "[8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33]\n", "Community division:\n", - "[2, 9, 24, 25, 27, 28, 31]\n", + "[8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33]\n", "[]\n", "===========================================\n", - "\n", "===========================================\n", - "Calculations for graph with 12 nodes, level of recursion: 3\n", + "Calculations for graph with 6 nodes, level of recursion: 3\n", "===========================================\n", "Base community:\n", - "[8, 14, 15, 18, 20, 22, 23, 26, 29, 30, 32, 33]\n", + "[23, 24, 25, 27, 28, 31]\n", "Community division:\n", + "[23, 24, 25, 27, 28, 31]\n", "[]\n", - "[8, 14, 15, 18, 20, 22, 23, 26, 29, 30, 32, 33]\n", "===========================================\n", - "\n", "Stopping community detection\n", "Result: \n", - "[[4, 5, 6, 10, 16], [0, 1, 3, 7, 11, 12, 13, 17, 19, 21], [2, 9, 24, 25, 27, 28, 31], [8, 14, 15, 18, 20, 22, 23, 26, 29, 30, 32, 33]]\n" + "[[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21], [4, 5, 6, 10, 16], [8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33], [23, 24, 25, 27, 28, 31]]\n" ] }, { "data": { "text/plain": [ - "[[4, 5, 6, 10, 16],\n", - " [0, 1, 3, 7, 11, 12, 13, 17, 19, 21],\n", - " [2, 9, 24, 25, 27, 28, 31],\n", - " [8, 14, 15, 18, 20, 22, 23, 26, 29, 30, 32, 33]]" + "[[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21],\n", + " [4, 5, 6, 10, 16],\n", + " [8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33],\n", + " [23, 24, 25, 27, 28, 31]]" ] }, - "execution_count": 30, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -236,24 +229,24 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from Qommunity.samplers.regular.dqm_sampler import DQMSampler\n", "from Qommunity.samplers.regular.louvain_sampler import LouvainSampler\n", - "from Qommunity.searchers.community_searcher import CommunitySearcher\n", + "from Qommunity.searchers.regular_searcher.regular_searcher import RegularSearcher\n", "\n", "dqm = DQMSampler(G, 5, 4)\n", "louvain = LouvainSampler(G, 1)\n", "\n", - "dqm_searcher = CommunitySearcher(dqm)\n", - "louvain_searcher = CommunitySearcher(louvain)" + "dqm_searcher = RegularSearcher(dqm)\n", + "louvain_searcher = RegularSearcher(louvain)" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -268,8 +261,8 @@ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", "[23, 24, 25, 27, 28, 31]\n", - "[4, 5, 6, 10, 16]\n", "[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21]\n", + "[4, 5, 6, 10, 16]\n", "[8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33]\n", "===========================================\n", "Stopping community detection\n" @@ -279,12 +272,12 @@ "data": { "text/plain": [ "[[23, 24, 25, 27, 28, 31],\n", - " [4, 5, 6, 10, 16],\n", " [0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21],\n", + " [4, 5, 6, 10, 16],\n", " [8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33]]" ] }, - "execution_count": 19, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -295,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -309,10 +302,10 @@ "Base community:\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", - "['x0', 'x1', 'x2', 'x3', 'x7', 'x11', 'x12', 'x13', 'x17', 'x19', 'x21']\n", - "['x4', 'x5', 'x6', 'x10', 'x16']\n", - "['x23', 'x24', 'x25', 'x27', 'x28', 'x31']\n", - "['x8', 'x9', 'x14', 'x15', 'x18', 'x20', 'x22', 'x26', 'x29', 'x30', 'x32', 'x33']\n", + "['s0', 's1', 's2', 's3', 's7', 's11', 's12', 's13', 's17', 's19', 's21']\n", + "['s4', 's5', 's6', 's10', 's16']\n", + "['s23', 's24', 's25', 's27', 's28', 's31']\n", + "['s8', 's9', 's14', 's15', 's18', 's20', 's22', 's26', 's29', 's30', 's32', 's33']\n", "===========================================\n", "Stopping community detection\n" ] @@ -320,43 +313,43 @@ { "data": { "text/plain": [ - "{'x0': 0,\n", - " 'x1': 0,\n", - " 'x2': 0,\n", - " 'x3': 0,\n", - " 'x4': 1,\n", - " 'x5': 1,\n", - " 'x6': 1,\n", - " 'x7': 0,\n", - " 'x8': 3,\n", - " 'x9': 3,\n", - " 'x10': 1,\n", - " 'x11': 0,\n", - " 'x12': 0,\n", - " 'x13': 0,\n", - " 'x14': 3,\n", - " 'x15': 3,\n", - " 'x16': 1,\n", - " 'x17': 0,\n", - " 'x18': 3,\n", - " 'x19': 0,\n", - " 'x20': 3,\n", - " 'x21': 0,\n", - " 'x22': 3,\n", - " 'x23': 2,\n", - " 'x24': 2,\n", - " 'x25': 2,\n", - " 'x26': 3,\n", - " 'x27': 2,\n", - " 'x28': 2,\n", - " 'x29': 3,\n", - " 'x30': 3,\n", - " 'x31': 2,\n", - " 'x32': 3,\n", - " 'x33': 3}" + "{'s0': 0,\n", + " 's1': 0,\n", + " 's2': 0,\n", + " 's3': 0,\n", + " 's4': 1,\n", + " 's5': 1,\n", + " 's6': 1,\n", + " 's7': 0,\n", + " 's8': 3,\n", + " 's9': 3,\n", + " 's10': 1,\n", + " 's11': 0,\n", + " 's12': 0,\n", + " 's13': 0,\n", + " 's14': 3,\n", + " 's15': 3,\n", + " 's16': 1,\n", + " 's17': 0,\n", + " 's18': 3,\n", + " 's19': 0,\n", + " 's20': 3,\n", + " 's21': 0,\n", + " 's22': 3,\n", + " 's23': 2,\n", + " 's24': 2,\n", + " 's25': 2,\n", + " 's26': 3,\n", + " 's27': 2,\n", + " 's28': 2,\n", + " 's29': 3,\n", + " 's30': 3,\n", + " 's31': 2,\n", + " 's32': 3,\n", + " 's33': 3}" ] }, - "execution_count": 20, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -367,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -383,8 +376,7 @@ "Community division:\n", "[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21]\n", "[16, 4, 5, 6, 10]\n", - "[32, 33, 8, 9, 14, 15, 18, 20, 22, 23, 26, 27, 29, 30]\n", - "[24, 25, 28, 31]\n", + "[8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "===========================================\n", "Stopping community detection\n" ] @@ -394,11 +386,10 @@ "text/plain": [ "[[0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21],\n", " [16, 4, 5, 6, 10],\n", - " [32, 33, 8, 9, 14, 15, 18, 20, 22, 23, 26, 27, 29, 30],\n", - " [24, 25, 28, 31]]" + " [8, 9, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]]" ] }, - "execution_count": 23, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -409,7 +400,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -423,10 +414,10 @@ "Base community:\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]\n", "Community division:\n", - "['x0', 'x4', 'x5', 'x6', 'x10', 'x11', 'x16', 'x17', 'x19', 'x21']\n", - "['x1', 'x2', 'x3', 'x7', 'x12', 'x13']\n", - "['x23', 'x24', 'x25', 'x27', 'x28', 'x31']\n", - "['x32', 'x33', 'x8', 'x9', 'x14', 'x15', 'x18', 'x20', 'x22', 'x26', 'x29', 'x30']\n", + "['x0', 'x1', 'x2', 'x3', 'x7', 'x11', 'x12', 'x13', 'x17', 'x19', 'x21']\n", + "['x16', 'x4', 'x5', 'x6', 'x10']\n", + "['x24', 'x25', 'x28', 'x31']\n", + "['x32', 'x33', 'x8', 'x9', 'x14', 'x15', 'x18', 'x20', 'x22', 'x23', 'x26', 'x27', 'x29', 'x30']\n", "===========================================\n", "Stopping community detection\n" ] @@ -435,25 +426,23 @@ "data": { "text/plain": [ "{'x0': 0,\n", - " 'x4': 0,\n", - " 'x5': 0,\n", - " 'x6': 0,\n", - " 'x10': 0,\n", + " 'x1': 0,\n", + " 'x2': 0,\n", + " 'x3': 0,\n", + " 'x7': 0,\n", " 'x11': 0,\n", - " 'x16': 0,\n", + " 'x12': 0,\n", + " 'x13': 0,\n", " 'x17': 0,\n", " 'x19': 0,\n", " 'x21': 0,\n", - " 'x1': 1,\n", - " 'x2': 1,\n", - " 'x3': 1,\n", - " 'x7': 1,\n", - " 'x12': 1,\n", - " 'x13': 1,\n", - " 'x23': 2,\n", + " 'x16': 1,\n", + " 'x4': 1,\n", + " 'x5': 1,\n", + " 'x6': 1,\n", + " 'x10': 1,\n", " 'x24': 2,\n", " 'x25': 2,\n", - " 'x27': 2,\n", " 'x28': 2,\n", " 'x31': 2,\n", " 'x32': 3,\n", @@ -465,12 +454,14 @@ " 'x18': 3,\n", " 'x20': 3,\n", " 'x22': 3,\n", + " 'x23': 3,\n", " 'x26': 3,\n", + " 'x27': 3,\n", " 'x29': 3,\n", " 'x30': 3}" ] }, - "execution_count": 31, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -496,7 +487,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.11.1" } }, "nbformat": 4, diff --git a/requirements.txt b/requirements.txt index 01586f949..ec2d76732 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ +# Requires Python >=3.9,<=3.11 + bayanpy==0.7.7 dimod==0.12.16 dwave_cloud_client==0.12.0 @@ -9,5 +11,5 @@ leidenalg==0.10.2 networkx==3.3 pytest==8.2.2 python_igraph==0.11.6 -QHyper==0.2.2 +QHyper==0.3.3 powerlaw \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 000000000..fcfcd22a7 --- /dev/null +++ b/setup.py @@ -0,0 +1,30 @@ +from setuptools import setup, find_packages + +setup( + name="Qommunity", + version="0.1.0", + description="Library for community detection where you can use variety of solvers, including quantum solvers", + packages=find_packages(), + python_requires=">=3.9,<=3.11", + install_requires=[ + "bayanpy==0.7.7", + "dimod==0.12.16", + "dwave_cloud_client==0.12.0", + "dwave_optimization==0.1.0", + "dwave_preprocessing==0.6.6", + "dwave_samplers==1.3.0", + "dwave_system==1.24.0", + "leidenalg==0.10.2", + "networkx==3.3", + "pytest==8.2.2", + "python_igraph==0.11.6", + "powerlaw", + "QHyper==0.3.3", + ], + classifiers=[ + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Operating System :: OS Independent", + ], +) \ No newline at end of file