Compare commits

..

23 Commits

Author SHA1 Message Date
50390f7118 move init and free to functions 2024-11-19 11:46:06 +01:00
7b83d9eeb4 cleanup includes 2024-10-22 23:39:57 +02:00
8ffcc39c9c testing around with structs 2024-10-22 23:38:00 +02:00
cddbadfd4a switch from uint64_t to unsigned long 2024-10-22 23:26:09 +02:00
c41d130a45 formatting 2024-10-14 14:07:59 +02:00
2b2ffe9649 update .gitignore 2024-10-11 16:38:02 +02:00
e5ddece861 implement dfs 2024-10-11 00:09:26 +02:00
cb5561b35b done with basic implementation 2024-10-10 00:44:00 +02:00
21fb373f65 new but broken functionality 2024-10-09 15:35:17 +02:00
a94122eeb2 new functionality 2024-10-09 01:42:55 +02:00
02bd70cedd fuck around with csv files 2024-10-09 01:20:12 +02:00
16274d2a98 rename matrix_multiply_basic to gemm_basic 2024-10-08 23:29:02 +02:00
d8c3a75d50 switch to heap memory in benchmark() 2024-10-08 23:04:09 +02:00
55480a727e switch to puts where reasonable 2024-10-08 22:18:36 +02:00
49cab7b2cc finish calculate_distance_matrix() 2024-10-07 09:03:29 +02:00
6ab823c1fc fixed copy function
I mistook the variables inside the loop and it caused really weird behaviour
2024-10-07 09:03:01 +02:00
9929a4470c startet distance_matrix bullshit 2024-10-04 17:36:40 +02:00
9f17802c49 tiny changes 2024-10-04 16:46:40 +02:00
5cb04ff579 read csv now works 2024-10-04 13:05:02 +02:00
c85be15175 unimportant change 2024-10-04 01:04:47 +02:00
04a8712b0f read_csv doesn't work 2024-10-04 01:03:39 +02:00
808d971af6 modify .gitignore 2024-10-04 01:03:13 +02:00
6863d20530 add csv files 2024-10-04 01:02:38 +02:00
11 changed files with 1076 additions and 106 deletions

57
.gitignore vendored
View File

@ -1,54 +1,3 @@
# ---> C *.x64
# Prerequisites gmon.out
*.d prof_output
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

24
csv/24n.csv Normal file
View File

@ -0,0 +1,24 @@
0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;1;0;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;1;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;1;1;0;1;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;1;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;1;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;1;0;0;0;1;1;1;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;0;0;0;1;0;1;0;0;0;1;0;0;1;0;0;0;0;0;0;0
0;0;0;0;0;0;1;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0;0;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;1;1;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;0;0;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;1;0;0;0;1;1;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;1;0;0;0;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;1;0;1;0;0
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1;1
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;1
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;1;0
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 0 0 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
7 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
8 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
9 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
11 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0
12 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
13 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
14 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
15 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 0 0 0
16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0
17 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 0 0 0
18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0
19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0
20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0
21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0
22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0

50
csv/50n.csv Normal file
View File

