0%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void Graph::oriented_triangle_counting(ui n, ui m, ui *peel_sequence, ept *pstart, ept *pend, ui *edges, ui *tri_cnt, ui *adj) {
ui *rid = adj;//存储等待处理的顶点
for(ui i = 0;i < n;i ++) rid[peel_sequence[i]] = i;
for(ui i = 0;i < n;i ++) {
ept &end = pend[i] = pstart[i];
for(ept j = pstart[i];j < pstart[i+1];j ++) if(rid[edges[j]] > rid[i]) edges[end ++] = edges[j];
}

#ifndef NDEBUG
long long sum = 0;
for(int i = 0;i < n;i ++) sum += pend[i] - pstart[i];
// printf("%lld %lld\n", sum, m);
assert(sum*2 == m);
#endif

memset(adj, 0, sizeof(ui)*n);
long long cnt = 0;
memset(tri_cnt, 0, sizeof(ui)*m);
for(ui u = 0;u < n;u ++) {
for(ept j = pstart[u];j < pend[u];j ++) adj[edges[j]] = j+1;

for(ept j = pstart[u];j < pend[u];j ++) {
ui v = edges[j];
for(ept k = pstart[v];k < pend[v];k ++) if(adj[edges[k]]) {
++ tri_cnt[j];
++ tri_cnt[k];
++ tri_cnt[adj[edges[k]]-1];
++ cnt;
}
}

for(ept j = pstart[u];j < pend[u];j ++) adj[edges[j]] = 0;
}
#ifndef NDEBUG
//printf("*** Total number of triangles: %s\n", Utility::integer_to_string(cnt).c_str());
#endif
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void Graph::reorganize_oriented_graph(ui n, ui *tri_cnt, ui *edge_list, ept *pstart, ept *pend, ept *pend2, ui *edges, ui *edgelist_pointer, ui *buf) {
for(ui i = 0;i < n;i ++) pend2[i] = pend[i];//copied
ept pos = 0;
for(ui i = 0;i < n;i ++) {
for(ept j = pstart[i];j < pend[i];j ++) {
tri_cnt[pos>>1] = edgelist_pointer[j]; edge_list[pos++] = i; edge_list[pos++] = edges[j];

ept &k = pend2[edges[j]];
edgelist_pointer[k] = edgelist_pointer[j] = (pos>>1)-1;
edges[k ++] = i;
}
}

#ifndef NDEBUG
for(ui i = 0;i < n;i ++) assert(pend2[i] == pstart[i+1]);
#endif
//commonly using asserts when debugging

for(ui i = 0;i < n;i ++) {
pend2[i] = pend[i];
pend[i] = pstart[i];
}
for(ui i = 0;i < n;i ++) {
for(ept j = pend2[i];j < pstart[i+1];j ++) {
ept &k = pend[edges[j]];
edgelist_pointer[k] = edgelist_pointer[j];
edges[k ++] = i;
}
}

ept *ids = pend2;
for(ui i = 0;i < n;i ++) {
if(pend[i] == pstart[i]||pend[i] == pstart[i+1]) continue;
ept j = pstart[i], k = pend[i], pos = 0;
while(j < pend[i]&&k < pstart[i+1]) {
if(edges[j] < edges[k]) {
ids[pos] = edges[j];
buf[pos ++] = edgelist_pointer[j ++];
}
else {
ids[pos] = edges[k];
buf[pos ++] = edgelist_pointer[k ++];
}
}
while(j < pend[i]) {
ids[pos] = edges[j];
buf[pos ++] = edgelist_pointer[j ++];
}
while(k < pstart[i+1]) {
ids[pos] = edges[k];
buf[pos ++] = edgelist_pointer[k ++];
}
for(ept j = 0;j < pos;j ++) {
edges[pstart[i] + j] = ids[j];
edgelist_pointer[pstart[i] + j] = buf[j];
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
void Graph::search() {
Timer t;
kplex.resize(2*K-2); //screen out trivial cases which are unconnected kplexes(Xiao)
int max_degree=0;
for(ui i = 0;i < n;i ++) {
if(pstart[i+1]-pstart[i] > max_degree) max_degree = pstart[i+1]-pstart[i];
}

ui LB = heuristic_kplex_max_weight(10);
//first finding,need to be changed(new heuristic way)
//The best solution found so far (Lower Bound)

ui oldn = n;
ui *seq = new ui[n];
ui *core = new ui[n];
ui *degree = new ui[n];
char *vis = new char[n];

ListLinearHeap *heap = new ListLinearHeap(n, n-1);


ui UB = degen(n, seq, core, pstart, edges, degree, vis, heap, true);
//Still need a New upper bound for a k-plex ,now is too trivial

printf("*** Upper Bound: %lu,Lower Bound:%lu", UB , LB);
delete heap;
delete[] vis;
delete[] degree;

//main loop to find the max kplex
if(kplex.size() < UB) {
ui old_size = kplex.size();
ui *out_mapping = new ui[n];
ui *rid = new ui[n];//携带着满足条件,即shrink以后剩余的节点的vec

shrink_graph(n, m, seq, core, out_mapping, NULL, rid, pstart, edges, true);
// delete[] core; core = NULL;
//core已经高阶替代了degree在induced subgraph中的作用

ui *degree = new ui[n];
for(ui i = 0;i < n;i ++) degree[i] = pstart[i+1] - pstart[i];
//此时pstart已经被更改了,所以重新计算度数

ListLinearHeap *linear_heap = new ListLinearHeap(n, n-1);
linear_heap->init(n, n-1, seq, degree);//重新维护顶点堆

assert(pend == nullptr);
pend = new ept[n];

ui *edgelist_pointer = new ui[m];
oriented_triangle_counting(n, m, seq, pstart, pend, edges, edgelist_pointer, rid); // edgelist_pointer currently stores triangle_counts

// delete[] seq; seq = NULL;

pend_buf = new ept[n];
ui *edge_list = new ui[m];
ui *tri_cnt = new ui[m/2];
reorganize_oriented_graph(n, tri_cnt, edge_list, pstart, pend, pend_buf, edges, edgelist_pointer, rid);

for(ui i = 0;i < n;i ++) pend[i] = pstart[i+1];

ui *active_edgelist = new ui[m>>1];
ui active_edgelist_n = m>>1;
for(ui i = 0;i < (m>>1);i ++) active_edgelist[i] = i;

ui *Qe = new ui[m>>1];
char *deleted = new char[m>>1];
memset(deleted, 0, sizeof(char)*(m>>1));
char *exists = new char[n];
memset(exists, 0, sizeof(char)*n);

ui *Qv = new ui[n];
ui Qv_n = 0;
MSearcher *kplex_solver = new MSearcher();

if(kplex.size() > 2*K-2 ) {
m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, true, kplex.size()+1-2*K, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
printf("*** After core-truss co-pruning: n = %s, m = %s, density = %.4lf\n", Utility::integer_to_string(n-Qv_n).c_str(), Utility::integer_to_string(m/2).c_str(), double(m)/(n-Qv_n)/(n-Qv_n-1));
}

Timer tt;

int max_n = n - Qv_n;
s_degree = new ui[max_n];
s_pstart = new ept[max_n+1];
s_pend = new ept[max_n];
s_edges = new ui[m];
s_peel_sequence = new ui[max_n];
s_core = new ui[max_n];
s_vis = new char[max_n];
s_heap = new ListLinearHeap(max_n,max_n-1);
s_edgelist_pointer = new ui[m];
s_tri_cnt = new ui[m/2];
s_edge_list = new ui[m];
s_active_edgelist = new ui[m/2];
s_deleted = new char[m/2];

vector<pair<int,int> > vp; vp.reserve(m/2);
ui *t_degree = new ui[n];

ui max_n_prune = 0, max_n_search = 0, prune_cnt = 0, search_cnt = 0;
double min_density_prune = 1, min_density_search = 1, total_density_prune = 0, total_density_search = 0;
ui last_m=0;

for(int i = 0;i < n&&m&&kplex.size() < UB;i ++) {
ui u, key;
linear_heap->pop_min(u, key);
// if(key != 0) printf("u = %u, key = %u\n", u, key);
if(key < kplex.size()+1-K) {
if(degree[u] != 0) { // degree[u] == 0 means u is deleted. it could be the case that degree[u] == 0, but key[u] > 0, as key[u] is not fully updated in linear_heap
Qv[0] = u; Qv_n = 1;
if(kplex.size()+1>2*K) m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, false, kplex.size()+1-2*K, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
else m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, false, 0, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
}
continue;
}
if(m == 0) break;
assert(degree[u] == key);

ui *ids = Qv;
ui ids_n = 0;
bool mflag=false;

if( K<3 || max_n==oldn ) kplex_solver->enableInput=false;
if( K>=10 ) kplex_solver->enableInput=true;

// if(last_m<0.8*m) {
if(true){
ui pre_size;
do{
pre_size=kplex.size();
extract_subgraph_and_prune(u, ids, ids_n, rid, vp, Qe, t_degree, exists, pend, deleted, edgelist_pointer);
if(ids_n) {
double density = (double(vp.size()*2))/ids_n/(ids_n-1);
total_density_prune += density; ++ prune_cnt;
if(density < min_density_prune) min_density_prune = density;
if(ids_n > max_n_prune) max_n_prune = ids_n;
}
if(ids_n > kplex.size()&&vp.size()*2 < m) subgraph_prune(ids, ids_n, vp, rid, Qv, Qe, exists);
// Qv_n=0;
// if(kplex.size() != pre_size && kplex.size()> 2*K-2) m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, true, kplex.size()+1-2*K, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
}
while(kplex.size()!=pre_size);
}
else {
extract_graph(n, m, degree, ids, ids_n, rid, vp, exists, pstart, pend, edges, deleted, edgelist_pointer);
double density = (double(vp.size()*2))/ids_n/(ids_n-1);
total_density_prune += density; ++ prune_cnt;
if(density < min_density_prune) min_density_prune = density;
if(ids_n > max_n_prune) max_n_prune = ids_n;
mflag=true;
}
last_m=vp.size()*2;
ui pre_size = kplex.size();
if(ids_n > kplex.size()) {
double density = (double(vp.size()*2))/ids_n/(ids_n-1);
total_density_search += density; ++ search_cnt;
if(density < min_density_search) min_density_search = density;
if(ids_n > max_n_search) max_n_search = ids_n;
kplex_solver->load(ids_n, vp);
if(mflag){
kplex_solver->runWHOLE(K, kplex);
break;
}
else kplex_solver->run(K, kplex);
}
Qv[0] = u; Qv_n = 1;
if(kplex.size() != pre_size && kplex.size()> 2*K-2) {
for(ui j = 0;j < kplex.size();j ++) kplex[j] = ids[kplex[j]];
m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, true, kplex.size()+1-2*K, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
}
else if(kplex.size()>2*K-2) m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, false, kplex.size()+1-2*K, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
else m -= 2*peeling(n, linear_heap, Qv, Qv_n, kplex.size()+1-K, Qe, false, 0, tri_cnt, active_edgelist, active_edgelist_n, edge_list, edgelist_pointer, deleted, degree, pstart, pend, edges, exists);
}

if(prune_cnt == 0) ++ prune_cnt;
if(search_cnt == 0) ++ search_cnt;
printf("prune_cnt: %u, max_n: %u, min_density: %.4lf, avg_density: %.4lf\n", prune_cnt, max_n_prune, min_density_prune, total_density_prune/prune_cnt);
printf("search_cnt: %u, max_n: %u, min_density: %.4lf, avg_density: %.4lf\n", search_cnt, max_n_search, min_density_search, total_density_search/search_cnt);
printf("*** Search time: %s \n", Utility::integer_to_string(tt.elapsed()).c_str());

if(kplex.size() > old_size) {
for(ui i = 0;i < kplex.size();i ++) {
kplex[i] = out_mapping[kplex[i]];
}
}

delete kplex_solver;
delete linear_heap;
delete[] t_degree;
delete[] exists;
delete[] out_mapping;
delete[] rid;
delete[] degree;
delete[] edgelist_pointer;
delete[] tri_cnt;
delete[] active_edgelist;
delete[] Qe;
delete[] Qv;
delete[] deleted;
}
delete[] core;
delete[] seq;



printf("\tMaximum kPlex Size: %lu, Total Time: %s (microseconds)\n", kplex.size(), Utility::integer_to_string(t.elapsed()).c_str());
// printf("*** Node count: %lld\n",nodeCnt);
// printf("*** Gamma avg: %.4lf\n",(edgeCnt+0.1)/(nodeCnt+0.1));
// printf("*** Sub avg: %.4lf\n",(subSum+0.1)/(subCnt+0.1));
// printf("*** Sub max: %lld\n",subMax);
// printf("*** Max degree: %d\n",max_degree);
}

Some useful grammars in Python

Input

1
2
3
4
5
6
a,b=input().split()
print(a,b)
## way 2
s=input().split()
a,b=list(map(int,s))
print(a,b)

List

image-20240224095825541

image-20240224104855878

List slice:

image-20240224105303773

Copy:

image-20240224105731333

Tuple

Elements in tuples cannot be altered,while it could be switched into list to do so.

Inner functions are mostly the same between the two data structures.

image-20240224111238019

String

image-20240224113213331

image-20240224113501087

Judge functions(Inner):

image-20240224113532965

Transformer:

image-20240224113647852

查找类方法:

image-20240228172607722

From string to list:

image-20240224130951659

image-20240224131441588

当t转换为list类型之后,可以利用str.join(t)将序列的每个元素用str连接起来

Format格式化

image-20240228172156115

同时也可以先用实际意义的变量名作为占位符,随后format实际上是一个后赋值的操作

image-20240228172400739

字典

Some of my former works

I’ve done some projects during my last three undergraduate semesters.

The projects are mainly about:

Database: SIRBabbage/Database-SQL-base⁤ (github.com)

C && Data structure && Algorithms: c2022-challenge/实验 at main · SIRBabbage/c2022-challenge (github.com)

Block-chain: SIRBabbage/Lottery-block-chain (github.com)

The languages used above included C,C plus plus,Java,SQL,HTML,JS and Solidity.

If you are interested,the codes are committed to be downloaded and it would be kind to give your stars.

THIS IS MY FIRST BLOG

Welcome to Runner21st’s blog.

My blog is mainly about Maths and Computer Science,now I’m majored in CS at UESTC as an undergraduate.

And this site is just a temporary place to share my researches or study notes,in order to record my studying path. If some of you get interested in what I’ve learned or shared,please contact me via Github: SIRBabbage.github.io or leave a comment here.

Now I’m doing researches in Exact Algorithms and Artificial Intelligence.

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment