贪心算法的改进

2023-05-16

关于贪心算法,请看我的上一篇博客。

      1. 解决贪心算法的复杂度

为解决贪心算法的复杂度。本文提出:通过分解极大联通子图去寻找影响力最大的节点的算法。

强连通:在有向图G中,如果任意两个不同的顶点相互可达,则称该有向图是强连通的。

极大强连通子图:G 是一个极大强连通子图当且仅当 G 是一个强连通子图且不存在另一个强连通子图 G’使得 G 是 G’的真子集。也就是说不可能找到一个包含它的强连通分量。若将有向图中的强连通分量都缩为一个点,则原图会形成一个 DAG(有向无环图)

该改进算法是基于对图深度优先搜索(DFS)的算法,每个强连通分量为搜索树中的一棵子树(的一部分)。搜索时,把当前搜索树中未处理的结点加入一个栈,对于每一个结点,当它自己搜索完毕时判断是否存在强连通分量。

算法:void dfs(int u)

{

    times++;//记录dfn顺序

    dfn[u]=times;//赋值

    low[u]=times;//先赋初值

    vis[u]=true;//vis[i]用来判断i是否搜索过;

    insta[u]=true;//表示是否在栈中,true为在栈中;

    stack[top]=u;//栈顶

    top++;

    for(int i=head[u];i!=-1;i=edge[i].next)// 以建图顺序枚举此点所连的边

    {

        int v=edge[i].to;//搜索到的点

        if(!vis[v])//如果未搜索过即未入栈

        {

            dfs(v);//继续以此点进行深搜

            low[u]=min(low[u],low[v]);//更新low值,此边为树枝边所以比较u此时的

        }                           // low值(未更新时就是其dfn值)和v的low值

        else

            if(insta[v]==true)//如果搜索过且在栈中,说明此边为后向边或栈中横叉边

            {

                low[u]=min(low[u],dfn[v]);//更新low值,比较u此时的low值和v的dfn值

            }

    }

    if(low[u]==dfn[u])//相等说明找到一个强连通分量

    {

        while(top>0&&stack[top]!=u)//开始退栈一直退到 u为止

        {

            top--;

            insta[stack[top]]=false;

        }

    }

}

分解完之后再用上述贪心算法。

      1. 改进LT模型,重复使用贪心算法

在LT模型的基础上:计算边的权重,计算每个节点AP的值,选择前k/2个节点,贪心算法再选择后k/2个节点。减小了计算的复杂度,增加权重和AP值使模型更可靠。

#计算图中边的权重

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     #返回值是贪心算法求得的子节点集和该子节点集激活的最大节点集

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

贪心算法的改进 的相关文章

