[论文笔记]Graph Cube: 基于数据仓库和OLAP多维网络

Graph Cube: On Warehousing and OLAP Multidimensional Networks

研究背景

  数据仓库是一种为企业进行决策制定的工具。区别于数据库,数据仓库的主要功能并非保存数据,而是为数据分析师,战略制定者获取有价值信息提供服务的。

在这里插入图片描述
  如上图所示,数据仓库的基本模型是数据立方体(Cube),数据立方体由多个方体(Cuboid)组成。每个方体可以表示为一张表,属性为方体的维度,表中的每行数据称为元组(Cell)。

  以往人们在使用数据仓库时,总是根据维度需求在数据立方体中计算出单个所需的方体,以便进行数据分析或数据挖掘。然而当我们需要对多个方体进行联合分析时,传统的数据仓库模型便无法做到了。除此之外,传统的方体只关注元组的属性和度量,而忽略了不同元组之间的关系。当我们想分析个体之间的联系时,也是很不方便的。

  作者基于上述问题,提出了新的数据仓库模型——图数据立方体(Graph Cube),并在此基础上提出了解决多个方体联合分析的方法——跨方体(Crossboid)。

Graph Cube 模型

  首先介绍一下多维网络(Multidimensional Network)。多维网络的示意图如下所示。

在这里插入图片描述
  可以看到,多维网络就是图与表的结合。图中顶点表示单个个体,个体拥有多个属性(ID, Gender, Location, Profession, Income),其中ID为个体的主键,标记在顶点的内部。图中边表示个体之间的关系。

  图数据立方体技术实质上就是将传统的数据立方体与多维网络进行结合。在图数据立方体中,上图的多维网络就是它的Base Cuboid。图数据立方体的示意图如下所示。

在这里插入图片描述
  在上图中,除了最下方的Base Cuboid,其余的方体称为聚合网络(Aggregation Network)。下图为聚合网络与传统方体的聚合表的对比。

在这里插入图片描述

(Gender)方体

在这里插入图片描述
(Gender, Location)方体

  可以看到图数据立方体的方体——聚合网络保存了个体之间的关系。图中顶点内的数字表示在Base Cuboid中对应的个体数;图中边上的数字表示在Base Cuboid中对应个体之间的边数。

Graph Cube的联机分析处理

  联机分析处理(OLAP),是人们对数据仓库最主要的操作方式,在模型中就是根据要求计算出相应的方体,将结果方体以表格的形式展示给数据分析师。
  在图数据立方体中的OLAP分为两种形式:基于单个方体的查询(Cuboid Query),基于多个方体的查询(Crossboid Query)。

基于单个方体的查询

  该查询形式与一般的数据仓库查询形式基本相同,系统根据用户给定的属性计算出图数据立方体中对应的方体,将聚合网络返回给用户。下图为图数据立方体中的各个方体。
在这里插入图片描述
  方体的聚合网络构建算法如下所示。

在这里插入图片描述
  算法通过哈希函数构造属性与顶点的关系。对于查询属性相同的个体,将被映射到相同的顶点。
  首先生成聚合网络的顶点。3-8行循环遍历Bsae Cuboid的多维网络中的所有顶点,即所有个体。若映射的顶点不存在,则创建新的顶点,并为顶点赋予权值1;若映射的顶点已存在,则为顶点的权值加1。
  接着生成聚合网络的边。9-15行循环遍历Bsae Cuboid的多维网络中的所有边,即个体间的关系。根据边的首尾顶点,找到对应聚合网络中的两个顶点。若两顶点间不存在边,则创建边,并为边赋予权值1;若已存在边,则为边的权值加1。
最后将生成的聚合网络返回给用户。

  如果聚合网络A已算出,用户希望获得另一个聚合网络B,并且B是A的祖先(即B的属性集是A的真子集),此时可以直接通过聚合网络A计算出聚合网络B。将上述算法的输入网络由多维网络改成聚合网络A即可。

基于多个方体的查询

考虑如下问题。

ID=3的用户与不同地区的用户之间的关系网络是怎样的?

  可以看到,这种查询要求仅计算一个方体是不够的。

  在基于多个方体的查询形式下,用户需要的聚合网络横跨多个方体。作者在这里以2个方体为例进行分析,将2个方体的结合称为跨方体(Crossboid)。跨方体由2个方体通过连接操作构建而成。跨方体与方体的关系如下图所示。图中包含了三个方体和两个跨方体。

在这里插入图片描述
  两个跨方体的聚合网络分别如下图所示。

在这里插入图片描述

按性别分类的用户与按地区分类的用户之间的关系网络
在这里插入图片描述
ID=3的用户与不同地区的用户之间的关系网络

  我们知道,在维度为n的图数据立方体中有2n个方体。每个方体可以跟任意方体(包括本身,若是本身则连接后不变)进行连接组成一个跨方体,所有共有2n×2n=22n个跨方体。

  计算跨方体聚合网络的算法如下所示。