@ -0,0 +1,50 @@
0;1;1;0;0;0;0;1;0;1;0;1;0;0;1;1;1;1;0;1;1;1;1;1;0;1;0;0;1;1;0;1;0;1;0;0;0;1;1;0;1;0;0;1;0;0;0;0;0;0
0;0;1;0;1;0;0;1;1;1;0;1;1;0;1;1;0;0;1;0;1;0;1;0;0;0;1;0;0;1;0;1;1;0;0;0;1;0;0;0;1;0;1;0;1;0;1;0;1;1
1;0;0;1;0;0;0;1;0;1;1;1;1;0;0;1;0;1;1;1;0;1;1;1;1;0;0;1;1;1;1;1;1;0;0;1;0;0;1;1;0;1;0;0;1;0;0;0;1;0
1;1;1;0;0;0;1;1;0;1;1;1;1;1;0;1;1;0;1;1;0;0;0;1;1;0;1;1;1;0;0;0;0;0;0;1;1;1;0;0;1;0;0;1;0;0;1;0;0;0
1;0;1;0;0;0;1;0;1;1;0;1;0;1;0;1;0;0;0;1;1;1;1;1;1;0;0;1;1;1;1;1;0;0;0;1;1;1;1;1;1;0;1;1;0;0;0;0;1;1
0;0;0;1;1;0;1;1;0;1;0;1;1;1;0;1;0;1;1;1;0;1;0;0;1;1;0;1;1;0;0;0;1;1;0;1;0;1;0;0;1;1;0;1;1;0;0;1;0;0
0;0;0;0;0;0;0;1;1;0;0;1;1;0;1;1;0;0;0;1;0;0;0;0;0;0;1;1;1;0;0;1;0;1;0;1;0;0;1;1;1;0;0;1;1;0;1;1;0;1
1;0;0;1;1;0;0;0;0;0;1;0;1;0;0;1;1;1;0;1;1;0;1;0;0;1;0;1;1;0;0;0;0;0;0;1;0;1;1;1;1;0;0;0;1;1;1;1;1;0
1;0;0;1;0;0;0;0;0;1;0;0;1;0;1;1;0;0;0;0;1;0;1;0;1;1;0;1;0;1;0;1;1;1;0;1;0;0;0;0;0;1;1;1;0;0;1;1;0;1
1;0;0;1;0;1;1;0;0;0;0;1;1;0;0;0;1;1;1;0;0;1;1;1;0;1;0;0;0;1;0;1;0;1;1;0;1;1;0;1;0;1;1;1;1;1;0;1;0;1
0;0;0;0;1;1;1;1;0;1;0;1;1;0;1;0;1;1;0;1;0;0;0;1;1;1;1;0;0;0;1;0;1;0;1;0;0;0;0;0;1;0;1;1;0;0;0;0;1;0
1;1;1;0;0;1;0;0;1;1;1;0;0;0;0;1;1;0;0;0;1;0;1;1;1;0;1;0;1;1;1;0;0;1;0;1;0;1;1;1;1;0;0;1;1;1;0;1;0;0
1;0;1;1;1;1;0;0;0;1;1;1;0;0;0;1;0;0;1;0;1;1;1;1;0;0;0;0;0;0;1;0;1;1;1;1;0;0;0;0;1;0;1;1;0;1;1;1;0;1
1;1;0;0;0;0;1;0;0;1;1;0;0;0;0;0;0;0;0;1;1;0;0;1;1;0;0;1;1;1;0;1;0;0;0;1;1;1;0;1;1;0;0;1;1;1;1;1;0;1
0;1;0;0;0;0;1;0;0;1;1;0;0;1;0;1;1;1;0;0;0;1;0;1;1;1;0;0;0;1;0;0;0;1;1;1;0;0;0;0;1;0;0;1;0;1;1;1;0;1
0;1;1;1;1;1;0;1;1;0;0;0;0;1;0;0;0;1;1;0;0;0;1;1;1;1;0;1;0;0;0;0;1;1;1;1;0;0;1;0;1;0;1;1;0;1;1;1;0;1
0;1;1;0;1;1;0;0;0;0;0;0;0;1;0;1;0;0;0;1;0;0;1;0;0;0;0;0;1;1;1;0;1;1;1;1;0;1;0;1;0;0;0;0;0;0;0;0;1;0
0;1;0;0;0;0;1;1;0;1;0;0;1;1;0;0;1;0;1;1;1;1;0;1;0;1;1;0;0;0;1;1;1;0;1;0;0;1;0;0;0;1;1;0;1;0;0;0;0;1
1;0;0;0;0;0;1;1;1;0;1;1;0;1;1;0;0;1;0;0;1;0;1;0;0;1;0;0;0;1;1;1;0;0;0;0;0;1;0;0;0;0;1;0;1;1;1;1;0;1
1;1;1;0;1;1;0;1;0;1;1;0;0;1;1;0;1;0;0;0;1;0;1;0;1;0;1;1;0;1;0;1;0;1;1;0;1;0;1;0;0;1;1;0;0;1;1;0;1;0
0;1;0;0;0;0;0;1;1;0;1;0;1;0;1;0;1;1;0;0;0;1;0;1;1;1;0;1;0;1;0;1;0;1;1;1;0;1;0;0;1;0;0;0;0;0;0;1;1;1
1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;1;0;1;1;1;1;0;0;1;1;0;0;1;1;0;1;1;1;1;1;0;0;0;1;0;0;0;1;1;1;0;0;0;0;1
1;0;1;1;0;0;0;1;1;1;0;1;0;1;0;1;0;0;1;0;0;0;0;1;0;0;1;0;1;1;0;0;1;1;1;1;1;1;0;1;1;1;0;0;1;0;0;0;0;0
0;0;0;1;1;1;0;1;1;1;1;1;1;0;0;0;0;1;1;0;0;0;0;0;0;0;0;1;0;0;0;1;1;1;1;1;0;0;0;1;1;0;1;1;1;0;0;1;0;1
0;0;0;1;0;1;0;1;0;1;1;1;0;0;1;0;0;0;1;0;1;0;0;0;0;0;0;1;1;0;0;0;1;1;0;1;1;1;1;0;1;1;0;0;1;1;1;1;0;0
1;1;1;1;1;1;0;0;0;1;1;0;1;1;1;0;1;1;1;0;1;0;0;1;1;0;0;0;0;0;0;1;1;1;0;1;1;0;1;1;0;1;1;1;0;1;0;1;0;0
1;1;1;1;0;1;1;1;1;1;1;0;0;1;0;0;0;0;1;0;0;0;0;0;0;1;0;1;1;0;0;0;1;1;1;1;0;1;0;0;0;1;0;1;0;1;1;0;0;0
0;0;0;1;0;1;0;0;0;0;1;1;0;0;0;0;1;1;0;0;1;1;0;1;1;1;1;0;1;1;1;0;0;0;0;1;1;1;1;1;0;0;0;0;0;1;1;0;1;0
1;1;1;0;0;0;1;1;1;1;0;1;1;1;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;1;1;1;1;1;1;1;0;1;0;0;1;0;1;1;0;0;1;1;1;1
0;0;1;0;1;1;0;1;0;0;0;1;0;0;0;0;1;1;1;1;0;0;0;0;0;0;0;1;1;0;0;1;0;0;1;1;1;1;0;0;0;1;0;0;1;1;0;1;1;0
1;1;0;1;0;1;0;0;1;0;1;0;0;0;1;0;1;1;0;1;1;0;0;1;0;1;0;1;1;0;0;1;1;1;1;0;1;0;0;1;0;0;1;0;1;0;1;1;1;1
1;0;1;0;0;0;1;0;1;1;1;0;1;1;1;0;1;1;0;1;0;0;1;0;0;1;1;1;1;0;1;0;1;0;1;1;1;1;0;1;1;0;0;0;0;1;0;1;0;0
0;0;1;1;1;1;0;0;0;0;1;0;0;0;1;1;0;0;1;1;0;0;0;1;1;0;0;1;0;0;1;1;0;0;1;0;1;0;0;0;1;0;1;0;1;1;1;0;0;1
1;1;1;1;1;1;1;1;0;0;1;1;0;1;0;1;1;0;0;0;0;1;1;1;0;0;1;0;1;0;1;0;0;0;1;0;0;0;1;1;0;1;1;1;1;0;1;1;1;1
0;1;0;0;0;0;0;0;0;1;1;0;0;0;1;0;1;0;1;0;0;0;0;0;1;0;0;0;1;0;0;1;1;0;0;1;0;0;0;0;1;0;1;1;0;0;1;1;0;1
1;0;0;0;1;0;1;1;1;0;1;0;0;1;0;1;1;0;0;1;0;0;1;0;0;1;1;0;0;0;1;1;0;0;1;0;1;0;1;1;1;1;1;1;0;0;0;1;0;1
0;0;0;1;0;0;1;0;1;1;1;1;0;1;0;1;0;1;1;1;0;0;0;0;1;1;1;1;1;0;1;0;1;1;0;1;0;0;0;0;0;0;1;0;0;1;1;0;1;0
1;0;0;0;0;0;0;1;0;0;1;1;1;1;1;0;0;0;0;0;1;1;0;0;1;1;1;0;1;0;0;0;1;0;0;1;1;0;0;0;1;1;0;1;0;1;1;0;1;0
1;0;1;0;1;1;1;0;1;0;0;0;1;1;1;0;0;1;0;0;0;0;1;0;0;0;1;0;1;0;1;1;1;0;1;0;1;1;0;0;0;1;0;0;0;1;0;1;1;1
0;1;1;1;1;0;0;1;0;0;1;0;1;1;1;1;1;0;1;1;1;1;0;1;0;1;0;0;1;0;1;0;0;0;0;0;1;0;1;0;1;0;1;0;1;1;0;1;1;0
1;1;1;1;1;1;0;1;0;0;1;0;1;0;0;1;0;1;0;0;0;0;1;1;0;0;0;0;1;0;0;0;1;1;1;0;1;1;1;1;0;0;0;1;1;1;0;0;0;1
1;1;0;0;0;0;1;0;0;0;1;1;1;1;0;0;1;0;0;1;1;1;0;1;0;0;1;0;1;1;1;0;1;1;0;1;1;0;1;0;0;0;0;1;0;0;1;0;0;0
0;0;1;0;1;0;0;0;0;0;0;0;1;1;0;0;0;0;0;1;1;1;1;0;1;1;0;1;1;1;0;1;1;0;0;1;1;0;1;1;0;0;0;0;0;1;0;1;1;1
1;1;0;1;0;1;0;1;0;1;1;0;0;0;0;0;1;1;1;1;0;1;1;1;0;1;1;0;1;0;1;1;1;0;0;0;0;0;1;0;0;0;1;0;0;0;0;1;0;0
1;0;0;0;1;1;0;1;0;0;1;1;0;0;1;0;0;0;1;1;1;0;0;0;0;1;1;0;1;1;1;1;1;1;1;0;0;1;1;1;1;0;1;1;0;0;1;0;1;0
0;1;0;0;1;1;0;0;1;0;0;1;1;1;0;0;1;1;1;1;1;0;0;1;0;1;0;1;0;0;1;0;0;1;1;0;1;0;1;0;0;0;0;1;1;0;0;1;1;0
0;0;1;0;0;1;1;0;0;0;0;1;0;0;1;1;0;1;0;1;0;0;0;0;0;1;0;1;1;0;0;1;0;0;0;0;0;0;0;0;0;1;0;1;1;0;0;1;1;1
0;0;1;1;0;0;1;1;1;1;1;1;1;1;0;1;1;0;0;0;1;1;1;1;0;1;0;1;0;1;1;0;0;0;1;0;0;1;1;0;1;0;1;0;0;0;1;0;1;0
0;0;0;1;0;0;0;1;0;0;1;1;0;1;0;1;0;0;1;0;1;1;1;0;0;0;0;0;1;0;1;1;0;0;1;1;0;0;0;1;0;1;1;1;0;1;1;0;0;1
1;0;0;0;0;1;0;1;0;0;0;0;0;0;1;1;1;1;1;1;1;0;0;0;1;1;1;0;1;1;1;0;1;0;1;0;1;0;1;1;1;1;0;1;0;1;0;0;0;0
1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 0 0 1 1 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0
2 0 0 1 0 1 0 0 1 1 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 0 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1
3 1 0 0 1 0 0 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0
4 1 1 1 0 0 0 1 1 0 1 1 1 1 1 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 1 1 1 0 0 1 0 0 1 0 0 1 0 0 0
5 1 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 0 0 0 1 1
6 0 0 0 1 1 0 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 1 1 0 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 0
7 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 1 0 1 0 1 0 0 1 1 1 0 0 1 1 0 1 1 0 1
8 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 1 1 1 0 1 1 0 1 0 0 1 0 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0
9 1 0 0 1 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 0 1 1 0 1
10 1 0 0 1 0 1 1 0 0 0 0 1 1 0 0 0 1 1 1 0 0 1 1 1 0 1 0 0 0 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 1 0 1
11 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 1 0 0 0 1 1 1 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0
12 1 1 1 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0 1 0 1 1 1 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 1 0 0
13 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0 1
14 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 1
15 0 1 0 0 0 0 1 0 0 1 1 0 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1
16 0 1 1 1 1 1 0 1 1 0 0 0 0 1 0 0 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 1 0 1 0 1 1 0 1 1 1 0 1
17 0 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 1 0
18 0 1 0 0 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 1 1 0 1 0 1 1 0 0 0 1 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 0 1
19 1 0 0 0 0 0 1 1 1 0 1 1 0 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 0 1
20 1 1 1 0 1 1 0 1 0 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 1 1 0 0 1 1 0 1 0
21 0 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 1 1 1
22 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1
23 1 0 1 1 0 0 0 1 1 1 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 1 0 0 1 0 0 0 0 0
24 0 0 0 1 1 1 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 0 1 0 1
25 0 0 0 1 0 1 0 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1 0 0
26 1 1 1 1 1 1 0 0 0 1 1 0 1 1 1 0 1 1 1 0 1 0 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 1 0 0
27 1 1 1 1 0 1 1 1 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 0
28 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 1 1 1 1 0 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 0 1 0
29 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 1
30 0 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 1 0
31 1 1 0 1 0 1 0 0 1 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 1
32 1 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 1 0 1 0 1 1 1 1 0 1 1 0 0 0 0 1 0 1 0 0
33 0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 1 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 0 1
34 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 1 1 0 0 1 0 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 1 1
35 0 1 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 1 1 0 0 1 1 0 1
36 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1
37 0 0 0 1 0 0 1 0 1 1 1 1 0 1 0 1 0 1 1 1 0 0 0 0 1 1 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 1 0
38 1 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 0 1 1 0 1 0
39 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 0 1 0 1 1 1
40 0 1 1 1 1 0 0 1 0 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0
41 1 1 1 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 1
42 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1 1 0 1 1 0 1 0 0 0 0 1 0 0 1 0 0 0
43 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1 1 1
44 1 1 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0
45 1 0 0 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 0 0 1 0 1 0
46 0 1 0 0 1 1 0 0 1 0 0 1 1 1 0 0 1 1 1 1 1 0 0 1 0 1 0 1 0 0 1 0 0 1 1 0 1 0 1 0 0 0 0 1 1 0 0 1 1 0
47 0 0 1 0 0 1 1 0 0 0 0 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1
48 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0
49 0 0 0 1 0 0 0 1 0 0 1 1 0 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1 1 0 0 1
50 1 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 1 0 0 0 0

