IGraph使用实例——图属性创建1

 1 概述

在图论中,图由顶点(vertices)和边(edges)组成,可以是无向的或有向的。图的属性是用来提供关于图、顶点或边的额外信息的数据。以下是从图论角度对图的属性的描述:

图的属性(Graph Attributes)

图的属性是与整个图相关的信息,而不是与图中的个别顶点或边相关。这些属性可以用来描述图的整体特征,例如:

  • 图的标识符(ID):一个唯一的标识符,用于区分不同的图。
  • 图的名称(Name):图的一个描述性名称,例如“社交网络图”或“交通网络图”。
  • 图是否规则(Regularity):布尔值,表示图中的所有顶点是否具有相同数量的边。
  • 其他可能的属性包括图的类型(例如,是否是有向图或无向图)、图的权重信息等。

顶点的属性(Vertex Attributes)

顶点属性是与图中的每个顶点相关的信息。这些属性可以用来描述顶点的特征,例如:

  • 顶点的值(Value):与顶点相关的数值,可能表示顶点的重要性、权重或其他数值度量。
  • 顶点的颜色(Color):在某些应用中,顶点可能被赋予颜色,用于可视化或其他目的。
  • 顶点的标签(Label):一个字符串或数字,用于标识或分类顶点。
  • 其他可能的属性包括顶点的度数(与顶点相连的边的数量)、顶点的类型(例如,在社交网络中,顶点可能代表不同类型的用户)等。

边的属性(Edge Attributes)

边属性是与图中的每条边相关的信息。这些属性可以用来描述边的特征,例如:

  • 边的权重(Weight):表示边的强度或成本,常用于表示距离、成本或流量。
  • 边的颜色(Color):与边相关的颜色,可能用于可视化或表示边的类型。
  • 边的标签(Label):用于标识或分类边的字符串或数字。
  • 边的方向(Direction):对于有向图,边的方向表示从一个顶点指向另一个顶点的关系。
  • 其他可能的属性包括边的类型(例如,在交通网络中,边可能代表不同类型的道路)等。

在实际应用中,图的属性可以根据具体的领域和需求进行定制。属性的引入使得图能够更丰富地表达信息,便于进行更复杂的分析和处理。

2 运行环境

操作系统:win10 64位

编程语言:C/C++

编译平台:vs2019  x64 debug | release

igraph版本: 0.10.12

3 示例代码

这段代码的主要作用是演示如何使用igraph库来创建一个图(graph),设置图的属性(包括图的属性、顶点的属性和边的属性),然后打印出这些属性。

下面print_attributes方法实现了图数据打印功能。函数首先初始化一些向量和字符串向量来存储属性名称和类型,然后通过igraph_cattribute_list函数获取图的属性列表。之后,它遍历图的属性、顶点和边,打印出它们的属性名称和值。