在这里插入图片描述
  算法的大致思路与上一个算法相同,同样是构造哈希函数映射属性与顶点的关系,依次构造聚合网络的顶点和边。区别在于构造边的时候,该算法将多维网络中的无向边作为有向边考虑。

  与上一个算法类似,跨方体网络的计算也可以进行简化。若用户希望获得方体S与方体T连接的跨方体ST的聚合网络,系统可以直接通过S与T的最近共同子孙方体NCD(S,T)的网络计算。方法同样是将输入的多维网络改为NCD(S,T)的聚合网络。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以前和大家分享过SIGMOD2009的论文,朋友们都很感兴趣,现手里有SIGMOD211的全部论文,再次和大家分享~ 一个包放不下,一共分成了3个包,包含百余篇论文,朋友们可以挑选自己感兴趣的部分下载,我尽量把文章目录写得明白一些。 这是第二部分。 Nearest Keyword Search in XML Documents (Page 589) Yufei Tao (Chinese University of Hong Kong) Stavros Papadopoulos (Chinese University of Hong Kong) Cheng Sheng (Chinese University of Hong Kong) Kostas Stefanidis (Chinese University of Hong Kong) Efficient and Generic Evaluation of Ranked Queries (Page 601) Wen Jin (Independent Consultant) Jignesh M. Patel (University of Wisconsin - Madison) (Return to Top) Session 13: Stream and Complex Event Processing Changing Flights in Mid-Air: A Model for Safely Modifying Continuous Queries (Page 613) Kyumars Sheykh Esmaili (ETH Zurich) Tahmineh Sanamrad (ETH Zurich) Peter M. Fischer (ETH Zurich) Nesime Tatbul (ETH Zurich) How Soccer Players Would Do Stream Joins (Page 625) Jens Teubner (ETH Zurich) Rene Mueller (IBM Almaden Research Group) BE-Tree: An Index Structure to Efficiently Match Boolean Expressions Over High-Dimensional Discrete Space (Page 637) Mohammad Sadoghi (University of Toronto) Hans-Arno Jacobsen (University of Toronto) TI: An Efficient Indexing Mechanism for Real-Time Search on Tweets (Page 649) Chun Chen (Zhejiang University) Feng Li (National University of Singapore) Beng Chin Ooi (National University of Singapore) Sai Wu (National University of Singapore) (Return to Top) Session 14: Query Processing More Efficient Datalog Queries: Subsumptive Tabling Beats Magic Sets (Page 661) K. Tuncay Tekle (LogicBlox, Inc.) Yanhong A. Liu (State University of New York at Stony Brook) Entangled Queries: Enabling Declarative Data-Driven Coordination (Page 673) Nitin Gupta (Cornell University) Lucja Kot (Cornell University) Sudip Roy (Cornell University) Gabriel Bender (Cornell University) Johannes Gehrke (Cornell University) Christoph Koch (École Polytechnique Fédérale de Lausanne) Data Generation Using Declarative Constraints (Page 685) Arvind Arasu (Microsoft Research) Raghav