5
csv/5n.csv Normal file
View File

@ -0,0 +1,5 @@
0;0;1;0;0
0;0;1;0;0
1;1;0;1;1
0;0;1;0;1
0;0;1;1;0
1 0 0 1 0 0
2 0 0 1 0 0
3 1 1 0 1 1
4 0 0 1 0 1
5 0 0 1 1 0

5
csv/5n_no_edges.csv Normal file
View File

@ -0,0 +1,5 @@
0;0;0;0;0
0;0;0;0;0
0;0;0;0;0
0;0;0;0;0
0;0;0;0;0
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 0 0

7
csv/7n.csv Normal file
View File

@ -0,0 +1,7 @@
0;0;0;0;0;0;0
0;0;0;0;1;0;0
0;0;0;0;0;0;0
0;0;0;0;1;0;0
0;1;0;1;0;0;0
0;0;0;0;0;0;1
0;0;0;0;0;1;0
1 0 0 0 0 0 0 0
2 0 0 0 0 1 0 0
3 0 0 0 0 0 0 0
4 0 0 0 0 1 0 0
5 0 1 0 1 0 0 0
6 0 0 0 0 0 0 1
7 0 0 0 0 0 1 0

496
graph.c
View File

@ -1,17 +1,497 @@
#include <stdint.h> #include "graph.h"
#include "matrix.h"
#include <string.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
void random_adjacency(const uint64_t row_length, const uint64_t column_length, uint64_t matrix[row_length][column_length]) { void random_adjacency(const ulong vertex_count, ulong matrix[vertex_count][vertex_count]) {
srand(time(NULL)); srand(time(NULL));
for (uint8_t row_index=0; row_index < row_length; row_index++) { for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (uint8_t column_index=0; column_index < column_length; column_index++) { for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if(column_index == row_index) { if (column_index == row_index) {
matrix[row_index][column_index] = 1; matrix[row_index][column_index] = 0;
continue; } else {
matrix[row_index][column_index] = rand() % 2;
} }
matrix[row_index][column_index] = rand()%2; }
}
}
void random_adjacency_struct(const Matrix *matrix) {
if (matrix->row_length != matrix->column_length) {
return;
}
srand(time(NULL));
for (ulong row_index = 0; row_index < matrix->row_length; row_index++) {
for (ulong column_index = 0; column_index < matrix->column_length; column_index++) {
if (column_index == row_index) {
matrix->values[row_index][column_index] = 0;
} else {
matrix->values[row_index][column_index] = rand() % 2;
}
}
}
}
void calculate_distance_matrix(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong distance_matrix[vertex_count][vertex_count]) {
ulong power_matrix[vertex_count][vertex_count];
ulong temp_power_matrix[vertex_count][vertex_count];
memcpy(power_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (row_index == column_index) {
distance_matrix[row_index][column_index] = 0;
} else if (adjacency_matrix[row_index][column_index] == 1) {
distance_matrix[row_index][column_index] = 1;
} else {
distance_matrix[row_index][column_index] = -1;
}
}
}
for(ulong k = 2; k <= vertex_count; k++) {
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(ulong));
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (power_matrix[row_index][column_index] != 0 && distance_matrix[row_index][column_index] == -1) {
distance_matrix[row_index][column_index] = k;
}
}
}
}
}
int get_eccentricities(const ulong vertex_count, const ulong distance_matrix[vertex_count][vertex_count], ulong eccentricities[vertex_count]) {
ulong eccentricity;
// set all eccentricities to infinity in case this is a disconnected graph
for (ulong index = 0; index < vertex_count; index++) {
eccentricities[index] = -1;
}
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
eccentricity = 0;
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (distance_matrix[row_index][column_index] > eccentricity) {
eccentricity = distance_matrix[row_index][column_index];
}
}
// in case of a disconnected graph
if (eccentricity == 0) {
return 1;
}
eccentricities[row_index] = eccentricity;
}
return 0;
}
ulong get_radius(const ulong vertex_count, const ulong eccentricities[vertex_count]) {
ulong radius = -1;
for (ulong index = 0; index < vertex_count; index++) {
if (eccentricities[index] < radius) {
radius = eccentricities[index];
}
}
return radius;
}
ulong get_diameter(const ulong vertex_count, const ulong eccentricities[vertex_count]) {
ulong diamter = 0;
for (ulong index = 0; index < vertex_count; index++) {
if (eccentricities[index] > diamter) {
diamter = eccentricities[index];
}
}
return diamter;
}
void get_centre(const ulong vertex_count, const ulong eccentricities[vertex_count], const ulong radius, ulong centre[vertex_count]) {
memset(centre, 0, vertex_count * sizeof(ulong));
for (ulong index = 0; index < vertex_count; index++) {
if (eccentricities[index] == radius) {
centre[index] = 1;
}
}
}
void calculate_path_matrix(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong path_matrix[vertex_count][vertex_count]) {
ulong power_matrix[vertex_count][vertex_count];
ulong temp_power_matrix[vertex_count][vertex_count];
memcpy(power_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (row_index == column_index || adjacency_matrix[row_index][column_index] == 1) {
path_matrix[row_index][column_index] = 1;
} else {
path_matrix[row_index][column_index] = 0;
}
}
}
for(ulong k = 2; k <= vertex_count; k++) {
memcpy(temp_power_matrix, power_matrix, vertex_count * vertex_count * sizeof(ulong));
gemm_basic(vertex_count, vertex_count, adjacency_matrix, vertex_count, vertex_count, temp_power_matrix, power_matrix);
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (power_matrix[row_index][column_index] != 0) {
path_matrix[row_index][column_index] = 1;
}
}
}
}
}
void find_components_basic(const ulong vertex_count, const ulong path_matrix[vertex_count][vertex_count], ulong components[vertex_count][vertex_count]) {
ulong component[vertex_count];
int contains_component;
memset(components, 0, vertex_count * vertex_count * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
memset(component, 0, vertex_count * sizeof(ulong));
contains_component = 0;
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (path_matrix[row_index][column_index] == 1) {
component[column_index] = column_index + 1;
}
}
for (ulong index = 0; index < vertex_count; index++) {
if (memcmp(components[index], component, vertex_count * sizeof(ulong)) == 0) {
contains_component = 1;
}
}
if (!contains_component) {
for (ulong index = 0; index < vertex_count; index++) {
components[row_index][index] = component[index];
}
}
}
}
void dfs(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, ulong visited[vertex_count]) {
visited[vertex] = 1;
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (visited[neighbor_vertex]) {
continue;
}
dfs(vertex_count, adjacency_matrix, neighbor_vertex, visited);
}
}
void find_components_dfs(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], ulong components[vertex_count][vertex_count]) {
ulong component[vertex_count];
int contains_component = 0;
memset(components, 0, vertex_count * vertex_count * sizeof(ulong));
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
memset(component, 0, vertex_count * sizeof(ulong));
contains_component = 0;
dfs(vertex_count, adjacency_matrix, vertex, component);
for (ulong index = 0; index < vertex_count; index++) {
if (memcmp(components[index], component, vertex_count * sizeof(ulong)) == 0) {
contains_component = 1;
}
}
if (!contains_component) {
for (ulong index = 0; index < vertex_count; index++) {
components[vertex][index] = component[index];
}
}
}
}
ulong amount_of_components(const ulong vertex_count, const ulong components[vertex_count][vertex_count]) {
ulong amount_of_components = 0;
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
amount_of_components++;
break;
}
}
}
return amount_of_components;
}
int contains_bridge(const ulong vertex_count, const ulong bridges[vertex_count][2], const ulong bridge[2]) {
for (ulong index = 0; index < vertex_count; index++) {
if (memcmp(bridges[index], bridge, 2 * sizeof(ulong)) == 0) {
return 1;
}
}
return 0;
}
void find_bridges_basic(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
ulong path_matrix[vertex_count][vertex_count];
ulong temp_adjacency_matrix[vertex_count][vertex_count];
ulong temp_components[vertex_count][vertex_count];
ulong bridge[2];
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (row_index == column_index) {
continue;
}
if (column_index < row_index) {
bridge[0] = column_index + 1;
bridge[1] = row_index + 1;
} else {
bridge[0] = row_index + 1;
bridge[1] = column_index + 1;
}
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
temp_adjacency_matrix[row_index][column_index] = 0;
temp_adjacency_matrix[column_index][row_index] = 0;
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, temp_components);
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
bridges[row_index][0] = bridge[0];
bridges[row_index][1] = bridge[1];
}
}
}
print_matrix(vertex_count, 2, bridges);
}
void find_bridges_dfs_v1(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
ulong temp_adjacency_matrix[vertex_count][vertex_count];
ulong temp_components[vertex_count][vertex_count];
ulong bridge[2];
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (row_index == column_index) {
continue;
}
if (column_index < row_index) {
bridge[0] = column_index + 1;
bridge[1] = row_index + 1;
} else {
bridge[0] = row_index + 1;
bridge[1] = column_index + 1;
}
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
temp_adjacency_matrix[row_index][column_index] = 0;
temp_adjacency_matrix[column_index][row_index] = 0;
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) && !contains_bridge(vertex_count, bridges, bridge)) {
bridges[row_index][0] = bridge[0];
bridges[row_index][1] = bridge[1];
}
}
}
}
void dfs_bridges(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, const ulong parent_vertex, ulong visited[vertex_count],
ulong current_time, ulong discovery_time[vertex_count], ulong lowest_time[vertex_count], ulong bridges[vertex_count][2]) {
current_time++;
visited[vertex] = 1;
discovery_time[vertex] = current_time;
lowest_time[vertex] = current_time;
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (parent_vertex != neighbor_vertex && visited[neighbor_vertex]) {
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
lowest_time[vertex] = discovery_time[neighbor_vertex];
}
continue;
}
if (visited[neighbor_vertex]) {
continue;
}
dfs_bridges(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, bridges);
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
lowest_time[vertex] = lowest_time[neighbor_vertex];
}
if (discovery_time[vertex] < lowest_time[neighbor_vertex]) {
bridges[neighbor_vertex][0] = vertex + 1;
bridges[neighbor_vertex][1] = neighbor_vertex + 1;
}
}
}
void find_bridges_dfs_v2(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong bridges[vertex_count][2]) {
ulong visited[vertex_count];
ulong current_time = 0;
ulong discovery_time[vertex_count];
ulong lowest_time[vertex_count];
memset(bridges, 0, vertex_count * 2 * sizeof(ulong));
memset(visited, 0, vertex_count * sizeof(ulong));
memset(discovery_time, 0, vertex_count * sizeof(ulong));
memset(lowest_time, 0, vertex_count * sizeof(ulong));
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
if (!visited[vertex]) {
dfs_bridges(vertex_count, adjacency_matrix, vertex, -1, visited, current_time, discovery_time, lowest_time, bridges);
}
}
}
void find_articulations_basic(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
ulong path_matrix[vertex_count][vertex_count];
ulong temp_adjacency_matrix[vertex_count][vertex_count];
ulong temp_components[vertex_count][vertex_count];
memset(articulations, 0, vertex_count * sizeof(ulong));
for (ulong i = 0; i < vertex_count; i++) {
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
temp_adjacency_matrix[row_index][i] = 0;
temp_adjacency_matrix[i][column_index] = 0;
}
}
calculate_path_matrix(vertex_count, temp_adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, temp_components);
// the + 1 is needed because I am not removing the vertex, I am just removing all of its edges
// removing all of its edges, means it itself becomes a component, which needs to be accounted for
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) + 1) {
articulations[i] = i + 1;
}
}
}
void find_articulations_dfs_v1(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
ulong temp_adjacency_matrix[vertex_count][vertex_count];
ulong temp_components[vertex_count][vertex_count];
memset(articulations, 0, vertex_count * sizeof(ulong));
for (ulong i = 0; i < vertex_count; i++) {
memcpy(temp_adjacency_matrix, adjacency_matrix, vertex_count * vertex_count * sizeof(ulong));
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
temp_adjacency_matrix[row_index][i] = 0;
temp_adjacency_matrix[i][column_index] = 0;
}
}
find_components_dfs(vertex_count, temp_adjacency_matrix, temp_components);
// the + 1 is needed because I am not removing the vertex, I am just removing all of its edges
// removing all of its edges, means it itself becomes a component, which needs to be accounted for
if (amount_of_components(vertex_count, temp_components) > amount_of_components(vertex_count, components) + 1) {
articulations[i] = i + 1;
}
}
}
void dfs_articulations(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count], const ulong vertex, const ulong parent_vertex,
ulong visited[vertex_count], ulong current_time, ulong discovery_time[vertex_count], ulong lowest_time[vertex_count],
ulong articulations[vertex_count]) {
current_time++;
visited[vertex] = 1;
discovery_time[vertex] = current_time;
lowest_time[vertex] = current_time;
ulong child_count = 0;
ulong is_articulation = 0;
for (ulong neighbor_vertex = 0; neighbor_vertex < vertex_count; neighbor_vertex++) {
if (adjacency_matrix[vertex][neighbor_vertex] != 1) {
continue;
}
if (visited[neighbor_vertex]) {
if (lowest_time[vertex] > discovery_time[neighbor_vertex]) {
lowest_time[vertex] = discovery_time[neighbor_vertex];
}
continue;
}
child_count++;
dfs_articulations(vertex_count, adjacency_matrix, neighbor_vertex, vertex, visited, current_time, discovery_time, lowest_time, articulations);
if (lowest_time[vertex] > lowest_time[neighbor_vertex]) {
lowest_time[vertex] = lowest_time[neighbor_vertex];
}
if (parent_vertex != -1 && discovery_time[vertex] <= lowest_time[neighbor_vertex]) {
is_articulation = 1;
}
}
if (parent_vertex == -1 && child_count > 1) {
is_articulation = 1;
}
if (is_articulation) {
articulations[vertex] = vertex + 1;
}
}
void find_articulations_dfs_v2(const ulong vertex_count, const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count], ulong articulations[vertex_count]) {
ulong visited[vertex_count];
ulong current_time = 0;
ulong discovery_time[vertex_count];
ulong lowest_time[vertex_count];
memset(articulations, 0, vertex_count * sizeof(ulong));
memset(visited, 0, vertex_count * sizeof(ulong));
memset(discovery_time, 0, vertex_count * sizeof(ulong));
memset(lowest_time, 0, vertex_count * sizeof(ulong));
for (ulong vertex = 0; vertex < vertex_count; vertex++) {
if (!visited[vertex]) {
dfs_articulations(vertex_count, adjacency_matrix, vertex, -1, visited, current_time, discovery_time, lowest_time, articulations);
} }
} }
} }