// 定义函数print_attributes,接受一个指向igraph_t结构的指针作为参数
void print_attributes(const igraph_t *g) {
    // 声明变量用于存储图、顶点和边的属性类型和名称
    igraph_vector_int_t gtypes, vtypes, etypes;
    igraph_strvector_t gnames, vnames, enames;
    igraph_integer_t i, j;

    // 初始化图、顶点和边的属性类型向量
    igraph_vector_int_init(&gtypes, 0);
    igraph_vector_int_init(&vtypes, 0);
    igraph_vector_int_init(&etypes, 0);
    // 初始化图、顶点和边的属性名称字符串向量
    igraph_strvector_init(&gnames, 0);
    igraph_strvector_init(&vnames, 0);
    igraph_strvector_init(&enames, 0);

    // 获取图的属性列表
    igraph_cattribute_list(g,
                           &gnames, &gtypes,
                           &vnames, &vtypes,
                           &enames, &etypes);

    // 打印图属性
    for (i = 0; i < igraph_strvector_size(&gnames); i++) {
        printf("%s=", igraph_strvector_get(&gnames, i)); // 打印属性名称
        // 根据属性类型打印数值或字符串
        if (VECTOR(gtypes)[i] == IGRAPH_ATTRIBUTE_NUMERIC) {
            igraph_real_printf(GAN(g, igraph_strvector_get(&gnames, i))); // 打印数值属性
            putchar(' ');
        } else {
            printf("\"%s\" ", GAS(g, igraph_strvector_get(&gnames, i))); // 打印字符串属性
        }
    }
    printf("\n"); // 换行

    // 打印顶点属性
    for (i = 0; i < igraph_vcount(g); i++) {
        printf("Vertex %" IGRAPH_PRId ": ", i); // 打印顶点编号
        for (j = 0; j < igraph_strvector_size(&vnames); j++) {
            printf("%s=", igraph_strvector_get(&vnames, j)); // 打印属性名称
            // 根据属性类型打印数值或字符串
            if (VECTOR(vtypes)[j] == IGRAPH_ATTRIBUTE_NUMERIC) {
                igraph_real_printf(VAN(g, igraph_strvector_get(&vnames, j), i)); // 打印数值属性
                putchar(' ');
            } else {
                printf("\"%s\" ", VAS(g, igraph_strvector_get(&vnames, j), i)); // 打印字符串属性
            }
        }
        printf("\n"); // 换行
    }

    // 打印边属性
    for (i = 0; i < igraph_ecount(g); i++) {
        printf("Edge %" IGRAPH_PRId " (%" IGRAPH_PRId "-%" IGRAPH_PRId "): ", i, IGRAPH_FROM(g, i), IGRAPH_TO(g, i)); // 打印边编号和端点
        for (j = 0; j < igraph_strvector_size(&enames); j++) {
            printf("%s=", igraph_strvector_get(&enames, j)); // 打印属性名称
            // 根据属性类型打印数值或字符串
            if (VECTOR(etypes)[j] == IGRAPH_ATTRIBUTE_NUMERIC) {
                igraph_real_printf(EAN(g, igraph_strvector_get(&enames, j), i)); // 打印数值属性
                putchar(' ');
            } else {
                printf("\"%s\" ", EAS(g, igraph_strvector_get(&enames, j), i)); // 打印字符串属性
            }
        }
        printf("\n"); // 换行
    }

    // 销毁之前初始化的向量和字符串向量
    igraph_strvector_destroy(&enames);
    igraph_strvector_destroy(&vnames);
    igraph_strvector_destroy(&gnames);
    igraph_vector_int_destroy(&etypes);
    igraph_vector_int_destroy(&vtypes);
    igraph_vector_int_destroy(&gtypes);
}

下面的程序首先创建了一个有向图,然后设置了图的属性,包括数值类型、字符串类型和布尔类型。接着,它为一条边设置了颜色属性,并使用向量为所有顶点设置了属性"y"的值。之后,它为顶点0单独设置了属性"y"的值,并删除了图的布尔属性"is_regular"。最后,程序打印了图的最终属性。

#include <igraph.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    igraph_t graph;         // 声明一个igraph_t类型的图变量
    igraph_vector_t y;      // 声明一个igraph_vector_t类型的向量变量

    /* 启用属性处理 */
    igraph_set_attribute_table(&igraph_cattribute_table);

    /* 创建一个有向图,包含3个顶点和3条边 */
    igraph_small(&graph, 3, IGRAPH_DIRECTED, 0,1, 1,2, -1);

    /* 设置图属性 */
    /* 设置数值类型的图属性 */
    SETGAN(&graph, "id", 10); 
    /* 设置字符串类型的图属性 */
    SETGAS(&graph, "name", "toy");
    /* 设置布尔类型的图属性 */
    SETGAB(&graph, "is_regular", false);

    /* 设置边的字符串属性 */
    SETEAS(&graph, "color", 1, "RED");

    /* 设置顶点属性,使用向量 */
    igraph_vector_init(&y, igraph_vcount(&graph)); // 初始化向量,大小为顶点数
    igraph_vector_fill(&y, 1.23);                  // 用1.23填充向量
    SETVANV(&graph, "y", &y);                     // 为所有顶点设置属性"y"的值
    igraph_vector_destroy(&y);                     // 销毁向量,释放内存

    /* 设置单个顶点的数值属性 */
    SETVAN(&graph, "y", 0, -1); // 为顶点0设置属性"y"的值为-1

    /* 删除图属性 */
    DELGA(&graph, "is_regular"); // 删除属性"is_regular"

    /* 打印最终结果 */
    print_attributes(&graph); // 调用之前定义的函数打印图的属性

    /* 删除所有剩余的属性 */
    DELALL(&graph); // 删除图的所有属性

    /* 销毁图 */
    igraph_destroy(&graph); // 释放图占用的内存

    return 0; // 程序正常退出
}

4 运行结果