使用C++实现有向图的邻接矩阵,以及可达矩阵的计算算法。 请完成Project05.cpp中DirectedGraph类的成员函数,具体要求如下: DirectedGraph类: 用来表示一个有向图。 成员变量: m_AdjMat:邻接矩阵 m_ReachabilityMat:可达矩阵 成员函数: DirectedGraph():默认构造函数,构造一个空图。 ~DirectedGraph():析构函数 DirectedGraph(string filepath):解析文件filepath,构造一个DirectedGraph对象。 filepath文件格式与项目四相同,但本项目的图为有向图。 DirectedGraph(const Graph & graph):复制构造函数 operator=(const Graph & graph):赋值运算符 ClearGraph():清空图的邻接矩阵和可达矩阵。 OutputGraph():输出图的邻接矩阵 operator*(const DirectedGraph & graph): 乘法运算符,用于实现可达矩阵运算中的矩阵逻辑乘 DirectedGraph Pow(int power):邻接矩阵的整数次幂。 用法如下: DirectedGraph a; a = a.Pow(5); 即a的5次幂,相当于a = a * a * a * a * a; 注意要考虑0次幂的情况。 该函数适合以递归实现。 DirectedGraph MatOr(DirectedGraph graph):矩阵逐元素的逻辑或运算。 例如: 1 0 0 1 与 0 1 1 0 运算后的结果为 1 1 1 1 void CalcReachabilityMat():计算可达矩阵,要求该函数基于*运算符和Pow函数实现 void OutputReachabilityMat():输出可达矩阵 IsConnected(int src, int dst):基于可达矩阵判断从节点src与dst之间是否存在通路,如存在返回真,否则返回假
05-30
以下是Project05.cpp的完整代码实现,包括DirectedGraph类的定义和成员函数的实现: ```c++ #include <iostream> #include <fstream> #include <vector> #include <cstring> using namespace std; const int MAXN = 100; // 最大节点数 class DirectedGraph { public: DirectedGraph(); DirectedGraph(string filepath); DirectedGraph(const DirectedGraph & graph); ~DirectedGraph(); DirectedGraph & operator=(const DirectedGraph & graph); void ClearGraph(); void OutputGraph(); DirectedGraph operator*(const DirectedGraph & graph); DirectedGraph Pow(int power); DirectedGraph MatOr(DirectedGraph graph); void CalcReachabilityMat(); void OutputReachabilityMat(); bool IsConnected(int src, int dst); private: int n; // 节点数 int m_AdjMat[MAXN][MAXN]; // 邻接矩阵 int m_ReachabilityMat[MAXN][MAXN]; // 可达矩阵 void ReadGraphFromFile(string filepath); // 从文件中读取图 }; DirectedGraph::DirectedGraph() { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); } DirectedGraph::DirectedGraph(string filepath) { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); ReadGraphFromFile(filepath); } DirectedGraph::DirectedGraph(const DirectedGraph & graph) { n = graph.n; memcpy(m_AdjMat, graph.m_AdjMat, sizeof(m_AdjMat)); memcpy(m_ReachabilityMat, graph.m_ReachabilityMat, sizeof(m_ReachabilityMat)); } DirectedGraph::~DirectedGraph() {} DirectedGraph & DirectedGraph::operator=(const DirectedGraph & graph) { if (this == &graph) { return *this; } n = graph.n; memcpy(m_AdjMat, graph.m_AdjMat, sizeof(m_AdjMat)); memcpy(m_ReachabilityMat, graph.m_ReachabilityMat, sizeof(m_ReachabilityMat)); return *this; } void DirectedGraph::ClearGraph() { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); } void DirectedGraph::OutputGraph() { cout << "邻接矩阵:" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m_AdjMat[i][j] << " "; } cout << endl; } } DirectedGraph DirectedGraph::operator*(const DirectedGraph & graph) { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { ret.m_ReachabilityMat[i][j] = ret.m_ReachabilityMat[i][j] || (m_ReachabilityMat[i][k] && graph.m_ReachabilityMat[k][j]); } } } return ret; } DirectedGraph DirectedGraph::Pow(int power) { DirectedGraph ret; ret.n = n; if (power == 0) { for (int i = 0; i < n; i++) { ret.m_ReachabilityMat[i][i] = 1; } } else if (power == 1) { memcpy(ret.m_ReachabilityMat, m_ReachabilityMat, sizeof(m_ReachabilityMat)); } else if (power % 2 == 0) { DirectedGraph half = Pow(power / 2); ret = half * half; } else { DirectedGraph half = Pow(power / 2); ret = half * half * (*this); } return ret; } DirectedGraph DirectedGraph::MatOr(DirectedGraph graph) { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { ret.m_ReachabilityMat[i][j] = m_ReachabilityMat[i][j] || graph.m_ReachabilityMat[i][j]; } } return ret; } void DirectedGraph::CalcReachabilityMat() { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { ret.m_ReachabilityMat[i][j] = m_AdjMat[i][j]; } } for (int i = 1; i < n; i++) { ret = ret + Pow(i); } memcpy(m_ReachabilityMat, ret.m_ReachabilityMat, sizeof(m_ReachabilityMat)); } void DirectedGraph::OutputReachabilityMat() { cout << "可达矩阵:" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m_ReachabilityMat[i][j] << " "; } cout << endl; } } bool DirectedGraph::IsConnected(int src, int dst) { return m_ReachabilityMat[src][dst]; } void DirectedGraph::ReadGraphFromFile(string filepath) { ifstream fin(filepath); if (!fin) { cout << "文件不存在!" << endl; return; } fin >> n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { fin >> m_AdjMat[i][j]; } } fin.close(); } int main() { DirectedGraph graph("input.txt"); graph.OutputGraph(); graph.CalcReachabilityMat(); graph.OutputReachabilityMat(); cout << "0和3是否连通:" << graph.IsConnected(0, 3) << endl; cout << "1和2是否连通:" << graph.IsConnected(1, 2) << endl; return 0; } ``` 在该代码中,我们定义了DirectedGraph类,实现了题目中要求的各种成员函数。我们首先在main函数中创建一个DirectedGraph对象,并读取输入文件中的有向图。然后,我们调用OutputGraph函数输出邻接矩阵。接着,我们调用CalcReachabilityMat函数计算可达矩阵,并使用OutputReachabilityMat函数输出可达矩阵。最后,我们使用IsConnected函数判断一些节点之间是否连通。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值