社交网络影响力最大化——贪心算法实现(Python实现)

简介: 社交网络影响力最大化——贪心算法实现(Python实现)环境: Win7 Pycharm Anaconda2该算法每个节点的阈值设为 0.
社交网络影响力最大化——贪心算法实现(Python实现)

环境: Win7 Pycharm Anaconda2

该算法每个节点的阈值设为 0.5


linear_threshold_clime.py(LT传播模型算法)
# -*- coding: utf-8 -*-
"""
Implement linear threshold models

"""
import copy
import itertools
import random
import math
import networkx as nx

__all__ = ['linear_threshold']

#-------------------------------------------------------------------------
#  Some Famous Diffusion Models
#-------------------------------------------------------------------------

def linear_threshold(G, seeds, steps=0):
  """

  Parameters
  ----------
  G : networkx graph
      The number of nodes.

  seeds: list of nodes
      The seed nodes of the graph

  steps: int
      The number of steps to diffuse
      When steps <= 0, the model diffuses until no more nodes
      can be activated

  Return
  ------
  layer_i_nodes : list of list of activated nodes
    layer_i_nodes[0]: the seeds
    layer_i_nodes[k]: the nodes activated at the kth diffusion step

  Notes
  -----
  1. Each node is supposed to have an attribute "threshold".  If not, the
     default value is given (0.5).
  2. Each edge is supposed to have an attribute "influence".  If not, the
     default value is given (out_deg / out_deg_sum)

  """
  if type(G) == nx.MultiGraph or type(G) == nx.MultiDiGraph:
      raise Exception( \
          "linear_threshold() is not defined for graphs with multiedges.")

  # make sure the seeds are in the graph
  for s in seeds:
    if s not in G.nodes():
      raise Exception("seed", s, "is not in graph")

  # change to directed graph
  if not G.is_directed():
     #DG = G.to_directed()
     DG=nx.DiGraph(G)
  else:
    DG = copy.deepcopy(G)

  # init thresholds
  for n in DG.nodes():
    if 'threshold' not in DG.node[n]:
      DG.node[n]['threshold'] = 0.5
    elif DG.node[n]['threshold'] > 1:
      raise Exception("node threshold:", DG.node[n]['threshold'], \
          "cannot be larger than 1")

  # init influences

 # in_deg_all = DG.in_degree()        #获取所有节点的入度
  out_deg_all=DG.out_degree()        #获取所有节点的出度
  in_edges_all=DG.in_edges()         #获取所有的入边
  for e in DG.edges():               #对所有的边进行循环
    if 'influence' not in DG[e[0]][e[1]]:
      out_deg=out_deg_all[e[0]]      #获取节点e[0]的出度
      in_edges=in_edges_all._adjdict[e[1]]    #获取节点e[1]的所有的入边
      edges_dict=dict(in_edges)
      in_all_edges=list(edges_dict.keys())      #获取节点e[1]的所有入边节点并存入列表
      out_deg_sum=0
      for i in in_all_edges:                #求节点e[1]所有入边节点的出度和
        out_deg_sum=out_deg_sum+out_deg_all[i]
      DG[e[0]][e[1]]['influence'] = out_deg / out_deg_sum
    elif DG[e[0]][e[1]]['influence'] > 1:
      raise Exception("edge influence:", DG[e[0]][e[1]]['influence'], \
          "cannot be larger than 1")



  # perform diffusion
  A = copy.deepcopy(seeds)
  if steps <= 0:
    # perform diffusion until no more nodes can be activated
    return _diffuse_all(DG, A)
  # perform diffusion for at most "steps" rounds only
  return _diffuse_k_rounds(DG, A, steps)

def _diffuse_all(G, A):
  layer_i_nodes = [ ]
  layer_i_nodes.append([i for i in A])
  while True:
    len_old = len(A)
    A, activated_nodes_of_this_round = _diffuse_one_round(G, A)
    layer_i_nodes.append(activated_nodes_of_this_round)
    if len(A) == len_old:
      break
  return layer_i_nodes

def _diffuse_k_rounds(G, A, steps):
  layer_i_nodes = [ ]
  layer_i_nodes.append([i for i in A])
  while steps > 0 and len(A) < len(G):
    len_old = len(A)
    A, activated_nodes_of_this_round = _diffuse_one_round(G, A)
    layer_i_nodes.append(activated_nodes_of_this_round)
    if len(A) == len_old:
      break
    steps -= 1
  return layer_i_nodes

