1 #include<bits/stdc++.h>
2 #include<windows.h>
3
4 using namespace std;
5
6 map<string,int>mp;
7 map<string,bool>mp2;
8 map<pair<int,int>,bool>con;//判断两节点之间是否有边
9 vector<int>G[5500];//存储图
10 vector<int>pre[5500];
11 string s[5500];
12 int dis[5500],DC[5500],id[5500],CC[5500],EC[5500];
13 double ECC[5500],Lid[5500],ct[5500],ks[5500],BC[5500];
14 bool vis[5500];
15 int ans=0;
16 //求最短路,输入x,返回x到其他点的最短路之和
17 int Dijkstra(int x){
18 memset(vis,false,sizeof(vis));
19 memset(dis,0x3f3f3f3f,sizeof(dis));
20 dis[x]=0;
21 int num=1;
22 queue<int>q;
23 vis[x]=true;
24 q.push(x);
25 while(!q.empty()){
26 int p=q.front();
27 q.pop();
28 int d=G[p].size();
29 for(int i=0;i<d;i++){
30 if(!vis[G[p][i]]){//没有访问过G[p][i],则更新dis[G[p][i]]=dis[p]+1
31 dis[G[p][i]]=dis[p]+1;
32 vis[G[p][i]]=true;
33 num++;
34 q.push(G[p][i]);
35 }
36 }
37 if(num==ans) break;
38 }
39 while(!q.empty()){
40 q.pop();
41 }
42 int sum=0;
43 for(int i=1;i<=ans;i++){
44 sum+=dis[i];
45 }
46 return sum;
47 }
48 void Degree(){
49 sort(id+1,id+1+ans,[](const int &a, const int &b){if(DC[a]==DC[b]){return s[a]<s[b];} return DC[a]>DC[b];});
50 int result=0;
51 cout<<"Degree: ";
52 for(int i=1;i<=600;i++){
53 if(mp2[s[id[i]]]) result++;
54 if(i%100==0) cout<<result<<" ";
55 }
56 cout<<endl;
57 }
58 //将每个点的最短路之和存到CC[i]中,然后排序,输出。
59 void Closeness(){
60 memset(CC,0,sizeof(CC));
61 for(int i=1;i<=ans;i++){
62 CC[i]=Dijkstra(i);
63 }
64 sort(id+1,id+1+ans,[](const int &a, const int &b){if(CC[a]==CC[b]){return s[a]<s[b];} return CC[a]<CC[b];});
65 int result=0;
66 cout<<"Closeness: ";
67 for(int i=1;i<=600;i++){
68 if(mp2[s[id[i]]]) result++;
69 if(i%100==0) cout<<result<<" ";
70 }
71 cout<<endl;
72 }
73 void Betweenness(){
74 stack<int>st;
75 memset(BC,0,sizeof(BC));
76 for(int x=1;x<=ans;x++){
77 memset(vis,false,sizeof(vis));
78 memset(dis,0x3f3f3f3f,sizeof(dis));
79 memset(ks,0,sizeof(ks));
80 memset(ct,0,sizeof(ct));
81 dis[x]=0;//初始化,将x到自己的距离设为0
82 ct[x]=1;
83 int num=1;
84 queue<int>q;
85 vis[x]=true;
86 q.push(x);
87 while(!q.empty()){
88 int p=q.front();
89 q.pop();
90 st.push(p);
91 int d=G[p].size();
92 for(int i=0;i<d;i++){
93 if(!vis[G[p][i]]){
94 dis[G[p][i]]=dis[p]+1;
95 vis[G[p][i]]=true;
96 q.push(G[p][i]);
97 }
98 if(dis[G[p][i]]==dis[p]+1){
99 ct[G[p][i]]+=ct[p];
100 pre[G[p][i]].push_back(p);
101 }
102 }
103 }
104 while(!st.empty()){
105 int p=st.top();
106 st.pop();
107 int d=pre[p].size();
108 for(int i=0;i<d;i++){
109 ks[pre[p][i]]+=ct[pre[p][i]]/ct[p]*(1.0+ks[p]);
110 }
111 if(p!=x){
112 BC[p]+=ks[p];
113 }
114 }
115 for(int j=1;j<=ans;j++){
116 pre[j].clear();
117 }
118 }
119 sort(id+1,id+1+ans,[](const int &a, const int &b){if(fabs(BC[a]-BC[b])<1e-2){return s[a]<s[b];} return BC[a]>BC[b];});
120 int result=0;
121 cout<<"Betweenness: ";
122 for(int i=1;i<=600;i++){
123 if(mp2[s[id[i]]]) result++;
124 if(i%100==0) cout<<result<<" ";
125 }
126 cout<<endl;
127 }
128 void Clustering_coefficient(){
129 memset(ECC,0,sizeof(ECC));
130 int x,y;
131 for(int i=1;i<=ans;i++){
132 int d=G[i].size();
133 x=d*(d-1)/2;
134 y=0;
135 for(int j=0;j<d;j++){
136 for(int k=j+1;k<d;k++){
137 if(con.find(make_pair(G[i][j],G[i][k]))!=con.end()){//判断它的邻家之间是否有边,若有,则三角形个数y++;
138 y++;
139 }
140 }
141 }
142 if(d<=1) ECC[i]=0;
143 else ECC[i]=1.0*y/x;
144 }
145 sort(id+1,id+1+ans,[](const int &a, const int &b){if(fabs(ECC[a]-ECC[b])<1e-8){return s[a]<s[b];} return ECC[a]>ECC[b];});
146 int result=0;
147 cout<<"Clustering_coefficient: ";
148 for(int i=1;i<=600;i++){
149 if(mp2[s[id[i]]]) result++;
150 if(i%100==0) cout<<result<<" ";
151 }
152 cout<<endl;
153 }
154 void LID(){
155 memset(Lid,0,sizeof(Lid));
156 memset(vis,false,sizeof(vis));
157 int x,y;
158 for(int i=1;i<=ans;i++){
159 memset(vis,0,sizeof(vis));
160 int d=G[i].size();
161 x=0;
162 y=0;
163 for(int j=0;j<d;j++){
164 for(int k=j+1;k<d;k++){
165 if(con.find(make_pair(G[i][j],G[i][k]))!=con.end()){//判断它的邻家之间是否有边,若有,则三角形个数y++;
166 vis[G[i][j]]=1;
167 vis[G[i][k]]=1;
168 y++;
169 }
170 }
171 }
172 for(int j=1;j<=ans;j++){
173 if(vis[j]&&j!=i){
174 x++;
175 }
176 }
177 if(y==0) Lid[i]=0;
178 else Lid[i]=1.00*y/x;
179 }
180 sort(id+1,id+1+ans,[](const int &a, const int &b){if(fabs(Lid[a]-Lid[b])<1e-10){return s[a]<s[b];} return Lid[a]>Lid[b];});
181 int result=0;
182 cout<<"LID: ";
183 for(int i=1;i<=600;i++){
184 if(mp2[s[id[i]]]) result++;
185 if(i%100==0) cout<<result<<" ";
186 }
187 cout<<endl;
188 }
189 void Eigenvector(){
190 memset(EC,0,sizeof(EC));
191 memset(vis,0,sizeof(vis));
192 for(int i=1;i<=ans;i++){
193 int d=G[i].size();
194 for(int j=0;j<d;j++){
195 EC[i]+=DC[G[i][j]];
196 }
197 }
198 sort(id+1,id+1+ans,[](const int a, const int b){if(EC[a]==EC[b]) return s[a]<s[b]; return EC[a]>EC[b];});
199 int result=0;
200 cout<<"Eigenvector: ";
201 for(int i=1;i<=600;i++){
202 if(mp2[s[id[i]]]) result++;
203 if(i%100==0) cout<<result<<" ";
204 }
205 cout<<endl;
206 }
207 int main(){
208 //c++读取xlsx文件比较复杂,我将数据导出为.txt文件,方便读取。
209 ifstream fin("Yeast PPI.txt");
210 string s1,s2,s3;
211 mp.clear();
212 mp2.clear();
213 con.clear();
214 int x,y;
215 int start_time=GetTickCount();
216 while(fin>>s1>>s2){
217 if(mp[s1]==0){
218 ans++;
219 mp[s1]=ans;
220 s[ans]=s1;
221 DC[ans]=0;
222 id[ans]=ans;
223 }
224 if(mp[s2]==0){
225 ans++;
226 mp[s2]=ans;
227 s[ans]=s2;
228 DC[ans]=0;
229 id[ans]=ans;
230 }
231 x=mp[s1];
232 y=mp[s2];
233 DC[x]++;
234 DC[y]++;
235 G[x].push_back(y);
236 G[y].push_back(x);
237 con[make_pair(x,y)]=true;
238 con[make_pair(y,x)]=true;
239 }
240 fin.close();
241 ifstream fin2("name.txt");
242 while(fin2>>s1){
243 mp2[s1]=true;
244 }
245 Degree();
246 Closeness();
247 Betweenness();
248 Clustering_coefficient();
249 LID();
250 Eigenvector();
251 int end_time=GetTickCount();
252 cout<<"used time: "<<1.0*(end_time-start_time)/1000<<"s"<<endl;//输出程序运行时间
253 return 0;
254 }