Metis是由Karypis Lab开发的一个具有强大功能的图划分软件包,可用于划分不规则图(graph)、网格(mesh)以及计算稀疏矩阵(Sparse Matrices)的Fill-Reducing Orderings。它提供了一组可以独立运行的命令行程序,同时也提供API方便集成到C/C++或Fortran程序中。

由于图划分问题np-hard性质带来的求解难度,Metis更新并不频繁(从1997年开始发布,最近一次更新是2013年3月,已经很是良心),其核心算法也不再是当前最优秀的,但并不妨碍它继续作为一个经典且稳定的第三方库在开源领域(如,国产开源CFD软件OneFLOW)中发挥重要作用。

在我当前的研究课题中一个子问题涉及到图划分,使用Metis的C/C++接口成功求解了该问题。本文主要记录一下Metis软件包的简单使用过程,更多内容请参考Karypis Lab官网。

0. 准备条件

  • VS2017 / VS2019

  • CMake 3.18

1. 下载&安装

参考Win10 VS安装METIS和使用METIS软件包进行图划分,这两篇博客文章已经介绍得很详细,按照步骤进行即可。有几点这里再强调一下:

  • 官方文件BUILD-Windows.txt中建议使用CMake 2.8,但CMake 2.8不支持vs2017,下载安装最新版本的CMake即可,建议使用Scoop安装。

  • 配置CMake编译选项时注意选择正确的编译器版本和机器位数,如本次实验中直接选择了vs2017 + release + x64。

  • 使用MSC编译器需要注释掉gk_arch.h文件中的一行代码,不要忘了。

  • 如果CMake配置的目标路径在C盘,可能需要使用管理员权限启动vs2017才能成功生成解决方案。

2. 在新项目中添加依赖

vs中引用第三方静态库永远都是关注两个文件(.h和.lib)、三个配置项

  • 附加包含目录:.h文件所在的目录
  • 附加库目录:.lib文件所在的目录
  • 附加依赖项:.lib文件
    具体可以参考一文梳理vs2017中lib的使用。

建议: 在新项目中建立Lib/目录,将用到的第三方库文件都复制到该目录,使用相对路径配置附加包含/库目录(如上述图中所示),避免使用绝对路径,这样可以方便项目在不同机器之间迁移和节约协同开发成本。如下图所示:

3. Metis’ API介绍

安装完Metis后可以在manual/目录下找到说明文档manual.pdf,其中介绍了命令行程序(Programs)和API的使用方法。这里主要对用于图划分的两个接口METIS_PartGraphRecursiveMETIS_PartGraphKway作简单说明。

Metis提供了 RecursiveKway 两种划分方式,分别基于 multilevel recursive bisectionmultilevel k-way partitioning 实现。我们这里不关心其核心算法思路,仅关注其具体使用场景,下面这段话摘自官网的Discussions:

“This function(METIS_PartGraphKway) should be used to partition a graph into a large number of partitions(greater than 8). If a small number of partitions is desired, the METIS_PartGraphRecursive should be used instead, as it produces somewhat better partitions.”

即求解划分子图数目较多时(官方建议划分8个以上子图)使用METIS_PartGraphKway,小规模划分使用METIS_PartGraphRecursive能获得质量更好的解,在后面的实验中也验证了这点。

此外,重点关注以下几个参数(更多参数信息请参考文档manual.pdf):

  • nvtxs: 节点数目。

  • ncon: 节点权重维度,默认1。

  • xadj,adjncy: Metis使用压缩图(CSR)表示图的邻接关系,详情参考文档Metis' API/Graph data structure部分。

  • vwgt: 节点权重列表,设为NULL表示节点无权重或所有节点权重相同,相当于按照子图中节点的数目平衡划分。

  • adjwgt: 边的权重列表,默认优化目标为切断边的权重之和最小,设为NULL则表示按照切边数最小划分。

  • nparts: 要划分的子图数目。

  • objval: 目标函数值。

  • part: 保存划分结果。

4. Demo