69
graph.h
View File

@ -1,8 +1,73 @@
#ifndef GRAPH_H #ifndef GRAPH_H
#define GRAPH_H #define GRAPH_H
#include <stdint.h> #include "matrix.h"
void random_adjacency(const uint64_t row_length, const uint64_t column_length, uint64_t matrix[row_length][column_length]); void random_adjacency(const ulong vertex_count,
ulong matrix[vertex_count][vertex_count]);
void random_adjacency_struct(const Matrix *matrix);
void calculate_distance_matrix(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
ulong distance_matrix[vertex_count][vertex_count]);
// returns 1 if it is a disconnected graph and sets all values in eccentricities to UINT64_MAX
int get_eccentricities(const ulong vertex_count,
const ulong distance_matrix[vertex_count][vertex_count],
ulong eccentricities[vertex_count]);
ulong get_radius(const ulong vertex_count,
const ulong eccentricities[vertex_count]);
ulong get_diameter(const ulong vertex_count,
const ulong eccentricities[vertex_count]);
void get_centre(const ulong vertex_count,
const ulong eccentricities[vertex_count],
const ulong radius,
ulong centre[vertex_count]);
void calculate_path_matrix(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
ulong path_matrix[vertex_count][vertex_count]);
void find_components_basic(const ulong vertex_count,
const ulong path_matrix[vertex_count][vertex_count],
ulong components[vertex_count][vertex_count]);
void find_components_dfs(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
ulong components[vertex_count][vertex_count]);
void find_bridges_basic(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong bridges[vertex_count][2]);
void find_bridges_dfs_v1(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong bridges[vertex_count][2]);
void find_bridges_dfs_v2(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong bridges[vertex_count][2]);
void find_articulations_basic(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong articulations[vertex_count]);
void find_articulations_dfs_v1(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong articulations[vertex_count]);
void find_articulations_dfs_v2(const ulong vertex_count,
const ulong adjacency_matrix[vertex_count][vertex_count],
const ulong components[vertex_count][vertex_count],
ulong articulations[vertex_count]);
#endif #endif