def _diffuse_one_round(G, A):
  activated_nodes_of_this_round = set()
  for s in A:
    nbs = G.successors(s)
    for nb in nbs:
      if nb in A:
        continue
      active_nb = list(set(G.predecessors(nb)).intersection(set(A)))
      if _influence_sum(G, active_nb, nb) >= G.node[nb]['threshold']:
        activated_nodes_of_this_round.add(nb)
  A.extend(list(activated_nodes_of_this_round))
  return A, list(activated_nodes_of_this_round)

def _influence_sum(G, froms, to):
  influence_sum = 0.0
  for f in froms:
    influence_sum += G[f][to]['influence']
  return influence_sum




test_linear_threshold_clime.py
#!/usr/bin/env python
# coding=UTF-8
from nose.tools import *
from networkx import *
from linear_threshold_clime import *
"""Test Diffusion Models
----------------------------
"""
#贪心算法
def _linear_clime(G,k):      #参数k-表示要获取的子节点的个数
    allnodes = G.nodes()     #获取图中所有节点数
    seed_nodes = []          #该列表存储选取的子节点集
    for m in range(k):
        all_nodes = list(allnodes)   #将所有的节点存储在all_nodes列表里
        layers_activite = []    # 存储每个节点的激活节点列表
        lengths = []         # 存储每个节点的激活列表长度
        datas = []
        for i in all_nodes:   #遍历所有的节点,分别求出每个节点对应的激活节点集以及激活节点集的长度
            data = []
            data.append(i)
            datas.append(i)
            data_test=seed_nodes+data
            layers = linear_threshold(G,data_test)
            data.pop()
            del layers[-1]
            length = 0
            layer_data = []
            for j in range(len(layers)):
                length = length + len(layers[j])
                layer_data = layer_data + layers[j]
            length_s = length - len(layers[0])
            for s in range(len(layers[0])):
                del layer_data[0]
            layers_activite.append(layer_data)
            lengths.append(length_s)
      # length_max = max(lengths)  # 获取激活节点最多的节点数
        layers_max = layers_activite[lengths.index(max(lengths))]  # 获取被激活节点数最多的列表
        seed_nodes.append(datas[lengths.index(max(lengths))])      # 获取被激活节点最多的子节点
        for i in all_nodes:       #该循环是删除所有节点中seed_nodes节点集
            if i in seed_nodes:
                del all_nodes[all_nodes.index(i)]
        allnodes=all_nodes
    return seed_nodes,layers_max     #返回值是贪心算法求得的子节点集和该子节点集激活的最大节点集

#测试算法
if __name__=='__main__':
    datasets=[]
    f=open("Wiki-Vote.txt")
    data=f.read()
    rows=data.split('\n')
    for row in rows:
      split_row=row.split('\t')
      name=(int(split_row[0]),int(split_row[1]))
      datasets.append(name)
    G=networkx.DiGraph()
    G.add_edges_from(datasets)   #根据数据集创建有向图

    n=input('Please input the number of seeds: k=')
    k=int(n)
    seed_nodes, layers_max=_linear_clime(G,k)   #调用贪心算法获取节点子集和节点子集的最大激活节点集

    print(seed_nodes)
    print(layers_max)


运行结果


LT_improve.py(LT模型改进算法)
#!/usr/bin/env python
# coding=UTF-8
from nose.tools import *
from networkx import *
from linear_threshold_clime import *
from linear_threshold  import *
import math

#计算图中边的权重
def Buv_calculate(G,u,v):
    out_deg_all = G.out_degree()  # 获取所有节点的出度
    in_edges_all = G.in_edges()  # 获取所有的入边
    out_deg = out_deg_all[u]  # 获取节点e[0]的出度
    in_edges = in_edges_all._adjdict[v]  # 获取节点e[1]的所有的入边
    edges_dict = dict(in_edges)
    in_all_edges = list(edges_dict.keys())  # 获取节点e[1]的所有入边节点并存入列表
    out_deg_sum = 0
    for i in in_all_edges:  # 求节点e[1]所有入边节点的出度和
        out_deg_sum = out_deg_sum + out_deg_all[i]
    return out_deg / out_deg_sum