注意: Demo使用了manual.pdf中的一个简单带权算例,怎样在VS中用C++调用METIS提供的API和使用METIS软件包进行图划分两篇博客文章中也使用了同样的算例。但通过我个人的学习与理解,认为他们在调用API时出现了明显的失误并已经在各自文章的评论区出指出了问题,如果我的理解有误,欢迎批评指正。

  • 算例图示及文件格式
  • 代码
#include <metis.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>using namespace std;vector<idx_t> func(vector<idx_t> &xadj, vector<idx_t> &adjncy, vector<idx_t> &adjwgt, decltype(METIS_PartGraphKway) *METIS_PartGraphFunc) {idx_t nVertices = xadj.size() - 1; // 节点数idx_t nEdges = adjncy.size() / 2;  // 边数idx_t nWeights = 1;                // 节点权重维数idx_t nParts = 2;                  // 子图个数≥2idx_t objval;                      // 目标函数值vector<idx_t> part(nVertices, 0);  // 划分结果int ret = METIS_PartGraphFunc(&nVertices, &nWeights, xadj.data(), adjncy.data(),NULL, NULL, adjwgt.data(), &nParts, NULL,NULL, NULL, &objval, part.data());if (ret != rstatus_et::METIS_OK) { cout << "METIS_ERROR" << endl; }cout << "METIS_OK" << endl;cout << "objval: " << objval << endl;for (unsigned part_i = 0; part_i < part.size(); part_i++) {cout << part_i + 1 << " " << part[part_i] << endl;}return part;
}int main() {ifstream ingraph("graph.txt");int vexnum, edgenum;string line;getline(ingraph, line);istringstream tmp(line);tmp >> vexnum >> edgenum;vector<idx_t> xadj(0);vector<idx_t> adjncy(0); // 压缩图表示vector<idx_t> adjwgt(0); // 边权重idx_t a, w;for (int i = 0; i < vexnum; i++) {xadj.push_back(adjncy.size());getline(ingraph, line);istringstream tmp(line);while (tmp >> a >> w) {adjncy.push_back(a - 1); // 节点id从0开始adjwgt.push_back(w);}}xadj.push_back(adjncy.size());ingraph.close();vector<idx_t> part = func(xadj, adjncy, adjwgt, METIS_PartGraphRecursive);//vector<idx_t> part = func(xadj, adjncy, adjwgt, METIS_PartGraphKway);ofstream outpartition("partition.txt");for (int i = 0; i < part.size(); i++) { outpartition << i + 1 << " " << part[i] << endl; }outpartition.close();return 0;
}
  • 运行结果

    • METIS_PartGraphRecursive划分结果:
    • METIS_PartGraphKway划分结果:

可以看出,对于上述仅划分两个子图的情况,METIS_PartGraphRecursive要优于METIS_PartGraphKway;但在我的研究课题中,算例规模和子图数目稍大一些,经过测试使用METIS_PartGraphKway求解的质量更好。

建议: 在实际使用过程中,可能会由于算例规模的变化交替使用两种划分办法。由于这两个API参数与返回值形式完全一致,建议使用传递函数指针的方式区分调用,避免写出大量重复代码。

Github

项目实例均在vs2017/vs2019上测试,并上传至GitHub,将LearnMetis设为启动项目即可复现实验结果。

Reference

Win10 VS安装METIS

怎样在VS中用C++调用METIS提供的API

使用METIS软件包进行图划分

win10+vs2019从源代码编译网格剖分软件Metis5.1.0

