Anita=energic 2024-02-05 22:18 采纳率: 0%
浏览 6

java运行Louvain算法,从数据库中批量添加边,运算不出来,该怎么解决

java运行Louvain算法,运行这位老哥的代码出现了问题https://blog.csdn.net/weixin_42111859/article/details/108537783
我想从数据库中批量添加边,然后我的数据量很大,导致第二个dst值很大,然后,即使我试着只读取10条数据,也运算不出来,该怎么解决

这是我的表
src dst weight
3 87743 1
5 87746 1
11 87749 1
12 87753 1
13 87755 1
15 87757 1
18 87759 1
19 87762 1
21 87764 1

原来老哥这部分代码是这样的:

public void testSingle() {
        Graph g = new Graph();
        // 0->1->2->0
        g.addLinks(Arrays.asList(new Link(0, 1, 1.0)));
        g.addLinks(Arrays.asList(new Link(1, 2, 1.0)));
        g.addLinks(Arrays.asList(new Link(2, 0, 1.0)));
        // 3->4->5->3
        g.addLinks(Arrays.asList(new Link(3, 4, 1.0)));
        g.addLinks(Arrays.asList(new Link(4, 5, 1.0)));
        g.addLinks(Arrays.asList(new Link(5, 3, 1.0)));
        // 构造计算器
        LouvainCalculator louvainCalculator = new LouvainCalculator(g);
        // 执行划分
        CommunityInfo communityInfo = louvainCalculator.findCommunitiesSingleLevel();
        // 输出结果
        System.out.println(communityInfo);
    }

我修改完的代码:


 Graph g = new Graph();
        for (Point point :  points) {
      g.addLinks(Arrays.asList(new Link(point.getSrc(), point.getDst(), point.getWeight())));

        }
//      g.addLinks(Arrays.asList(new Link(0, 1, 1.0)));
     // 构造计算器
      LouvainCalculator louvainCalculator = new LouvainCalculator(g);
     // 执行划分
     CommunityInfo communityInfo = louvainCalculator.findCommunitiesSingleLevel();
   // 输出结果
      System.out.println(communityInfo);
      return communityInfo;
    }


  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-05 22:21
    关注

    引自免费微信小程序:皆我百晓生

    在Java中运行Louvain算法并从数据库批量读取边构建图时,如果遇到数据量大导致无法计算的问题,可以从以下几个方面排查和优化:

    1. 内存管理:由于数据量大,可能超出Java虚拟机的内存限制。确保已为JVM分配足够的堆空间以容纳整个图结构。可以在启动Java应用时通过-Xms-Xmx参数设置初始和最大堆大小。

    2. 批量加载与流式处理

      • 一次性加载所有边可能会消耗大量内存。可以尝试分批从数据库读取边,并逐批添加到图中进行计算。
      int batchSize = 1000; // 自定义一个合适的批次大小
      List<Link> linksBatch;
      
      try (Stream<Point> pointStream = pointsRepository.streamAll()) {
          linksBatch = pointStream.limit(batchSize)
                                  .map(point -> new Link(point.getSrc(), point.getDst(), point.getWeight()))
                                  .collect(Collectors.toList());
      
          while (!linksBatch.isEmpty()) {
              g.addLinks(linksBatch);
              CommunityInfo communityInfo = louvainCalculator.findCommunitiesSingleLevel();
              // 处理communityInfo(例如存储结果或检查是否满足停止条件)
      
              // 获取下一批数据
              linksBatch = pointStream.limit(batchSize)
                                      .map(point -> new Link(point.getSrc(), point.getDst(), point.getWeight()))
                                      .collect(Collectors.toList());
          }
      }
      

      注意,上述代码假设您有一个支持流式处理的数据库接口。根据实际情况调整数据库查询和数据加载方式。

    3. 分布式计算或增量计算: 如果单机内存不足以处理全部数据,考虑使用分布式计算框架(如Apache Spark)来并行执行Louvain算法。或者对算法进行改造,使其支持增量计算,在每次添加新边后只更新受影响的社区。

    4. 数据预处理

      • 确保数据正确无误,没有异常值或重复项。
      • 对于非常大的图,考虑是否有可能提前过滤掉对最终社区划分影响不大的边。
    5. 算法实现优化: 检查使用的Louvain算法实现是否有针对大规模图的优化措施,比如使用更节省空间的数据结构、局部最优解的缓存策略等。

    6. 调试与日志记录: 在代码中加入详细的日志输出,查看在哪个阶段出现问题,是内存溢出还是算法本身的bug。如果问题依然存在,请检查LouvanCalculator库的具体实现,看是否有对大规模图处理的特殊要求或限制。

    请根据实际项目情况针对性地选择和实施以上建议。对于给出的部分代码,你已经基本实现了从数据库加载边的功能,但需要按需进行适当的分批处理。另外,需要注意的是,上述示例中的Louvain计算是在每一批次添加完边之后立即执行,而实际上,Louvain算法在一个层级完成之前通常不会切换到下一个层级,所以在真实场景下,可能需要在处理完整个数据集后统一调用findCommunitiesMultiLevel方法来进行多层级计算。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月5日

悬赏问题

  • ¥15 远程访问linux主机超时
  • ¥15 odoo17存货管理优势于中国国内该行业传统ERP或MES的详细解读和举例
  • ¥15 CPU卡指令整合指令数据都在图片上
  • ¥15 odoo17处理受托加工产品
  • ¥15 如何用MATLAB编码图三的积分
  • ¥15 圆孔衍射光强随孔径变化
  • ¥15 MacBook pro m3max上用vscode运行c语言没有反应
  • ¥15 ESP-PROG配置错误,ALL ONES
  • ¥15 结构功能耦合指标计算
  • ¥50 AI大模型精调(百度千帆、飞浆)