#计算每个节点AP的值
def AP_calculate(node):
    data = []
    data.append(node)
    layer_two_nodes = linear_threshold(G, data, 2)  # 获取每个节点的两层出度节点数
    data.pop()
    del layer_two_nodes[-1]
    length = 0
    for i in range(len(layer_two_nodes)):
        length = length + len(layer_two_nodes[i])
    lengths = length - len(layer_two_nodes[0])

    out_edges = out_edges_all._adjdict[node]  # 获得节点的出边
    edges_dict = dict(out_edges)
    out_all_edges = list(edges_dict.keys())  # 将节点的所有出边存入列表
    Buv_sum = 0
    for out_edge in out_all_edges:   # 计算该节点所有出边的Buv的值
        Buv = Buv_calculate(G, node, out_edge)
        Buv_sum = Buv_sum + Buv
    cha_sum = 1 + math.e ** (-Buv_sum)
    AP = lengths + cha_sum
    return AP

def select_layers(G,node_list_sorted,k1):   #选择前k/2个节点的算法实现
    seed_nodes = []  # 存贮种子节点
    for i in range(k1):
        data = []
        data.append(node_list_sorted[0][0])
        seed_nodes.append(node_list_sorted[0][0])
        layers = linear_threshold(G, data)        # 使用LT算法
        data.pop()
        del layers[-1]
        layers_activate = []
        for i in layers:  # 将种子节点和激活的节点存入layers_activate列表
            for j in i:
                layers_activate.append(j)

        for m in node_list_sorted:  # 删除node_list_sorted中的layers_activate
            for n in layers_activate:
                if m[0] == n:
                    node_list_sorted.remove(m)

    return seed_nodes,node_list_sorted

def _select_others(seed_nodes, other_nodes,k2):     #贪心算法选择剩余k/2个节点
    for m in range(k2):
        all_nodes = list(other_nodes)   #将所有的节点存储在all_nodes列表里
        layers_activite = []    # 存储每个节点的激活节点列表
        lengths = []         # 存储每个节点的激活列表长度
        datas = []
        for i in all_nodes:   #遍历所有的节点,分别求出每个节点对应的激活节点集以及激活节点集的长度
            data = []
            data.append(i)
            datas.append(i)
            data_test=seed_nodes+data
            layers = linear_threshold(G,data_test)
            data.pop()
            del layers[-1]
            length = 0
            layer_data = []
            for j in range(len(layers)):
                length = length + len(layers[j])
                layer_data = layer_data + layers[j]
            length_s = length - len(layers[0])
            for s in range(len(layers[0])):
                del layer_data[0]
            layers_activite.append(layer_data)
            lengths.append(length_s)
        layers_max = layers_activite[lengths.index(max(lengths))]  # 获取被激活节点数最多的列表
        seed_nodes.append(datas[lengths.index(max(lengths))])      # 获取被激活节点最多的子节点
        for i in all_nodes:       #该循环是删除所有节点中seed_nodes节点集
            if i in seed_nodes:
                del all_nodes[all_nodes.index(i)]
        other_nodes=all_nodes
    return seed_nodes,layers_max     #返回值是贪心算法求得的子节点集和该子节点集激活的最大节点集


if __name__=='__main__':
    datasets=[]
    f=open("Wiki-Vote.txt")
    data=f.read()
    rows=data.split('\n')
    for row in rows:
      split_row=row.split('\t')
      name=(int(split_row[0]),int(split_row[1]))
      datasets.append(name)
    G=networkx.DiGraph()
    G.add_edges_from(datasets)   #根据数据集创建有向图

    allnodes=G.nodes()           #获取图中所有的节点
    all_nodes=list(allnodes)
    out_edges_all = G.out_edges() # 获取所有节点的出边
    node_dict={}               #将节点和节点对应的AP值存入字典


    for node in all_nodes:        #遍历所有节点获得每个节点的AP值
        AP=AP_calculate(node)
        node_dict[node]=AP

    node_list_sorted=sorted(node_dict.items(),key=lambda d:d[1],reverse=True)  #对字典按AP值进行由大到小排序
    '''
    f=open('data.txt','r')
    data=f.read()
    node_list_sorted=list(data)
    '''
    k=input('Please input inter of k=')
    seed_nodes, node_list_sorted=select_layers(G,node_list_sorted,k/2)
    other_nodes=[]
    '''
    for i in range(len(node_list_sorted)):
        other_nodes.append(node_list_sorted[i][0])
    '''
    for i in seed_nodes:
        if i in all_nodes:
            all_nodes.remove(i)
    other_nodes=all_nodes

    seed_nodes, layers_max=_select_others(seed_nodes,other_nodes,k/2)
    layer=linear_threshold(G,seed_nodes)
    lenth=len(layers_max)
    print(seed_nodes)
    print(layers_max)
    print(lenth)
    print(layer)