下面是对这些输出结果的解释:

  1. id=10 name="toy": 这部分显示了图的属性。id 是一个数值属性,值为 10;name 是一个字符串属性,值为 "toy"。

  2. Vertex 0: y=-1: 这表示顶点 0 的属性 y 的值为 -1。这是通过 SETVAN 函数单独为顶点 0 设置的。

  3. Vertex 1: y=1.23: 这表示顶点 1 的属性 y 的值为 1.23。这是通过 SETVANV 函数使用向量 y 为所有顶点设置的属性值。

  4. Vertex 2: y=1.23: 这与顶点 1 相同,属性 y 的值也为 1.23。

  5. Edge 0 (0-1): color="": 这表示边 0(从顶点 0 到顶点 1)的属性 color 没有被设置,因此显示为空字符串。

  6. Edge 1 (1-2): color="RED": 这表示边 1(从顶点 1 到顶点 2)的属性 color 被设置为 "RED"。

请注意,程序中删除了图的布尔属性 is_regular,但是在输出中没有显示这部分,因为它已经被删除了。此外,边的 color 属性只设置了边 1,所以边 0 的 color 属性为空。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/675089.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++:特殊类设计和四种类型转换

一、特殊类设计 1.1 不能被拷贝的类 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c;只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 C98&#xff1a; 1、将拷贝构造函数与赋值运算符重载只…

个人百度百科怎么创建

编辑百度词条是一个相对简单的流程&#xff0c;但需要注意的是&#xff0c;并不是所有的词条都可以编辑&#xff0c;部分锁定的词条是无法编辑的&#xff0c;但可以通过官方平台申请解封。以下百科优化网yajje分享是详细的步骤&#xff1a; 注册百度账号 首先&#xff0c;用户…

kernelbase.dll故障怎么处理的几种常见方法,有效的解决kernelbase.dll故障

kernelbase.dll是 Windows 操作系统的一个系统文件&#xff0c;它是 Windows NT 基本 API 客户端库的一部分。如果你遇到了kernelbase.dll出现故障的情况&#xff0c;这可能会导致软件崩溃或无法正常运行。下面是一些处理kernelbase.dll故障的常见方法。 重新启动计算机&#x…

企业百度百科词条怎么修改

企业百度百科词条的修改是提升企业网络形象的重要手段。以下是百科优化网yajj总结详细的修改步骤&#xff1a; 准备工作 注册并登录百度账号&#xff1a;这是进行词条编辑的前提]。熟悉百度百科编辑规则&#xff1a;了解内容要求、格式规范、参考资料等&#xff0c;有助于更好…

深入解析 Web 开发中的强缓存与协商缓存机制

在 Web 开发中,缓存机制是提高页面加载速度和用户体验的重要技术。缓存分为两种主要类型:强缓存和协商缓存。本文将详细介绍这两种缓存机制的原理、实现方式及其区别,并演示如何在 <meta> 元素中和 Nginx 服务器中进行缓存控制。 强缓存 强缓存(Strong Caching)是指…

气泡式水位计施工技术要求

1、气泡式水位计压力气管出气口应安装并固定在最低水位处&#xff0c;其压力气管也应固定&#xff0c;有条件的可用金属管或塑料管保护。气泡式水位计安装示意图见附图。 2、安装要求 1&#xff09;检查气泡式水位计气管外观有无破损及变形&#xff1b; 2&#xff09;旋开带有…

【c++进阶(二)】STL之string类的模拟实现

&#x1f493;博主CSDN主页:Am心若依旧&#x1f493; ⏩专栏分类c从入门到精通⏪ &#x1f69a;代码仓库:青酒余成&#x1f69a; &#x1f339;关注我&#x1faf5;带你学习更多c   &#x1f51d;&#x1f51d; 1.前言 本章重点 本章主要介绍一些关键接口的模拟实现&#xff…

Simulink从0搭建模型09-P10 各类常用子系统介绍

Simulink从0搭建模型09-P10 各类常用子系统介绍 今日学习内容1. 使能子系统 Enabled Subsystem2. 触发子系统 Triggered Subsystem3. 函数调用子系统 Function-Call Subsystem3.1. 使用Function-Call Generator 产生一个f()信号3.2. 使用Stateflow产生f()一个信号3.2.1. Chart模…

CentOS 7~9 救援模式恢复root密码实战指南

在管理Linux服务器时&#xff0c;忘记root密码是一件棘手的事情&#xff0c;但幸运的是&#xff0c;CentOS提供了救援模式来帮助我们重置root密码。本文将详细介绍如何通过GRUB引导菜单进入紧急模式&#xff08;或称为救援模式&#xff09;&#xff0c;进而恢复root用户的密码。…

