spfa算法求网络的点介数[R/C++]
数据说明
包含两列基因id的ceRNA网络,无向图,无权重(或认为边权为1)。
经验证,所用数据的网络中所有节点均连通,如果网络存在不连通的可能,则算法应适当改进。
igraph包中可能包含相应函数,因自身电脑原因用C++写了一种解法
点介数
节点k的介数:
经过点k的最短路的数量/网络中最短路的数量
由于所用数据的网络中节点均连通,则网络中最短路的数量=节点数*(节点数-1)/2
“经过点k的最短路”默认不包含以k为起点、以k为终点的路径
拓展-边介数:
包含边e的最短路的数量/网络中最短路的数量
spfa
单源(起点)最短路算法,由于算法特性,可以在运算过程中记录从源点到任意终点的具体路径(经过的点)。
(心累不写了)
枚举n个节点,进行n次spfa。
实现
write.table(df,file="g.txt",quote=F,row.names = F,col.names = F)
write.table(name,file="gg.txt",quote=F,row.names = F,col.names = F)
# C++ calculate shortest paths
ans <- read.table("ans.txt")
bc <- ans/(1630*1629/2)
plot(seq(1,1630,by=1),bc$V1)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<map>
#define N 2000
#define M 5000
using namespace std;
int n=1630,m=4789,inf=5000,S;
string id[N];
map <string,int>mmap;
int minpath[1635][1635];
int totaledge=1327635; //point*(point-1)/2
struct edge{
int u,v,sum,nxt;
}e[M*2];
int cnt,head[N],lst[N];
void add_edge(int x,int y,int s){
e[++cnt].u=x;
e[cnt].v=y;
e[cnt].sum=s;
e[cnt].nxt=head[x];
head[x]=cnt;
}
int dis[N],que[M],front=1,tail=1;
bool inq[N];
void spfa(){
front=1,tail=1;
memset(inq,false,sizeof(inq));
que[front]=S;inq[S]=true;
for(int i=1;i<=n;i++) dis[i]=inf;
memset(lst,0,sizeof(lst));
dis[S]=0;
while(front<=tail){
int now=que[front];
inq[now]=false;
for(int i=head[now];i;i=e[i].nxt){
int v=e[i].v;
if(dis[v]>dis[now]+e[i].sum){
lst[v]=now;//record
dis[v]=dis[now]+e[i].sum;
if(!inq[v]){
inq[v]=true;
que[++tail]=v;
}
}
}
front++;
}
}
int ans[N];
int main(){
freopen("gg.txt","r",stdin);
for(int i=1;i<=n;i++){
cin>>id[i];
mmap[id[i]]=i;
}
fclose(stdin);
memset(minpath,2000,sizeof(minpath));
freopen("g.txt","r",stdin);
for(int i=1;i<=m;i++){
string a,b;
cin>>a>>b;
// minpath[mmap[a]][mmap[b]]=1;
add_edge(mmap[a],mmap[b],1);
add_edge(mmap[b],mmap[a],1);
}
fclose(stdin);
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++){
S=i;
spfa();
printf("start from %d",i);
for(int j=1;j<=n;j++){
minpath[i][j]=dis[j];
if(j==i)continue;
int ss=j,tt=lst[ss];
while(tt!=i){
ans[tt]++;
tt=lst[tt];
}
}
}
freopen("ans.txt","w",stdout);
for(int i=1;i<=n;i++){
printf("%d\n",ans[i]);
}
fclose(stdout);
freopen("minpath.txt","w",stdout);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d\t",minpath[i][j]);
}
printf("\n");
}
fclose(stdout);
return 0;
}