运行结果:











相关文章
|
3天前
|
机器学习/深度学习 自然语言处理 PyTorch
使用Python实现循环神经网络(RNN)的博客教程
使用Python实现循环神经网络(RNN)的博客教程
23 1
|
1天前
|
数据采集 算法 数据可视化
python实现时序平滑算法SG滤波器
python实现时序平滑算法SG滤波器
|
4天前
|
算法
【免费】面向多微网网络结构设计的大规模二进制矩阵优化算法
【免费】面向多微网网络结构设计的大规模二进制矩阵优化算法
|
5天前
|
存储 JavaScript 前端开发
Python网络数据抓取(5):Pandas
Python网络数据抓取(5):Pandas
28 8
|
6天前
|
机器学习/深度学习 自然语言处理 算法
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
Python遗传算法GA对长短期记忆LSTM深度学习模型超参数调优分析司机数据|附数据代码
|
6天前
|
算法 机器人 Python
Python实现教程:平面最短路径算法
Python实现教程:平面最短路径算法
13 1
|
12天前
|
机器学习/深度学习 PyTorch TensorFlow
【Python机器学习专栏】循环神经网络(RNN)与LSTM详解
【4月更文挑战第30天】本文探讨了处理序列数据的关键模型——循环神经网络(RNN)及其优化版长短期记忆网络(LSTM)。RNN利用循环结构处理序列依赖,但遭遇梯度消失/爆炸问题。LSTM通过门控机制解决了这一问题,有效捕捉长距离依赖。在Python中,可使用深度学习框架如PyTorch实现LSTM。示例代码展示了如何定义和初始化一个简单的LSTM网络结构,强调了RNN和LSTM在序列任务中的应用价值。
|
12天前
|
机器学习/深度学习 PyTorch TensorFlow
【Python机器学习专栏】卷积神经网络(CNN)的原理与应用
【4月更文挑战第30天】本文介绍了卷积神经网络(CNN)的基本原理和结构组成,包括卷积层、激活函数、池化层和全连接层。CNN在图像识别等领域表现出色,其层次结构能逐步提取特征。在Python中,可利用TensorFlow或PyTorch构建CNN模型,示例代码展示了使用TensorFlow Keras API创建简单CNN的过程。CNN作为强大深度学习模型,未来仍有广阔发展空间。
|
12天前
|
机器学习/深度学习 自然语言处理 语音技术
【Python 机器学习专栏】Python 深度学习入门:神经网络基础
【4月更文挑战第30天】本文介绍了Python在深度学习中应用于神经网络的基础知识,包括神经网络概念、基本结构、训练过程,以及Python中的深度学习库TensorFlow和PyTorch。通过示例展示了如何使用Python实现神经网络,并提及优化技巧如正则化和Dropout。最后,概述了神经网络在图像识别、语音识别和自然语言处理等领域的应用,并强调掌握这些知识对深度学习的重要性。随着技术进步,神经网络的应用将持续扩展,期待更多创新。
|
12天前
|
机器学习/深度学习 运维 算法
【Python机器学习专栏】异常检测算法在Python中的实践
【4月更文挑战第30天】本文介绍了异常检测的重要性和在不同领域的应用,如欺诈检测和网络安全。文章概述了四种常见异常检测算法:基于统计、距离、密度和模型的方法。在Python实践中,使用scikit-learn库展示了如何实现这些算法,包括正态分布拟合、K-means聚类、局部异常因子(LOF)和孤立森林(Isolation Forest)。通过计算概率密度、距离、LOF值和数据点的平均路径长度来识别异常值。