图划分软件Metis的使用相关推荐

  1. windows 安装metis_图划分软件Metis的使用(win10+vs2017)

    Metis是由Karypis Lab开发的一个具有强大功能的图划分软件包,可用于划分不规则图(graph).网格(mesh)以及计算稀疏矩阵(Sparse Matrices)的Fill-Reducin ...

  2. metis 多线程图划分论文笔记

    多线程图划分 目的 利用多线程来完成图划分,从而达到提高效率的作用. 定义 balance: balance 是用来衡量 k 划分有多么的平等的. balance 定义为 k * max_i{η(V_ ...

  3. metis 论文串行图划分笔记

    Metis 图划分 目标:将图划分为几个包含差不多相等的顶点个数的部分,并且这些部分之间的边数目尽可能地小.(若是有权重的 ,则是各个划分内部的权重和差不多相等,各划分之间的权重尽可能小) k路划分: ...

  4. 使用METIS软件包进行图划分

    目录 0 前言 1 安装METIS 2 安装CMake GUI 3 用CMake GUI编译METIS 4 修改gk_arch.h文件 5 用VS生成解决方案 6 在VS中进行图划分 参考文献 0 前 ...

  5. 图划分(Graph PartitionRe-ordering): METIS(5.x)ParMETIS(4.x)使用实践

    图划分(Graph Partition&Re-ordering): METIS(5.x)&ParMETIS(4.x)使用实践 学习METIS&ParMETIS用法:阅读手册和示 ...

  6. 动态分区分配的“首次适应算法_动态图划分复制算法:Leopard

    数据管理和系统实现课程上要分享的论文:<LEOPARD: Lightweight Edge-Oriented Partitioning and Replication for Dynamic G ...

  7. 分享几个常做甘特图的软件

    因为现在做的工作是项目运营,所以平时在部署活动的时候需要跟进活动的执行情况,那活动的执行进度就要活动相关的甘特图.如果没有一款合适的软件去做甘特图会特别麻烦,一方面要处理数据另一方面要保证图型的美观, ...

  8. 图扑软件用数据可视化形式告诉你,楼宇建设如何数字化转型

    在"新基建"驱动的数字经济热潮下,智慧园区建设发展成为实现园区管理绿色化.现代化.智慧化的核心抓手.通过利用云计算.物联网.大数据等新一代技术手段,充分聚合园区内各类资源,全面提升 ...

  9. 图扑软件 | 数字孪生钢厂人员安全定位

    钢铁冶炼从原料采购.焦化烧结.炼铁.炼钢.轧钢.到产出成品,其冗长的生产工序.复杂的作业场景,更应加以重视生产现场的人员作业安全,将安全防范监管贯穿日常作业全过程,打通安全生产责任"最后一公 ...

最新文章

  1. php读取西门子plc_基于Socket访问西门子PLC系列教程(二)
  2. [SOA征文]SOA如何起步?
  3. 信息化建设工程的有效成本及定价分析(1)
  4. begin end会产生事务吗_无线信号放大器会产生同频干扰吗?
  5. 用户运营的三种思维层级,你在哪一层?
  6. HDU 2512 一卡通大冒险
  7. java数据结构队列杨辉三角_数据结构之队列——输出杨辉三角形
  8. memcpy和strcpy函数
  9. 开始研究WEKA,一个开源java的数据挖掘工具
  10. C++笔记------static 和 const 在类中用法
  11. 软件工程第二次作业 软件评价
  12. html表单-在线留言,aspcms自定义表单 在线留言修改
  13. (黑马教程)-webpack学习笔记
  14. 预编译stdafx.h,无法找到文件问题,红色波浪线
  15. layui 时间控件 只显示时分或者分秒
  16. java流分类_什么是流分类-JAVA中什么是流?流经常按照哪几种方式分类,每种方式又将流各分? 爱问知识人...
  17. 山寨AR手游频出,VRAR正打造一庞大…
  18. 渗透测试、安服等面试资料
  19. 用dxdiag命令show计算机系统配置
  20. Mac OS关机/睡眠快捷键

热门文章

  1. 计算机三级数据库技术 第14章 数据仓库与数据挖掘
  2. 让swfobject.js 支持透明的flash
  3. python中文字符截取乱码
  4. 微信小程序图片处理方案,解决加载缓慢,影响用户体验
  5. IDEA 注释模板,这样配置才够逼格!
  6. 使用IDM下载百度网盘的文件(亲测有用)
  7. Transformer模型学习笔记
  8. python-基础语法
  9. pulsar分析以及各消息队列对比
  10. centos 硬盘挂载