300
main.c
View File

@ -1,16 +1,294 @@
#include "graph.h" #include "graph.h"
#include "matrix.h" #include <stdio.h>
#include <stdint.h> #include <time.h>
#include <stdlib.h>
void benchmark_gemm() {
const ulong vertex_count = 100;
ulong adjacency_matrix1[vertex_count][vertex_count];
ulong adjacency_matrix2[vertex_count][vertex_count];
ulong dot_product[vertex_count][vertex_count];
double elapsed_time = 0.0;
const ulong iterations = 10;
clock_t start_time;
for (ulong i = 0; i < iterations; i++) {
random_adjacency(vertex_count, adjacency_matrix1);
random_adjacency(vertex_count, adjacency_matrix2);
start_time = clock();
gemm_basic(vertex_count, vertex_count, adjacency_matrix1,
vertex_count, vertex_count, adjacency_matrix2,
dot_product);
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
}
printf("%lu iterations of gemm_basic took roughly %f seconds\n", iterations, elapsed_time);
printf("An iteration of gemm_basic took on average roughly %f seconds\n", elapsed_time/iterations);
}
void benchmark_find_components() {
const ulong vertex_count = 100;
ulong adjacency_matrix[vertex_count][vertex_count];
ulong components[vertex_count][vertex_count];
ulong path_matrix[vertex_count][vertex_count];
double elapsed_time = 0.0;
const ulong iterations = 100;
clock_t start_time;
for (ulong i = 0; i < iterations; i++) {
random_adjacency(vertex_count, adjacency_matrix);
start_time = clock();
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, components);
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
}
printf("%lu iterations of find_components_basic took roughly %f seconds\n", iterations, elapsed_time);
printf("An iteration of find_components_basic took on average roughly %f seconds\n", elapsed_time/iterations);
elapsed_time = 0.0;
for (ulong i = 0; i < iterations; i++) {
random_adjacency(vertex_count, adjacency_matrix);
start_time = clock();
find_components_dfs(vertex_count, adjacency_matrix, components);
elapsed_time += (double)(clock() - start_time) / CLOCKS_PER_SEC;
}
printf("%lu iterations of find_components_dfs took roughly %f seconds\n", iterations, elapsed_time);
printf("An iteration of find_components_dfs took on average roughly %f seconds\n", elapsed_time/iterations);
}
void test_with_basic() {
const ulong vertex_count = 24;
ulong adjacency_matrix[vertex_count][vertex_count];
ulong distance_matrix[vertex_count][vertex_count];
ulong path_matrix[vertex_count][vertex_count];
ulong eccentricities[vertex_count];
ulong radius, diameter, centre[vertex_count];
ulong components[vertex_count][vertex_count];
ulong bridges[vertex_count][2];
ulong articulations[vertex_count];
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
return;
}
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
get_eccentricities(vertex_count, distance_matrix, eccentricities);
radius = get_radius(vertex_count, eccentricities);
diameter = get_diameter(vertex_count, eccentricities);
get_centre(vertex_count, eccentricities, radius, centre);
calculate_path_matrix(vertex_count, adjacency_matrix, path_matrix);
find_components_basic(vertex_count, path_matrix, components);
find_bridges_basic(vertex_count, adjacency_matrix, components, bridges);
find_articulations_basic(vertex_count, adjacency_matrix, components, articulations);
puts("adjacency_matrix:");
print_matrix(vertex_count, vertex_count, adjacency_matrix);
puts("\ndistance_matrix:");
print_matrix(vertex_count, vertex_count, distance_matrix);
puts("\neccentricities:");
for (ulong index = 0; index < vertex_count; index++) {
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
}
printf("\nradius: %lu", radius);
printf("\ndiameter: %lu", diameter);
puts("\ncentre:");
for (ulong index = 0; index < vertex_count; index++) {
if (centre[index] == 1) {
printf("\tVertex %lu\n", index + 1);
}
}
puts("\npath_matrix:");
print_matrix(vertex_count, vertex_count, path_matrix);
puts("\ncomponents:");
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
int empty = 1;
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
empty = 0;
}
}
if (empty) {
continue;
}
printf("\tComponent %lu: {", row_index + 1);
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
printf("%lu, ", components[row_index][column_index]);
}
}
puts("}");
}
puts("\nbridges:");
for (ulong index = 0; index < vertex_count; index++) {
if (bridges[index][0] != 0) {
printf("\tBridge %lu: {%lu, %lu}\n", index + 1, bridges[index][0], bridges[index][1]);
}
}
puts("\narticulations:");
for (ulong index = 0; index < vertex_count; index++) {
if (articulations[index] != 0) {
printf("\tVertex %lu\n", articulations[index]);
}
}
}
void test_with_dfs() {
const ulong vertex_count = 24;
ulong adjacency_matrix[vertex_count][vertex_count];
ulong distance_matrix[vertex_count][vertex_count];
ulong eccentricities[vertex_count];
ulong radius, diameter;
ulong centre[vertex_count];
ulong components[vertex_count][vertex_count];
ulong bridges[vertex_count][2];
ulong articulations[vertex_count];
if (read_csv("csv/24n.csv", vertex_count, vertex_count, adjacency_matrix) == 1) {
return;
}
/*
const ulong vertex_count = 1500;
ulong (*adjacency_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
ulong (*distance_matrix)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
ulong *eccentricities = malloc(vertex_count * sizeof(ulong));
ulong radius, diameter;
ulong *centre = malloc(vertex_count * sizeof(ulong));
ulong (*components)[vertex_count] = malloc(vertex_count * vertex_count * sizeof(ulong));
ulong (*bridges)[vertex_count] = malloc(vertex_count * 2 * sizeof(ulong));
ulong *articulations = malloc(vertex_count * sizeof(ulong));
random_adjacency(vertex_count, adjacency_matrix);
*/
calculate_distance_matrix(vertex_count, adjacency_matrix, distance_matrix);
get_eccentricities(vertex_count, distance_matrix, eccentricities);
radius = get_radius(vertex_count, eccentricities);
diameter = get_diameter(vertex_count, eccentricities);
get_centre(vertex_count, eccentricities, radius, centre);
find_components_dfs(vertex_count, adjacency_matrix, components);
find_bridges_dfs_v2(vertex_count, adjacency_matrix, components, bridges);
find_articulations_dfs_v2(vertex_count, adjacency_matrix, components, articulations);
puts("\nadjacency_matrix:");
print_matrix(vertex_count, vertex_count, adjacency_matrix);
puts("\ndistance_matrix:");
print_matrix(vertex_count, vertex_count, distance_matrix);
puts("\neccentricities:");
for (ulong index = 0; index < vertex_count; index++) {
printf("\tVertex %lu: %lu\n", index + 1, eccentricities[index]);
}
printf("\nradius: %lu", radius);
printf("\ndiameter: %lu", diameter);
puts("\ncentre:");
for (ulong index = 0; index < vertex_count; index++) {
if (centre[index] == 1) {
printf("\tVertex %lu\n", index + 1);
}
}
puts("\ncomponents:");
for (ulong row_index = 0; row_index < vertex_count; row_index++) {
int empty = 1;
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
empty = 0;
}
}
if (empty) {
continue;
}
printf("\tComponent %lu: {", row_index + 1);
for (ulong column_index = 0; column_index < vertex_count; column_index++) {
if (components[row_index][column_index] != 0) {
printf("%lu, ", column_index + 1);
}
}
puts("}");
}
ulong bridge_number = 1;
puts("\nbridges:");
for (ulong index = 0; index < vertex_count; index++) {
if (bridges[index][0] != 0) {
printf("\tBridge %lu: {%lu, %lu}\n", bridge_number, bridges[index][0], bridges[index][1]);
bridge_number++;
}
}
puts("\narticulations:");
for (ulong index = 0; index < vertex_count; index++) {
if (articulations[index] != 0) {
printf("\tVertex %lu\n", articulations[index]);
}
}
// free(adjacency_matrix);
// free(distance_matrix);
// free(eccentricities);
// free(centre);
// free(components);
// free(bridges);
// free(articulations);
}
void test_with_structs() {
ulong row_length = 5, column_length = 5;
Matrix *adjacency_matrix1 = create_matrix(row_length, column_length);
Matrix *adjacency_matrix2 = create_matrix(row_length, column_length);
Matrix *dot_product = create_matrix(row_length, column_length);
random_adjacency_struct(adjacency_matrix1);
print_matrix_struct(adjacency_matrix1);
putchar('\n');
random_adjacency_struct(adjacency_matrix2);
print_matrix_struct(adjacency_matrix2);
putchar('\n');
gemm_basic_structs(adjacency_matrix1, adjacency_matrix2,dot_product);
print_matrix_struct(dot_product);
free_matrix(adjacency_matrix1);
free_matrix(adjacency_matrix2);
free_matrix(dot_product);
}
int main(void) { int main(void) {
const uint64_t row_length = 5; // benchmark_gemm();
const uint64_t column_length = 5; // benchmark_find_components();
uint64_t matrix1[row_length][column_length]; // test_with_basic();
uint64_t matrix2[row_length*2][column_length*2]; // test_with_dfs();
test_with_structs();
random_adjacency(row_length, column_length, matrix1);
random_adjacency(row_length*2, column_length*2, matrix2);
print_matrix(row_length, column_length, matrix1);
} }