政安晨【零基础玩转各类开源AI项目】:解析开源项目:Champ 利用三维参数指导制作可控且一致的人体图像动画

目录 论文题目 Champ: 利用三维参数指导制作可控且一致的人体图像动画 安装 创建 conda 环境&#xff1a; 使用 pip 安装软件包 推理 1. 下载预训练模型 2. 准备准备引导动作数据 运行推理 训练模型 准备数据集 运行训练脚本 数据集 政安晨的个人主页&#xff1a;…

Stable diffusion文生图大模型——隐扩散模型原理解析

1、前言 本篇文章&#xff0c;我们将讲这些年非常流行的文生图大模型——Stable Diffusion。该模型也不难&#xff0c;甚至说很简单。创新点也相对较少&#xff0c;如果你学会了我以前的文章讲过的模型&#xff0c;学习这个也自然水到渠成&#xff01; 参考论文&#xff1a;H…

JVM-JAVA-双亲委派机制

双亲委派机制 双亲委派机制Tomcat打破双亲委派机制 双亲委派机制 双亲委派机制&#xff0c;加载某个类时会先委托父加载器寻找目标类&#xff0c;找不到再委托上层父加载器加载&#xff0c;如果所有父加载器在自己的加载类路径下都找不到目标类&#xff0c;则在自己的类加载路径…

Docker 基础使用 (1) 使用流程概览

文章目录 Docker 软件安装Docker 镜像仓库Docker 仓库指令Docker 镜像指令Docker 容器指令Docker 使用实例 —— 搭建 nginx 服务nginx 概念nginx 使用用 docker 启动 nginx Docker 基础使用&#xff08;0&#xff09;基础认识 Docker 基础使用 (1) 使用流程概览 Docker 基础使…

PHPStudy(xp 小皮)V8.1.1 通过cmd进入MySQL命令行模式

PHPStudy是一个PHP开发环境集成包&#xff0c;可用在本地电脑或者服务器上&#xff0c;该程序包集成最新的PHP/MySql/Apache/Nginx/Redis/FTP/Composer&#xff0c;一次性安装&#xff0c;无须配置即可使用。MySQL MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL A…

【C++入门到精通】C++ thread线程库 [ C++入门 ]

阅读导航 引言一、thread类的简单介绍二、thread类的用法1. 创建线程2. 使用 Lambda 表达式3. 传递参数给线程4. 线程的 join 和 detach5. 检查线程是否可 join6. 线程的 ID7. 线程的移动语义8. 线程的析构&#x1f6a8; 注意事项 三、线程函数参数温馨提示 引言 C thread线程…

代码随想录第二十三天 | 530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数,236.二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 看完想法&#xff1a;需要熟悉一下双指针的操作&#xff0c;好久没复习了&#xff0c;优先掌握递归 遇到在二叉搜索树上求什么最值&#xff0c;求差值之类的&#xff0c;都要思考一下二叉搜索树可是有序的&#xff0c;要利用好这一特点&#xff0…

el-date-picker选择开始日期的近半年

<el-date-pickerv-model"form[val.key]":type"val.datePickerType || daterange":clearable"val.clearable && true"range-separator"~"start-placeholder"开始日期"end-placeholder"结束日期"style&q…

ETF期权开户流程复杂吗?

ETF期权开户流程复杂吗&#xff1f;对于许多初次接触ETF期权的投资者来说&#xff0c;这个问题可能会让他们感到困惑。实际上&#xff0c;ETF期权开户的流程虽然涉及一些步骤&#xff0c;但只要遵循正确的指引&#xff0c;理解每一步的要求&#xff0c;整个过程并不会显得过于复…

【图像处理与机器视觉】频率域滤波

知识铺垫 复数 CRjI 可以看作复平面上的点&#xff0c;则该复数的坐标为&#xff08;R&#xff0c;I&#xff09; 欧拉公式 e j θ c o s θ j s i n θ e^{j\theta} cos \theta j sin \theta ejθcosθjsinθ 极坐标系中复数可以表示为&#xff1a; C ∣ C ∣ ( c o s…

安徽京准NTP时钟系统:GPS北斗卫星授时下的生活重塑

安徽京准NTP时钟系统&#xff1a;GPS北斗卫星授时下的生活重塑 安徽京准NTP时钟系统&#xff1a;GPS北斗卫星授时下的生活重塑 时间的流逝自古以来时钟都是人类生活与活动的基础。然而&#xff0c;随着科技的进步&#xff0c;我们对时间管理和测量的方法已经发生了翻天覆地的变…