随机推荐

  • 《软件工程》试题举例-简答题

    Please give out 3 pieces of recommendations regarding language independent good programming practice 6 marks 良好的编程实践的建议
  • 2020届电子信息类专业保研经历分享

    文章目录 一 个人基本情况二 初心三 夏令营 九推情况介绍1 上海交大自动化系直硕面试 xff08 7月8日 xff09 2 中科大信息学院夏令营 xff08 7月15日 xff09 3 中科院自动化所夏令营 xff08 7月23日 xff
  • RGB图与灰度图相互转换关系表达式

    RGB图转灰度图 1 Y 61 0 3R 43 0 59G 43 0 11B 2 平均值法 xff0c 将RGB平均 灰度图转RGB图 先将单通道的灰度图转为三通道的RGB图 xff0c 各通道值的初值赋值为与灰度值相同 然后按照下式映射关
  • sklearn包导入错误:ImportError: cannot import name ‘Type‘解决办法

    在python3 5环境下使用pip直接安装sklearn包后 xff0c 导入出现如下错误 xff1a 仔细观察报错信息可以发现 xff0c 出错的是sklearn中使用到的scipy包 单独导入scipy包发现出错 xff1a 看来 x
  • PyTorch Dataloader报错ValueError: num_samples的另一种可能原因

    先粘报错信息 xff1a Traceback most recent call last File train py line 169 in train test File train py line 29 in train test da
  • Focal loss变种汇总

    VariFocal loss 只对负样本做难易样本挖掘 xff08 正样本数量少 xff0c 不做loss压缩 xff09 Generalized Focal loss xff1a quality focal loss 43 distrib
  • 视觉Transformer中的位置编码方式

    绝对位置编码 基本形式 xff1a x 61 x 43 p 可学习的绝对位置编码 xff08 ViT xff09 ViT中提出的位置编码方式简单粗暴 xff0c 设置一组可学习的编码tokens xff0c 并在patch embeding
  • 秋招问题汇总

    1 Python变量作用域 xff1a 局部作用域 xff08 Local xff0c 简写为 L xff09 作用于闭包函数外的函数中的作用域 xff08 Enclosing xff0c 简写为 E xff09 全局作用域 xff08 G
  • 38、OpenCV之C++教程

    一 OpenCV的下载与安装 下载完成后会得到一个 opencv 3 4 15 vc14 vc15 exe 文件 点击运行后会生成一个文件夹 此文件夹为下一步工程创建使用 xff0c 文件夹可移动 复制和重命名 xff0c 这里命名如下 x
  • Java大数据之路--HDFS详解(3)--基本命令

    HDFS 分布式文件存储系统 基本命令 目录 HDFS 分布式文件存储系统 基本命令 一 常见命令 二 其他命令 一 常见命令 命令 说明 hadoop fs mkdir park 在hdfs 的根目录下 xff0c 创建 park目录 h
  • C# 连接 SqlServer 数据库

    目录 一 创建表 二 给表添加数据 三 新建 C 项目 四 SqlServerHelper 五 连接数据库 一 创建表 首先 xff0c 新建一个数据库 Test xff0c 然后新建一个表 Users xff0c 字段名如下图 xff0c
  • org.xml.sax.SAXParseException的错误解决 2020-11-20

    span class token number 2020 span span class token operator span span class token number 11 span span class token operat
  • JS如何优雅的删除对象中的指定属性?

    要优雅的话 xff0c 使用 Lodash 的 omit 方法移除不要的属性 xff1a const object 61 a 1 b 2 c 3 const result 61 omit object a c 61 gt b 2 或者用 p
  • python 使用 isdigit 判断字符串中是否只由数字组成

    span class token operator span span class token operator span span class token operator span span class token operator s
  • 快速排序详解(Java实现)

    一 快速排序的基本思想 每一轮的排序都会将区域分割成两个独立的分区 xff0c 其中左分区的序列的所有值均会比右分区的所有值小 然后对子分区进行同样的分割操作 xff0c 最后达到整体有序 在排序的过程中 xff0c 由于已经分开的两部分的
  • A*算法路径规划之Matlab实现

    A 算法路径规划之matlab实现 A 算法是一种传统的路径规划算法 xff0c 相较于Dijkstra算法 xff0c 其引入了启发式算子 xff0c 有效的提高了路径的搜索效率 主要步骤包括 xff1a 1 xff09 设置起始点 目标
  • C语言中‘a‘和“a“有什么区别?

    1 本质区别 双引号里面的是字符串 xff0c 而单引号里面的代表字符 2 输出区别 str 61 a 输出的就是a这个字母 xff1b str 61 a 输出的测试65 3 底层区别 用单引号引起的一个字符实际上代表一个整数 xff0c
  • linux VNC客户端登陆失败

    vnc登陆出现 Unknown authentication scheme from VNC server 解决办法 xff08 建议在做操作之前重启vnc server xff0c 密码输错过多可能导致一直连接失败 xff09 https
  • win 10 mstsc连接 RemoteApp

    本文是关于mstsc客户端的配置 xff08 服务端的配置本文不描述 xff09 xff0c 前提是服务端配好 xff0c 知道RemoteApp怎么玩的 windows 2008 的mstsc有个配置 xff0c 关于程序 的tab页 但
  • 贪心算法的改进

    关于贪心算法 xff0c 请看我的上一篇博客 解决贪心算法的复杂度 为解决贪心算法的复杂度 本文提出 xff1a 通过分解极大联通子图去寻找影响力最大的节点的算法 强连通 xff1a 在有向图G中 xff0c 如果任意两个不同的顶点相互可达