129
matrix.c
View File

@ -1,26 +1,119 @@
#include <stdint.h> #include "matrix.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void print_matrix(const uint64_t row_length, const uint64_t column_length, void print_matrix(const ulong row_length, const ulong column_length, const ulong matrix[row_length][column_length]) {
const uint64_t matrix[row_length][column_length]) { for (ulong column_index=0; column_index < column_length; column_index++) {
for (ulong row_index=0; row_index < row_length; row_index++) {
for (uint64_t column_index=0; column_index < column_length; column_index++) {
for (uint64_t row_index=0; row_index < row_length; row_index++) {
printf("%lu ", matrix[row_index][column_index]); printf("%lu ", matrix[row_index][column_index]);
} }
printf("\n"); puts("");
} }
} }
int matrix_multiply_basic(const uint64_t row_length1, void print_matrix_struct(const Matrix *matrix) {
const uint64_t column_length1, for (ulong column_index=0; column_index < matrix->column_length; column_index++) {
const uint64_t matrix1[row_length1][column_length1], for (ulong row_index=0; row_index < matrix->row_length; row_index++) {
const uint64_t row_length2, printf("%lu ", matrix->values[row_index][column_index]);
const uint64_t column_length2, }
const uint64_t matrix2[row_length2][column_length2], puts("");
uint64_t output_matrix[row_length1][column_length2]) { }
}
int ret = 0;
void gemm_basic(const ulong row_length1, const ulong column_length1, const ulong matrix1[row_length1][column_length1],
return ret; const ulong row_length2, const ulong column_length2, const ulong matrix2[row_length2][column_length2],
ulong output_matrix[row_length1][column_length2]) {
ulong sum;
for (ulong i = 0; i < row_length1; i++) {
for (ulong j = 0; j < column_length2; j++) {
sum = 0;
for (ulong k = 0; k < row_length1; k++) {
sum += matrix1[i][k] * matrix2[k][j];
}
output_matrix[i][j] = sum;
}
}
}
void gemm_basic_structs(const Matrix *matrix1, const Matrix *matrix2, Matrix *output_matrix) {
ulong sum;
for (ulong i = 0; i < matrix1->row_length; i++) {
for (ulong j = 0; j < matrix2->column_length; j++) {
sum = 0;
for (ulong k = 0; k < matrix1->row_length; k++) {
sum += matrix1->values[i][k] * matrix2->values[k][j];
}
output_matrix->values[i][j] = sum;
}
}
}
int read_csv(const char *file_name, const ulong row_length, const ulong column_length, ulong output_matrix[row_length][column_length]) {
FILE *file_ptr;
ulong bufsize = row_length*2+1; // have to account for delimiters
char buffer[bufsize];
char *value, *file_line;
ulong row_index = 0, column_index = 0;
file_ptr = fopen(file_name, "r");
if (file_ptr == NULL) {
puts("Unable to open csv");
return 1;
}
while ((file_line = fgets(buffer, bufsize, file_ptr)) != NULL) {
// This shit is just needed and I dont know why
file_line[strcspn(file_line, "\n")] = 0;
value = strtok(file_line, ";,");
// for some reason there are two NULLs at the end of a line
// and I dont wanna increment the column_index
if (value == NULL) {
continue;
}
while (value != NULL) {
output_matrix[row_index++][column_index] = strtoul(value, NULL, 0);
value = strtok(NULL, ";,");
}
row_index = 0;
column_index++;
}
fclose(file_ptr);
return 0;
}
Matrix* create_matrix(ulong row_length, ulong column_length) {
ulong **values = (ulong**)malloc(row_length * sizeof(ulong*));
for (ulong index = 0; index < row_length; index++) {
values[index] = (ulong*)malloc(column_length * sizeof(ulong));
}
Matrix *matrix = malloc(sizeof(Matrix));
matrix->row_length = row_length;
matrix->column_length = column_length;
matrix->values = values;
return matrix;
}
void free_matrix(Matrix *matrix) {
for (ulong index = 0; index < matrix->row_length; index++) {
free(matrix->values[index]);
}
free(matrix->values);
} }

