Source code for pynetim.py.algorithms.heuristic_algorithm

import heapq
import time
from collections import defaultdict

from ..graph import IMGraph
from .base_algorithm import BaseAlgorithm


[docs] class SingleDiscountAlgorithm(BaseAlgorithm): """ 简单度折扣启发式算法(Single Discount)用于选择影响力最大化种子节点。 该算法通过逐步选择具有最高度数的节点作为种子,并对其邻居节点的度数进行折扣, 以避免选择过多相互连接的节点。 参考文献: - Chen, W., Wang, Y., & Yang, S. (2009). "Efficient influence maximization in social networks." Proceedings of the 15th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (KDD), 199-208. DOI: 10.1145/1557019.1557047 URL: https://dl.acm.org/doi/10.1145/1557019.1557047 """ def __init__(self, graph: IMGraph, diffusion_model=None): """ 初始化简单度折扣算法实例。 Args: graph (IMGraph): 输入图对象 diffusion_model: 扩散模型,此算法不使用该参数 """ super(SingleDiscountAlgorithm, self).__init__(graph, diffusion_model)
[docs] def run(self, k: int): """ 运行简单度折扣算法选择k个种子节点。 Args: k (int): 需要选择的种子节点数量 Returns: list: 选择的种子节点列表 """ d = dict(self.graph.out_degree()) # 节点的初始度数 seeds = [] # 存储种子节点 selected = set() # 记录已选择的种子节点 # 使用最大堆存储 (-度数, 节点),堆中的节点按度数排序 heap = [(-d[v], v) for v in self.graph.nodes] heapq.heapify(heap) while len(seeds) < k: # 选择度数最大的节点作为种子节点 _, u = heapq.heappop(heap) if u in selected: continue seeds.append(u) # 将 u 添加到种子集合中 selected.add(u) # 标记 u 为已选择的节点 # 对 u 的邻居节点的度数进行折扣 for v in self.graph.out_neighbors(u): if v not in selected: d[v] -= 1 # 将邻居节点 v 的度数减一 # 重新将折扣后的节点放回堆中(更新度数) heapq.heappush(heap, (-d[v], v)) self.seeds = seeds return seeds
[docs] class DegreeDiscountAlgorithm(BaseAlgorithm): """ 度折扣启发式算法(Degree Discount)用于选择影响力最大化种子节点。 该算法是Single Discount的改进版本,考虑了邻居节点之间的影响关系, 使用更复杂的折扣公式来更好地评估节点的边际影响力。 参考文献: - Chen, W., Wang, Y., & Yang, S. (2009). "Efficient influence maximization in social networks." Proceedings of the 15th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (KDD), 199-208. DOI: 10.1145/1557019.1557047 URL: https://dl.acm.org/doi/10.1145/1557019.1557047 """ def __init__(self, graph: IMGraph, diffusion_model='IC'): """ 初始化度折扣算法实例。 Args: graph (IMGraph): 输入图对象 diffusion_model (str, optional): 扩散模型,默认为'IC' """ super(DegreeDiscountAlgorithm, self).__init__(graph, diffusion_model)
[docs] def run(self, k: int): """ 运行度折扣算法选择k个种子节点。 Args: k (int): 需要选择的种子节点数量 Returns: list: 选择的种子节点列表 """ d = dict(self.graph.out_degree()) # 节点的度 dd = d.copy() # 折扣度 degree discount t = defaultdict(int) # t[v]: 节点v已被选为邻居种子的数量 seeds = [] # 最终种子集合 # 使用最大堆存储 (-折扣度, 节点),注意 heapq 是最小堆,所以取负值 heap = [(-dd[v], v) for v in self.graph.nodes] heapq.heapify(heap) selected = set() while len(seeds) < k: _, u = heapq.heappop(heap) if u in selected: continue seeds.append(u) selected.add(u) for v in self.graph.out_neighbors(u): if v in selected: continue t[v] += 1 # 获取边的权重 weight = self.graph.edges[u, v]["weight"] # 更新折扣度 dd[v] = d[v] - 2 * t[v] - (d[v] - t[v]) * t[v] * weight heapq.heappush(heap, (-dd[v], v)) # 更新堆中的节点 self.seeds = seeds return seeds