使用matlab读取gml网络数据

  许多网络数据都保存为.gml格式的文件,可以使用Gephi软件进行读取,但是这样可能会有点麻烦,所以可以考虑使用matlab程序进行网络数据的格式转换,gml数据类似json格式,使用正则表达式进行数据的转换即可,可以使用如下代码。

function AdjGraphMat = gmlread(fileName)
% ReadMe:
% 功能:此函数用于读取gml格式的网络数据文件
% 参数列表:只有一个传入参数,参数为文件名
% 返回参数为邻接矩阵

%% 读取文本,打开文件并创建文件句柄fid
fid = fopen(fileName);
%% 将文本的Ascii码内容存为stringAsc
stringAsc = fread(fid)';
%% 关闭文件句柄
fclose(fid);
%% 将Ascii码转化为字符串形式
string = char(stringAsc);
%% 正则表达式,解析json格式的gml图数据
%% 此文件数据是否为有向图
isDirect = ~isempty(regexp(string,'directed 1\n','once'));
%% ----------------------1.节点------------------------
%% 设置node节点的字段匹配模式
patternNode = 'node[^a-z].*?]';
[strStart,strStop] = regexp(string,patternNode);
%% 设定节点的结构体及其数据成员的属性
stringTmp = string(strStart(1):strStop(1));
if isempty(regexp(stringTmp,'label', 'once'))
    isLabel = 0;
    nodeList(1:length(strStart)) = struct('id',[]);
else
    isLabel = 1;
    nodeList(1:length(strStart)) = struct('id',[],'label',[]);
end
for i = 1 : length(strStart)
    stringTmp = string(strStart(i):strStop(i));
    [strStartTmp,strStopTmp] = regexp(stringTmp,'id [0-9]+\n');
    nodeList(i).id = str2double(stringTmp(strStartTmp+3:strStopTmp-1));
    if isLabel
        [strStartTmp,strStopTmp] = regexp(stringTmp,'label ".*"\n');
        nodeList(i).label = stringTmp(strStartTmp+7:strStopTmp-2);
    end
end
%% ----------------------2.------------------------
%% 设置edge边的字段匹配模式
patternEdge = 'edge[^a-z].*?]';
[strStart,strStop] = regexp(string,patternEdge);
%% 设定边的结构体及其数据成员的属性
edgeList = zeros(length(strStart),2);
for i = 1 : length(strStart)
    stringTmp = string(strStart(i):strStop(i));
    [strStartTmp,strStopTmp] = regexp(stringTmp,'source [0-9]+\n');
    edgeList(i,1) = str2double(stringTmp(strStartTmp+7:strStopTmp-1));
    [strStartTmp,strStopTmp] = regexp(stringTmp,'target [0-9]+\n');
    edgeList(i,2) = str2double(stringTmp(strStartTmp+7:strStopTmp-1));
end
%% 构建邻接矩阵
AdjGraphMat = zeros(length(nodeList));
for i = 1 : length(edgeList)
    AdjGraphMat(edgeList(i,1)+1-nodeList(1).id,edgeList(i,2)+1-nodeList(1).id) = 1;
    if isDirect == 0
        AdjGraphMat(edgeList(i,2)+1-nodeList(1).id,edgeList(i,1)+1-nodeList(1).id) = 1;
    end
end
%% 稀疏矩阵写表
xlswrite([fileName(1:end-4) '.xlsx'],edgeList)
%% 邻接矩阵写.mat
save([fileName(1:end-4) '.mat'],'AdjGraphMat','edgeList')
end
% ReadMe:
% 功能:此函数用于,使用另一个执行函数,对数据集总目录下的所有文件分目录,分别运行
% 其各自的数据,并将各自的运行结果保存到分目录,以便一步运行所有数据集

%% 设置需要执行的函数句柄
fun = @gmlread;
%% 设置数据集总目录位置
filesDir = [pwd '\数据集\社区发现数据集'];
%% 判断目录是否存在
if exist(filesDir,'dir') ~= 7
    disp('文件目录不存在,请检查核对目录');
    return;
end
%% 列出数据集总目录下的所有数据集分目录
filesInDir = dir(filesDir);
%% 将压缩包等非目录文件删去,只留下目录文件夹
isDir = zeros(length(filesInDir),1);
for i = 1 : length(filesInDir)
    isDir(i) = filesInDir(i).isdir;
end
filesInDir(isDir==0)=[];
%% 对每个数据集的分目录,执行函数运算
for i = 3 : length(filesInDir)
    fileName = [filesInDir(i).folder '\' filesInDir(i).name '\' filesInDir(i).name '.gml'];
    fun(fileName);
end

猜你喜欢

转载自blog.csdn.net/wanchaochaochao/article/details/89944281