View File

@ -1,20 +1,34 @@
#ifndef MATRIX_H #ifndef MATRIX_H
#define MATRIX_H #define MATRIX_H
#include <stdint.h> typedef unsigned long ulong;
typedef struct matrix {ulong row_length; ulong column_length; ulong **values;} Matrix;
void print_matrix(const uint64_t row_length, const uint64_t column_length, void print_matrix(const ulong row_length, const ulong column_length,
const uint64_t matrix[row_length][column_length]); const ulong matrix[row_length][column_length]);
// Takes three matrices, the first two will be multiplied and restult will be written to output_matrix. void print_matrix_struct(const Matrix *matrix);
// Matrix requirements are as specified in the parameters.
// Function return 0 on success and 1 on failure. /*
int matrix_multiply_basic(const uint64_t row_length1, First two matrices will be multiplied and
const uint64_t column_length1, restult will be written to output_matrix.
const uint64_t matrix1[row_length1][column_length1], Matrix size requirements are as specified in the parameters.
const uint64_t row_length2, */
const uint64_t column_length2, void gemm_basic(const ulong row_length1, const ulong column_length1,
const uint64_t matrix2[row_length2][column_length2], const ulong matrix1[row_length1][column_length1],
uint64_t output_matrix[row_length1][column_length2]); const ulong row_length2, const ulong column_length2,
const ulong matrix2[row_length2][column_length2],
ulong output_matrix[row_length1][column_length2]);
void gemm_basic_structs(const Matrix *matrix1, const Matrix *matrix2,
Matrix *output_matrix);
int read_csv(const char *file_name, const ulong row_length,
const ulong column_length,
ulong output_matrix[row_length][column_length]);
Matrix* create_matrix(ulong row_length, ulong column_length);
void free_matrix(Matrix *matrix);
#endif #endif