first working, without arg parser, unoptimized
This commit is contained in:
parent
b6150ab95c
commit
c7fd378336
3
.vscode/c_cpp_properties.json
vendored
3
.vscode/c_cpp_properties.json
vendored
@ -9,7 +9,8 @@
|
||||
"defines": [],
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -1,6 +1,11 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"random_graph.h": "c",
|
||||
"random_groups.h": "c"
|
||||
"random_groups.h": "c",
|
||||
"random_edge_weight.h": "c",
|
||||
"rand_large.h": "c",
|
||||
"stdint.h": "c",
|
||||
"random_group_steiner.h": "c",
|
||||
"random_vertex_weight.h": "c"
|
||||
}
|
||||
}
|
6
Makefile
6
Makefile
@ -1,8 +1,8 @@
|
||||
# Compiler and Flags
|
||||
CC = gcc
|
||||
# CFLAGS = -Wall -Wextra -Iinclude -g -pg
|
||||
CFLAGS = -O2 -march=native -DNDEBUG -Wall -Wextra -Werror -Iinclude
|
||||
LDFLAGS = -lm
|
||||
CFLAGS = -Wall -Wextra -Iinclude -g -pg -O0
|
||||
# CFLAGS = -O3 -march=native -DNDEBUG -Wall -Wextra -Werror -Iinclude -s -flto -fno-math-errno
|
||||
LDFLAGS = -lm -flto
|
||||
|
||||
# Directories
|
||||
SRC_DIR = src
|
||||
|
160
analysis
Normal file
160
analysis
Normal file
@ -0,0 +1,160 @@
|
||||
Flat profile:
|
||||
|
||||
Each sample counts as 0.01 seconds.
|
||||
% cumulative self self total
|
||||
time seconds seconds calls s/call s/call name
|
||||
100.07 3.36 3.36 2 1.68 1.68 random_connected_graph
|
||||
0.00 3.36 0.00 6 0.00 0.00 cmpInt
|
||||
0.00 3.36 0.00 3 0.00 0.00 generate_random_edge_weight
|
||||
|
||||
% the percentage of the total running time of the
|
||||
time program used by this function.
|
||||
|
||||
cumulative a running sum of the number of seconds accounted
|
||||
seconds for by this function and those listed above it.
|
||||
|
||||
self the number of seconds accounted for by this
|
||||
seconds function alone. This is the major sort for this
|
||||
listing.
|
||||
|
||||
calls the number of times this function was invoked, if
|
||||
this function is profiled, else blank.
|
||||
|
||||
self the average number of milliseconds spent in this
|
||||
ms/call function per call, if this function is profiled,
|
||||
else blank.
|
||||
|
||||
total the average number of milliseconds spent in this
|
||||
ms/call function and its descendents per call, if this
|
||||
function is profiled, else blank.
|
||||
|
||||
name the name of the function. This is the minor sort
|
||||
for this listing. The index shows the location of
|
||||
the function in the gprof listing. If the index is
|
||||
in parenthesis it shows where it would appear in
|
||||
the gprof listing if it were to be printed.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved.
|
||||
|
||||
Call graph (explanation follows)
|
||||
|
||||
|
||||
granularity: each sample hit covers 2 byte(s) for 0.30% of 3.36 seconds
|
||||
|
||||
index % time self children called name
|
||||
1.68 0.00 1/2 main [3]
|
||||
1.68 0.00 1/2 generate_random_group_steiner_instance [2]
|
||||
[1] 100.0 3.36 0.00 2 random_connected_graph [1]
|
||||
0.00 0.00 6/6 cmpInt [4]
|
||||
0.00 0.00 3/3 generate_random_edge_weight [5]
|
||||
-----------------------------------------------
|
||||
<spontaneous>
|
||||
[2] 50.0 0.00 1.68 generate_random_group_steiner_instance [2]
|
||||
1.68 0.00 1/2 random_connected_graph [1]
|
||||
-----------------------------------------------
|
||||
<spontaneous>
|
||||
[3] 50.0 0.00 1.68 main [3]
|
||||
1.68 0.00 1/2 random_connected_graph [1]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 6/6 random_connected_graph [1]
|
||||
[4] 0.0 0.00 0.00 6 cmpInt [4]
|
||||
-----------------------------------------------
|
||||
0.00 0.00 3/3 random_connected_graph [1]
|
||||
[5] 0.0 0.00 0.00 3 generate_random_edge_weight [5]
|
||||
-----------------------------------------------
|
||||
|
||||
This table describes the call tree of the program, and was sorted by
|
||||
the total amount of time spent in each function and its children.
|
||||
|
||||
Each entry in this table consists of several lines. The line with the
|
||||
index number at the left hand margin lists the current function.
|
||||
The lines above it list the functions that called this function,
|
||||
and the lines below it list the functions this one called.
|
||||
This line lists:
|
||||
index A unique number given to each element of the table.
|
||||
Index numbers are sorted numerically.
|
||||
The index number is printed next to every function name so
|
||||
it is easier to look up where the function is in the table.
|
||||
|
||||
% time This is the percentage of the `total' time that was spent
|
||||
in this function and its children. Note that due to
|
||||
different viewpoints, functions excluded by options, etc,
|
||||
these numbers will NOT add up to 100%.
|
||||
|
||||
self This is the total amount of time spent in this function.
|
||||
|
||||
children This is the total amount of time propagated into this
|
||||
function by its children.
|
||||
|
||||
called This is the number of times the function was called.
|
||||
If the function called itself recursively, the number
|
||||
only includes non-recursive calls, and is followed by
|
||||
a `+' and the number of recursive calls.
|
||||
|
||||
name The name of the current function. The index number is
|
||||
printed after it. If the function is a member of a
|
||||
cycle, the cycle number is printed between the
|
||||
function's name and the index number.
|
||||
|
||||
|
||||
For the function's parents, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the function into this parent.
|
||||
|
||||
children This is the amount of time that was propagated from
|
||||
the function's children into this parent.
|
||||
|
||||
called This is the number of times this parent called the
|
||||
function `/' the total number of times the function
|
||||
was called. Recursive calls to the function are not
|
||||
included in the number after the `/'.
|
||||
|
||||
name This is the name of the parent. The parent's index
|
||||
number is printed after it. If the parent is a
|
||||
member of a cycle, the cycle number is printed between
|
||||
the name and the index number.
|
||||
|
||||
If the parents of the function cannot be determined, the word
|
||||
`<spontaneous>' is printed in the `name' field, and all the other
|
||||
fields are blank.
|
||||
|
||||
For the function's children, the fields have the following meanings:
|
||||
|
||||
self This is the amount of time that was propagated directly
|
||||
from the child into the function.
|
||||
|
||||
children This is the amount of time that was propagated from the
|
||||
child's children to the function.
|
||||
|
||||
called This is the number of times the function called
|
||||
this child `/' the total number of times the child
|
||||
was called. Recursive calls by the child are not
|
||||
listed in the number after the `/'.
|
||||
|
||||
name This is the name of the child. The child's index
|
||||
number is printed after it. If the child is a
|
||||
member of a cycle, the cycle number is printed
|
||||
between the name and the index number.
|
||||
|
||||
If there are any cycles (circles) in the call graph, there is an
|
||||
entry for the cycle-as-a-whole. This entry shows who called the
|
||||
cycle (as parents) and the members of the cycle (as children.)
|
||||
The `+' recursive calls entry shows the number of function calls that
|
||||
were internal to the cycle, and the calls entry for each member shows,
|
||||
for that member, how many times it was called from other members of
|
||||
the cycle.
|
||||
|
||||
Copyright (C) 2012-2023 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved.
|
||||
|
||||
Index by function name
|
||||
|
||||
[4] cmpInt [5] generate_random_edge_weight [1] random_connected_graph
|
@ -14,6 +14,5 @@ services:
|
||||
# - NODE_ENV=development
|
||||
user: root
|
||||
command: sleep infinity
|
||||
|
||||
volumes:
|
||||
steingen-volume:
|
||||
|
512
example2.txt
Normal file
512
example2.txt
Normal file
@ -0,0 +1,512 @@
|
||||
Generated graph edges:
|
||||
Edge 0 -> 1
|
||||
Edge 0 -> 2
|
||||
Edge 0 -> 6
|
||||
Edge 0 -> 8
|
||||
Edge 0 -> 9
|
||||
Edge 0 -> 10
|
||||
Edge 0 -> 13
|
||||
Edge 0 -> 14
|
||||
Edge 0 -> 15
|
||||
Edge 0 -> 22
|
||||
Edge 0 -> 23
|
||||
Edge 0 -> 24
|
||||
Edge 0 -> 25
|
||||
Edge 0 -> 26
|
||||
Edge 0 -> 27
|
||||
Edge 0 -> 28
|
||||
Edge 0 -> 29
|
||||
Edge 0 -> 30
|
||||
Edge 0 -> 31
|
||||
Edge 0 -> 32
|
||||
Edge 0 -> 35
|
||||
Edge 0 -> 38
|
||||
Edge 1 -> 3
|
||||
Edge 1 -> 7
|
||||
Edge 1 -> 8
|
||||
Edge 1 -> 10
|
||||
Edge 1 -> 11
|
||||
Edge 1 -> 12
|
||||
Edge 1 -> 13
|
||||
Edge 1 -> 14
|
||||
Edge 1 -> 15
|
||||
Edge 1 -> 17
|
||||
Edge 1 -> 18
|
||||
Edge 1 -> 19
|
||||
Edge 1 -> 20
|
||||
Edge 1 -> 21
|
||||
Edge 1 -> 22
|
||||
Edge 1 -> 24
|
||||
Edge 1 -> 25
|
||||
Edge 1 -> 27
|
||||
Edge 1 -> 28
|
||||
Edge 1 -> 29
|
||||
Edge 1 -> 30
|
||||
Edge 1 -> 31
|
||||
Edge 1 -> 32
|
||||
Edge 1 -> 33
|
||||
Edge 1 -> 35
|
||||
Edge 1 -> 36
|
||||
Edge 1 -> 37
|
||||
Edge 1 -> 39
|
||||
Edge 2 -> 3
|
||||
Edge 2 -> 4
|
||||
Edge 2 -> 7
|
||||
Edge 2 -> 8
|
||||
Edge 2 -> 9
|
||||
Edge 2 -> 12
|
||||
Edge 2 -> 13
|
||||
Edge 2 -> 14
|
||||
Edge 2 -> 15
|
||||
Edge 2 -> 16
|
||||
Edge 2 -> 17
|
||||
Edge 2 -> 18
|
||||
Edge 2 -> 19
|
||||
Edge 2 -> 20
|
||||
Edge 2 -> 21
|
||||
Edge 2 -> 22
|
||||
Edge 2 -> 24
|
||||
Edge 2 -> 27
|
||||
Edge 2 -> 29
|
||||
Edge 2 -> 30
|
||||
Edge 2 -> 31
|
||||
Edge 2 -> 33
|
||||
Edge 2 -> 34
|
||||
Edge 2 -> 36
|
||||
Edge 2 -> 38
|
||||
Edge 2 -> 39
|
||||
Edge 3 -> 4
|
||||
Edge 3 -> 6
|
||||
Edge 3 -> 7
|
||||
Edge 3 -> 9
|
||||
Edge 3 -> 10
|
||||
Edge 3 -> 12
|
||||
Edge 3 -> 13
|
||||
Edge 3 -> 14
|
||||
Edge 3 -> 15
|
||||
Edge 3 -> 16
|
||||
Edge 3 -> 17
|
||||
Edge 3 -> 18
|
||||
Edge 3 -> 19
|
||||
Edge 3 -> 21
|
||||
Edge 3 -> 22
|
||||
Edge 3 -> 23
|
||||
Edge 3 -> 24
|
||||
Edge 3 -> 26
|
||||
Edge 3 -> 27
|
||||
Edge 3 -> 28
|
||||
Edge 3 -> 31
|
||||
Edge 3 -> 32
|
||||
Edge 3 -> 33
|
||||
Edge 3 -> 34
|
||||
Edge 3 -> 35
|
||||
Edge 3 -> 38
|
||||
Edge 4 -> 5
|
||||
Edge 4 -> 6
|
||||
Edge 4 -> 7
|
||||
Edge 4 -> 8
|
||||
Edge 4 -> 9
|
||||
Edge 4 -> 11
|
||||
Edge 4 -> 12
|
||||
Edge 4 -> 13
|
||||
Edge 4 -> 14
|
||||
Edge 4 -> 15
|
||||
Edge 4 -> 17
|
||||
Edge 4 -> 19
|
||||
Edge 4 -> 20
|
||||
Edge 4 -> 21
|
||||
Edge 4 -> 22
|
||||
Edge 4 -> 23
|
||||
Edge 4 -> 25
|
||||
Edge 4 -> 27
|
||||
Edge 4 -> 28
|
||||
Edge 4 -> 29
|
||||
Edge 4 -> 30
|
||||
Edge 4 -> 31
|
||||
Edge 4 -> 32
|
||||
Edge 4 -> 33
|
||||
Edge 4 -> 35
|
||||
Edge 4 -> 38
|
||||
Edge 4 -> 39
|
||||
Edge 5 -> 8
|
||||
Edge 5 -> 9
|
||||
Edge 5 -> 10
|
||||
Edge 5 -> 11
|
||||
Edge 5 -> 12
|
||||
Edge 5 -> 16
|
||||
Edge 5 -> 17
|
||||
Edge 5 -> 18
|
||||
Edge 5 -> 22
|
||||
Edge 5 -> 24
|
||||
Edge 5 -> 25
|
||||
Edge 5 -> 26
|
||||
Edge 5 -> 28
|
||||
Edge 5 -> 34
|
||||
Edge 5 -> 36
|
||||
Edge 5 -> 37
|
||||
Edge 5 -> 38
|
||||
Edge 5 -> 39
|
||||
Edge 6 -> 7
|
||||
Edge 6 -> 9
|
||||
Edge 6 -> 10
|
||||
Edge 6 -> 11
|
||||
Edge 6 -> 12
|
||||
Edge 6 -> 13
|
||||
Edge 6 -> 14
|
||||
Edge 6 -> 15
|
||||
Edge 6 -> 17
|
||||
Edge 6 -> 18
|
||||
Edge 6 -> 20
|
||||
Edge 6 -> 22
|
||||
Edge 6 -> 23
|
||||
Edge 6 -> 26
|
||||
Edge 6 -> 27
|
||||
Edge 6 -> 28
|
||||
Edge 6 -> 29
|
||||
Edge 6 -> 30
|
||||
Edge 6 -> 33
|
||||
Edge 6 -> 36
|
||||
Edge 6 -> 37
|
||||
Edge 7 -> 8
|
||||
Edge 7 -> 9
|
||||
Edge 7 -> 12
|
||||
Edge 7 -> 14
|
||||
Edge 7 -> 15
|
||||
Edge 7 -> 17
|
||||
Edge 7 -> 18
|
||||
Edge 7 -> 19
|
||||
Edge 7 -> 20
|
||||
Edge 7 -> 23
|
||||
Edge 7 -> 24
|
||||
Edge 7 -> 26
|
||||
Edge 7 -> 27
|
||||
Edge 7 -> 32
|
||||
Edge 7 -> 33
|
||||
Edge 7 -> 34
|
||||
Edge 7 -> 35
|
||||
Edge 7 -> 37
|
||||
Edge 7 -> 38
|
||||
Edge 8 -> 10
|
||||
Edge 8 -> 12
|
||||
Edge 8 -> 13
|
||||
Edge 8 -> 14
|
||||
Edge 8 -> 15
|
||||
Edge 8 -> 17
|
||||
Edge 8 -> 18
|
||||
Edge 8 -> 19
|
||||
Edge 8 -> 20
|
||||
Edge 8 -> 21
|
||||
Edge 8 -> 23
|
||||
Edge 8 -> 25
|
||||
Edge 8 -> 27
|
||||
Edge 8 -> 30
|
||||
Edge 8 -> 31
|
||||
Edge 8 -> 35
|
||||
Edge 8 -> 37
|
||||
Edge 8 -> 38
|
||||
Edge 9 -> 10
|
||||
Edge 9 -> 11
|
||||
Edge 9 -> 13
|
||||
Edge 9 -> 14
|
||||
Edge 9 -> 15
|
||||
Edge 9 -> 16
|
||||
Edge 9 -> 17
|
||||
Edge 9 -> 19
|
||||
Edge 9 -> 20
|
||||
Edge 9 -> 21
|
||||
Edge 9 -> 24
|
||||
Edge 9 -> 25
|
||||
Edge 9 -> 26
|
||||
Edge 9 -> 27
|
||||
Edge 9 -> 29
|
||||
Edge 9 -> 31
|
||||
Edge 9 -> 33
|
||||
Edge 9 -> 34
|
||||
Edge 9 -> 37
|
||||
Edge 9 -> 39
|
||||
Edge 10 -> 11
|
||||
Edge 10 -> 12
|
||||
Edge 10 -> 15
|
||||
Edge 10 -> 16
|
||||
Edge 10 -> 17
|
||||
Edge 10 -> 18
|
||||
Edge 10 -> 19
|
||||
Edge 10 -> 20
|
||||
Edge 10 -> 21
|
||||
Edge 10 -> 22
|
||||
Edge 10 -> 24
|
||||
Edge 10 -> 25
|
||||
Edge 10 -> 28
|
||||
Edge 10 -> 29
|
||||
Edge 10 -> 32
|
||||
Edge 10 -> 33
|
||||
Edge 10 -> 34
|
||||
Edge 10 -> 35
|
||||
Edge 10 -> 38
|
||||
Edge 11 -> 12
|
||||
Edge 11 -> 13
|
||||
Edge 11 -> 15
|
||||
Edge 11 -> 16
|
||||
Edge 11 -> 20
|
||||
Edge 11 -> 21
|
||||
Edge 11 -> 22
|
||||
Edge 11 -> 24
|
||||
Edge 11 -> 25
|
||||
Edge 11 -> 27
|
||||
Edge 11 -> 28
|
||||
Edge 11 -> 30
|
||||
Edge 11 -> 31
|
||||
Edge 11 -> 32
|
||||
Edge 11 -> 35
|
||||
Edge 11 -> 36
|
||||
Edge 11 -> 38
|
||||
Edge 11 -> 39
|
||||
Edge 12 -> 13
|
||||
Edge 12 -> 14
|
||||
Edge 12 -> 15
|
||||
Edge 12 -> 16
|
||||
Edge 12 -> 18
|
||||
Edge 12 -> 19
|
||||
Edge 12 -> 20
|
||||
Edge 12 -> 21
|
||||
Edge 12 -> 24
|
||||
Edge 12 -> 25
|
||||
Edge 12 -> 29
|
||||
Edge 12 -> 31
|
||||
Edge 12 -> 32
|
||||
Edge 12 -> 33
|
||||
Edge 12 -> 34
|
||||
Edge 12 -> 35
|
||||
Edge 12 -> 36
|
||||
Edge 12 -> 37
|
||||
Edge 12 -> 38
|
||||
Edge 12 -> 39
|
||||
Edge 13 -> 14
|
||||
Edge 13 -> 15
|
||||
Edge 13 -> 16
|
||||
Edge 13 -> 17
|
||||
Edge 13 -> 18
|
||||
Edge 13 -> 21
|
||||
Edge 13 -> 22
|
||||
Edge 13 -> 24
|
||||
Edge 13 -> 27
|
||||
Edge 13 -> 31
|
||||
Edge 13 -> 32
|
||||
Edge 13 -> 34
|
||||
Edge 13 -> 35
|
||||
Edge 13 -> 38
|
||||
Edge 14 -> 15
|
||||
Edge 14 -> 16
|
||||
Edge 14 -> 17
|
||||
Edge 14 -> 19
|
||||
Edge 14 -> 21
|
||||
Edge 14 -> 22
|
||||
Edge 14 -> 23
|
||||
Edge 14 -> 24
|
||||
Edge 14 -> 25
|
||||
Edge 14 -> 30
|
||||
Edge 14 -> 31
|
||||
Edge 14 -> 32
|
||||
Edge 14 -> 33
|
||||
Edge 14 -> 34
|
||||
Edge 14 -> 35
|
||||
Edge 14 -> 37
|
||||
Edge 14 -> 39
|
||||
Edge 15 -> 16
|
||||
Edge 15 -> 17
|
||||
Edge 15 -> 19
|
||||
Edge 15 -> 21
|
||||
Edge 15 -> 23
|
||||
Edge 15 -> 24
|
||||
Edge 15 -> 25
|
||||
Edge 15 -> 27
|
||||
Edge 15 -> 28
|
||||
Edge 15 -> 29
|
||||
Edge 15 -> 30
|
||||
Edge 15 -> 36
|
||||
Edge 15 -> 37
|
||||
Edge 15 -> 38
|
||||
Edge 15 -> 39
|
||||
Edge 16 -> 17
|
||||
Edge 16 -> 18
|
||||
Edge 16 -> 19
|
||||
Edge 16 -> 20
|
||||
Edge 16 -> 22
|
||||
Edge 16 -> 23
|
||||
Edge 16 -> 24
|
||||
Edge 16 -> 27
|
||||
Edge 16 -> 28
|
||||
Edge 16 -> 29
|
||||
Edge 16 -> 31
|
||||
Edge 16 -> 32
|
||||
Edge 16 -> 33
|
||||
Edge 16 -> 35
|
||||
Edge 16 -> 38
|
||||
Edge 17 -> 18
|
||||
Edge 17 -> 19
|
||||
Edge 17 -> 21
|
||||
Edge 17 -> 23
|
||||
Edge 17 -> 25
|
||||
Edge 17 -> 27
|
||||
Edge 17 -> 28
|
||||
Edge 17 -> 29
|
||||
Edge 17 -> 31
|
||||
Edge 17 -> 32
|
||||
Edge 17 -> 33
|
||||
Edge 17 -> 36
|
||||
Edge 17 -> 37
|
||||
Edge 17 -> 38
|
||||
Edge 17 -> 39
|
||||
Edge 18 -> 19
|
||||
Edge 18 -> 20
|
||||
Edge 18 -> 21
|
||||
Edge 18 -> 22
|
||||
Edge 18 -> 23
|
||||
Edge 18 -> 25
|
||||
Edge 18 -> 26
|
||||
Edge 18 -> 27
|
||||
Edge 18 -> 28
|
||||
Edge 18 -> 29
|
||||
Edge 18 -> 33
|
||||
Edge 18 -> 35
|
||||
Edge 18 -> 36
|
||||
Edge 18 -> 37
|
||||
Edge 18 -> 38
|
||||
Edge 18 -> 39
|
||||
Edge 19 -> 20
|
||||
Edge 19 -> 21
|
||||
Edge 19 -> 22
|
||||
Edge 19 -> 23
|
||||
Edge 19 -> 26
|
||||
Edge 19 -> 27
|
||||
Edge 19 -> 29
|
||||
Edge 19 -> 32
|
||||
Edge 19 -> 34
|
||||
Edge 19 -> 35
|
||||
Edge 19 -> 36
|
||||
Edge 19 -> 37
|
||||
Edge 19 -> 38
|
||||
Edge 19 -> 39
|
||||
Edge 20 -> 21
|
||||
Edge 20 -> 23
|
||||
Edge 20 -> 24
|
||||
Edge 20 -> 25
|
||||
Edge 20 -> 26
|
||||
Edge 20 -> 28
|
||||
Edge 20 -> 29
|
||||
Edge 20 -> 31
|
||||
Edge 20 -> 32
|
||||
Edge 20 -> 37
|
||||
Edge 20 -> 39
|
||||
Edge 21 -> 22
|
||||
Edge 21 -> 23
|
||||
Edge 21 -> 25
|
||||
Edge 21 -> 27
|
||||
Edge 21 -> 29
|
||||
Edge 21 -> 31
|
||||
Edge 21 -> 32
|
||||
Edge 21 -> 33
|
||||
Edge 21 -> 35
|
||||
Edge 21 -> 36
|
||||
Edge 21 -> 38
|
||||
Edge 21 -> 39
|
||||
Edge 22 -> 23
|
||||
Edge 22 -> 24
|
||||
Edge 22 -> 26
|
||||
Edge 22 -> 28
|
||||
Edge 22 -> 29
|
||||
Edge 22 -> 34
|
||||
Edge 22 -> 37
|
||||
Edge 22 -> 38
|
||||
Edge 22 -> 39
|
||||
Edge 23 -> 26
|
||||
Edge 23 -> 27
|
||||
Edge 23 -> 30
|
||||
Edge 23 -> 32
|
||||
Edge 23 -> 33
|
||||
Edge 23 -> 34
|
||||
Edge 23 -> 37
|
||||
Edge 23 -> 38
|
||||
Edge 24 -> 28
|
||||
Edge 24 -> 31
|
||||
Edge 24 -> 33
|
||||
Edge 24 -> 36
|
||||
Edge 24 -> 37
|
||||
Edge 24 -> 38
|
||||
Edge 24 -> 39
|
||||
Edge 25 -> 26
|
||||
Edge 25 -> 27
|
||||
Edge 25 -> 30
|
||||
Edge 25 -> 33
|
||||
Edge 25 -> 34
|
||||
Edge 25 -> 36
|
||||
Edge 25 -> 37
|
||||
Edge 25 -> 38
|
||||
Edge 25 -> 39
|
||||
Edge 26 -> 27
|
||||
Edge 26 -> 28
|
||||
Edge 26 -> 29
|
||||
Edge 26 -> 30
|
||||
Edge 26 -> 32
|
||||
Edge 26 -> 34
|
||||
Edge 26 -> 35
|
||||
Edge 26 -> 36
|
||||
Edge 26 -> 37
|
||||
Edge 26 -> 38
|
||||
Edge 27 -> 29
|
||||
Edge 27 -> 30
|
||||
Edge 27 -> 31
|
||||
Edge 27 -> 35
|
||||
Edge 27 -> 36
|
||||
Edge 27 -> 37
|
||||
Edge 27 -> 39
|
||||
Edge 28 -> 29
|
||||
Edge 28 -> 31
|
||||
Edge 28 -> 33
|
||||
Edge 28 -> 35
|
||||
Edge 28 -> 38
|
||||
Edge 29 -> 30
|
||||
Edge 29 -> 34
|
||||
Edge 29 -> 35
|
||||
Edge 29 -> 37
|
||||
Edge 29 -> 39
|
||||
Edge 30 -> 31
|
||||
Edge 30 -> 32
|
||||
Edge 30 -> 34
|
||||
Edge 30 -> 36
|
||||
Edge 30 -> 37
|
||||
Edge 30 -> 38
|
||||
Edge 31 -> 32
|
||||
Edge 31 -> 33
|
||||
Edge 31 -> 34
|
||||
Edge 31 -> 35
|
||||
Edge 31 -> 39
|
||||
Edge 32 -> 33
|
||||
Edge 32 -> 35
|
||||
Edge 32 -> 36
|
||||
Edge 32 -> 37
|
||||
Edge 32 -> 38
|
||||
Edge 32 -> 39
|
||||
Edge 33 -> 34
|
||||
Edge 33 -> 35
|
||||
Edge 34 -> 36
|
||||
Edge 34 -> 37
|
||||
Edge 34 -> 38
|
||||
Edge 34 -> 39
|
||||
Edge 35 -> 36
|
||||
Edge 35 -> 37
|
||||
Edge 35 -> 38
|
||||
Edge 36 -> 38
|
||||
Edge 37 -> 38
|
||||
Edge 37 -> 39
|
||||
Random groups:
|
||||
Group 0: 0 23
|
||||
Group 1: 10 29
|
||||
Group 2: 16 25
|
||||
Group 3: 30 31
|
||||
Group 4: 5 18
|
||||
Group 5: 20 27
|
||||
Group 6: 1 15
|
||||
Group 7: 2 22
|
||||
Group 8: 11 16
|
||||
Group 9: 0 8
|
17
include/rand_large.h
Normal file
17
include/rand_large.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef RAND_R_LARGE_H
|
||||
#define RAND_R_LARGE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/**
|
||||
* Generates a large random number by combining two `rand_r` calls.
|
||||
*
|
||||
* @param seed A pointer to an unsigned 16-bit seed used for the random number generator.
|
||||
* The seed is updated after each call to maintain the sequence.
|
||||
*
|
||||
* @return A 64-bit unsigned random number.
|
||||
*/
|
||||
uint64_t rand_r_large(uint16_t* seed);
|
||||
|
||||
#endif // RAND_R_LARGE_H
|
14
include/random_edge_weight.h
Normal file
14
include/random_edge_weight.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef GEOMETRY_WEIGHTS_H
|
||||
#define GEOMETRY_WEIGHTS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Function to embed vertices into 2D space
|
||||
void embed_vertices(int N, float B, float *x, float *y, uint16_t* seed);
|
||||
|
||||
// Function to generate random edge weight
|
||||
float generate_random_edge_weight(float *x, float *y, unsigned int N, unsigned int s, unsigned int t,
|
||||
float a, float b, const char *family, const char *type, uint16_t* seed);
|
||||
|
||||
#endif // GEOMETRY_WEIGHTS_H
|
@ -4,20 +4,22 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include "rand_large.h"
|
||||
|
||||
// Edge structure
|
||||
typedef struct Edge {
|
||||
int src;
|
||||
int dest;
|
||||
uint32_t src;
|
||||
uint32_t dest;
|
||||
} Edge;
|
||||
|
||||
// Function prototypes
|
||||
int cmpInt(const void *a, const void *b);
|
||||
unsigned int uv2index(unsigned int u, unsigned int v, unsigned int n);
|
||||
unsigned int min(unsigned int u, unsigned int v);
|
||||
unsigned int max(unsigned int u, unsigned int v);
|
||||
int index2uv(unsigned int index, unsigned int n, int *u, int *v);
|
||||
void random_spanning_tree(
|
||||
unsigned int n, unsigned int m, unsigned int seed, Edge *edges);
|
||||
uint64_t uv2index(uint32_t u, uint32_t v, uint32_t n);
|
||||
uint32_t min(uint32_t u, uint32_t v);
|
||||
uint32_t max(uint32_t u, uint32_t v);
|
||||
int8_t index2uv(uint64_t index, uint32_t n, uint32_t *u, uint32_t *v);
|
||||
void random_connected_graph(
|
||||
uint32_t n, uint64_t m, Edge *edges, uint16_t* seed);
|
||||
|
||||
#endif // RANDOM_GRAPH_H
|
||||
|
13
include/random_group_steiner.h
Normal file
13
include/random_group_steiner.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef RANDOM_GROUP_STEINER_H
|
||||
#define RANDOM_GROUP_STEINER_H
|
||||
|
||||
#include "random_groups.h"
|
||||
#include "random_graph.h"
|
||||
|
||||
// Function to generate a random Group Steiner instance
|
||||
void generate_random_group_steiner_instance(
|
||||
uint32_t n, uint32_t m, uint16_t k, const char *filename,
|
||||
float vertex_a, float vertex_b, const char *vertex_weight_type,
|
||||
float edge_a, float edge_b, const char *edge_weight_family, const char *edge_weight_type, const char *instance_type, uint16_t* seed);
|
||||
|
||||
#endif // RANDOM_GROUP_STEINER_H
|
@ -3,14 +3,16 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Struct for representing groups
|
||||
typedef struct {
|
||||
unsigned int *group; // Pointer to an array of group members
|
||||
unsigned int size; // Number of members in the group
|
||||
uint32_t *group; // Pointer to an array of group members
|
||||
uint32_t size; // Number of members in the group
|
||||
} Group;
|
||||
|
||||
// Function to generate random groups
|
||||
void generate_random_groups(unsigned int n, unsigned int k, Group **groups);
|
||||
void shuffle(uint32_t *array, uint32_t size, uint16_t* seed);
|
||||
void generate_random_groups(uint32_t n, uint16_t k, Group *groups, uint16_t* seed);
|
||||
|
||||
#endif // RANDOM_GROUPS_H
|
||||
|
12
include/random_vertex_weight.h
Normal file
12
include/random_vertex_weight.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef RANDOM_VERTEX_WEIGHT_H
|
||||
#define RANDOM_VERTEX_WEIGHT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Function to generate a random vertex weight
|
||||
float generate_random_vertex_weight(const char *weight_type, float a, float b, uint16_t* seed);
|
||||
|
||||
#endif // RANDOM_VERTEX_WEIGHT_H
|
0
random_instance.stp
Normal file
0
random_instance.stp
Normal file
49
src/main.c
49
src/main.c
@ -1,38 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "random_graph.h"
|
||||
#include "random_groups.h"
|
||||
#include "random_group_steiner.h"
|
||||
|
||||
int main() {
|
||||
unsigned int n = 20, m = 80, k = 4, seed = 5;
|
||||
Edge *edges = malloc(m * sizeof(Edge));
|
||||
if (!edges) {
|
||||
fprintf(stderr, "Error: Memory allocation of EDGE array: edges FAILED.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
random_spanning_tree(n, m, seed, edges);
|
||||
|
||||
printf("Generated graph edges:\n");
|
||||
for (unsigned int i = 0; i < m; i++) {
|
||||
printf("Edge %d -> %d\n", edges[i].src, edges[i].dest);
|
||||
}
|
||||
uint32_t n = 90000; // Number of vertices
|
||||
uint64_t m = 1000000; // Number of edges
|
||||
uint16_t k = 2000; // Number of groups
|
||||
uint16_t seed = 12345;
|
||||
|
||||
|
||||
Group *groups;
|
||||
generate_random_groups(n, k, &groups);
|
||||
|
||||
// Print groups
|
||||
printf("Random groups:\n");
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
printf("Group %u: ", i);
|
||||
for (unsigned int j = 0; j < groups[i].size; j++) {
|
||||
printf("%u ", groups[i].group[j]);
|
||||
}
|
||||
printf("\n");
|
||||
free(groups[i].group); // Free each group's array
|
||||
}
|
||||
free(groups); // Free the groups array
|
||||
free(edges);
|
||||
const char *filename = "random_instance.stp";
|
||||
float vertex_a = 1.0, vertex_b = 10.0;
|
||||
const char *vertex_weight_type = "float";
|
||||
float edge_a = 1.0, edge_b = 10.0;
|
||||
const char *edge_weight_family = "random";
|
||||
const char *edge_weight_type = "float";
|
||||
const char *instance_type = "Node Weighted Group Steiner Tree Instance";
|
||||
|
||||
generate_random_group_steiner_instance(
|
||||
n, m, k, filename,
|
||||
vertex_a, vertex_b, vertex_weight_type,
|
||||
edge_a, edge_b, edge_weight_family, edge_weight_type, instance_type, &seed);
|
||||
|
||||
printf("Random Group Steiner instance written to %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
12
src/rand_large.c
Normal file
12
src/rand_large.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "rand_large.h"
|
||||
|
||||
/**
|
||||
* Generates a large random number by combining two `rand_r` calls.
|
||||
*/
|
||||
uint64_t rand_r_large(uint16_t* seed) {
|
||||
// Combine two `rand_r` calls for a larger range
|
||||
uint64_t large_random = ((uint64_t)rand_r((unsigned int* )seed) << 31) | rand_r((unsigned int* )seed);
|
||||
return large_random;
|
||||
}
|
49
src/random_edge_weight.c
Normal file
49
src/random_edge_weight.c
Normal file
@ -0,0 +1,49 @@
|
||||
#include "random_edge_weight.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Embed vertices into 2D space with random coordinates between 0 and B
|
||||
void embed_vertices(int N, float B, float *x, float *y, uint16_t* seed) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
x[i] = ((float)rand_r((unsigned int* )seed) / RAND_MAX) * B;
|
||||
y[i] = ((float)rand_r((unsigned int* )seed) / RAND_MAX) * B;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate random edge weight based on the given weight type
|
||||
float generate_random_edge_weight(float *x, float *y, unsigned int N, unsigned int s, unsigned int t,
|
||||
float a, float b, const char *family, const char *type, uint16_t* seed) {
|
||||
if (s >= N || t >= N) {
|
||||
fprintf(stderr, "Error: Vertex indices s (%u) or t (%u) exceed the number of vertices (%d).\n", s, t, N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
float weight = 1.0;
|
||||
|
||||
if (strcmp(family, "euclid") == 0) {
|
||||
// Euclidean distance
|
||||
float dx = x[s] - x[t];
|
||||
float dy = y[s] - y[t];
|
||||
weight += sqrt(dx * dx + dy * dy);
|
||||
} else if (strcmp(family, "grid") == 0) {
|
||||
// Manhattan distance
|
||||
weight += fabs(x[s] - x[t]) + fabs(y[s] - y[t]);
|
||||
} else if (strcmp(family, "random") == 0) {
|
||||
// Uniform random weight
|
||||
weight += a + ((float)rand_r((unsigned int* )seed) / RAND_MAX) * (b - a);
|
||||
} else {
|
||||
fprintf(stderr, "Error: Invalid weight type '%s'. Use 'euclid', 'grid', or 'random'.\n", family);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Cast to integer if the type is "int"
|
||||
if (strcmp(type, "int") == 0) {
|
||||
weight = (float)((int)weight);
|
||||
} else if (strcmp(type, "float") != 0) {
|
||||
fprintf(stderr, "Error: Invalid type '%s'. Use 'int' or 'float'.\n", type);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return weight;
|
||||
}
|
@ -1,50 +1,60 @@
|
||||
#include "random_graph.h"
|
||||
|
||||
|
||||
int cmpInt(const void *a, const void *b) {
|
||||
return (*(unsigned int *)a - *(unsigned int *)b);
|
||||
int64_t int_a = *(int64_t *)a;
|
||||
int64_t int_b = *(int64_t *)b;
|
||||
|
||||
// Return the difference (int_a - int_b)
|
||||
return (int) ((int_a > int_b) - (int_a < int_b)); // Returns -1, 0, or 1
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int min(unsigned int u, unsigned int v){
|
||||
inline uint32_t min(uint32_t u, uint32_t v){
|
||||
return u < v ? u : v;
|
||||
}
|
||||
|
||||
inline unsigned int max(unsigned int u, unsigned int v){
|
||||
inline uint32_t max(uint32_t u, uint32_t v){
|
||||
return u < v ? v : u;
|
||||
}
|
||||
|
||||
unsigned int uv2index(unsigned int u, unsigned int v, unsigned int n) {
|
||||
uint64_t uv2index(uint32_t u, uint32_t v, uint32_t n) {
|
||||
if (u < n && v < n && u < v) {
|
||||
unsigned int index = (u * (2*n - u - 1) / 2) + (v - u - 1);
|
||||
if (index < (n * (n - 1)) / 2) {
|
||||
return index;
|
||||
uint64_t uu = (uint64_t)(u);
|
||||
uint64_t vv = (uint64_t)(v);
|
||||
uint64_t nn = (uint64_t)(n);
|
||||
uint64_t mmax = (nn * (nn - 1)) / 2;
|
||||
uint64_t index = (uu * (2*nn - uu - 1))/2 + (vv - uu - 1);
|
||||
if (index < mmax) {
|
||||
return (uint64_t)index;
|
||||
} else {
|
||||
fprintf(stderr, "Error: Formula should be checked for index calculation.\n");
|
||||
return (unsigned int)-1;
|
||||
return (uint64_t)(-1);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Error: Invalid u or v values.\n");
|
||||
return (unsigned int)(-1);
|
||||
return (uint64_t)(-1);
|
||||
}
|
||||
|
||||
int index2uv(unsigned int index, unsigned int n, int *u, int *v) {
|
||||
int8_t index2uv(uint64_t index, uint32_t n, uint32_t *u, uint32_t *v) {
|
||||
if (index < (n * (n - 1)) / 2) {
|
||||
long long nn = (long long)n;
|
||||
long long indexx = (long long)index;
|
||||
long long dd = (2 * nn - 1) * (2 * nn - 1) - 8 * indexx;
|
||||
double uur = ((double)(2 * n - 1) - sqrt(dd)) / 2;
|
||||
long long uu = ((double)(2 * n - 1) - sqrt(dd)) / 2;
|
||||
long long vv = uu + index + 1 - uu * (2*n - uu - 1) / 2;
|
||||
int64_t nn = (int64_t)n;
|
||||
int64_t indexx = (int64_t)index;
|
||||
int64_t dd = (2 * nn - 1) * (2 * nn - 1) - 8 * indexx;
|
||||
// double uur = ((double)(2 * n - 1) - sqrt(dd)) / 2;
|
||||
int64_t uu = ((double)(2 * n - 1) - sqrt(dd)) / 2;
|
||||
int64_t vv = uu + index + 1 - uu * (2*n - uu - 1) / 2;
|
||||
if (uu >= 0 && uu < n && vv >= uu + 1 && vv < n) {
|
||||
*u = (unsigned int)uu;
|
||||
*v = (unsigned int)vv;
|
||||
*u = (uint32_t)uu;
|
||||
*v = (uint32_t)vv;
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
printf("n: %lld\n", nn);
|
||||
printf("index: %lld\n", indexx);
|
||||
printf("D: %lld\n", dd);
|
||||
printf("u: %.10f\n", uur);
|
||||
fprintf(stderr, "Error: Invalid calculated u or v values. Index: %d, u = %lld, v=%lld\n", index, uu, vv);
|
||||
// printf("n: %lu\n", nn);
|
||||
// printf("index: %lu\n", indexx);
|
||||
// printf("D: %d\n", dd);
|
||||
// printf("u: %.10f\n", uur);
|
||||
// fprintf(stderr, "Error: Invalid calculated u or v values. Index: %d, u = %d, v=%d\n", index, uu, vv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -52,83 +62,96 @@ int index2uv(unsigned int index, unsigned int n, int *u, int *v) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void random_spanning_tree(
|
||||
unsigned int n, unsigned int m, unsigned int seed, Edge *edges) {
|
||||
void random_connected_graph(
|
||||
uint32_t n, uint64_t m, Edge *edges, uint16_t* seed) {
|
||||
|
||||
if (m > n * (n - 1) / 2) {
|
||||
fprintf(stderr, "Error: Number of edges exceeds the maximum possible for %u vertices.\n", n);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
unsigned int mmax = n * (n - 1) / 2; // Maximum possible number of edges
|
||||
unsigned int *N = malloc(n * sizeof(unsigned int)); // Vertices array
|
||||
unsigned int *M = malloc(mmax * sizeof(unsigned int)); // All edge indices
|
||||
unsigned int *T = malloc(m * sizeof(unsigned int)); // Selected edges for the graph
|
||||
uint64_t mmax = (uint64_t)n * ((uint64_t)n - 1) / 2; // Maximum possible number of edges
|
||||
uint32_t *N = malloc(n * sizeof(uint32_t)); // Vertices array
|
||||
uint64_t *M = malloc(mmax * sizeof(uint64_t)); // All edge indices
|
||||
uint64_t *T = malloc(m * sizeof(uint64_t)); // Selected edges for the graph
|
||||
if (!N || !M || !T) {
|
||||
fprintf(stderr, "Error: Memory allocation failed.\n");
|
||||
free(N); free(M); free(T);
|
||||
exit(EXIT_FAILURE);
|
||||
fprintf(stderr, "Error: Memory allocation of arrays N, M or T failed.\n");
|
||||
free(T);
|
||||
free(M);
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Initialize vertex and edge index arrays
|
||||
for (unsigned int i = 0; i < n; i++) N[i] = i;
|
||||
for (unsigned int i = 0; i < mmax; i++) M[i] = i;
|
||||
for (uint32_t i = 0; i < n; i++) N[i] = i;
|
||||
for (uint64_t i = 0; i < mmax; i++) M[i] = i;
|
||||
|
||||
// Seed random number generator and shuffle vertices
|
||||
srand(seed);
|
||||
for (unsigned int i = n - 1; i > 0; i--) {
|
||||
unsigned int j = rand() % (i + 1);
|
||||
unsigned int temp = N[i];
|
||||
for (uint32_t i = n - 1; i > 0; i--) {
|
||||
uint32_t j = rand_r_large(seed) % (i + 1);
|
||||
uint32_t temp = N[i];
|
||||
N[i] = N[j];
|
||||
N[j] = temp;
|
||||
}
|
||||
|
||||
// Build spanning tree by randomly selecting edges
|
||||
for (unsigned int v = 1; v < n; v++) {
|
||||
unsigned int u = rand() % v;
|
||||
unsigned int index = uv2index(min(N[u],N[v]), max(N[u],N[v]), n);
|
||||
if (index == (unsigned int)-1) {
|
||||
free(N); free(M); free(T);
|
||||
for (uint32_t v = 1; v < n; v++) {
|
||||
uint32_t u = rand_r_large(seed) % v;
|
||||
uint64_t index = uv2index(min(N[u],N[v]), max(N[u],N[v]), n);
|
||||
if (index == (uint64_t)(-1)) {
|
||||
free(T);
|
||||
free(M);
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (index >= mmax){
|
||||
fprintf(stderr, "u = %u; v = %u", u, v);
|
||||
fprintf(stderr, "index = %lu; mmax = %lu", index, mmax);
|
||||
}
|
||||
T[v - 1] = index; // Add edge index to T
|
||||
}
|
||||
|
||||
// Sort the initial edges of the spanning tree
|
||||
qsort(T, n - 1, sizeof(unsigned int), cmpInt);
|
||||
qsort(T, n - 1, sizeof(uint64_t), cmpInt);
|
||||
|
||||
// put all selected edges back to the array (last n-1 elements of M)
|
||||
for (int i = n-2; i >= 0; i--) {
|
||||
unsigned int temp = M[mmax - 1 - n + 2 + i];
|
||||
for (int64_t i = n-2; i >= 0; i--) {
|
||||
if (T[i] > mmax){
|
||||
fprintf(stderr, "T[i] = %lu; mmax = %lu", T[i], mmax);
|
||||
|
||||
}
|
||||
uint32_t temp = M[mmax - 1 - n + 2 + i];
|
||||
M[mmax - 1 - n + 2 + i] = M[T[i]];
|
||||
M[T[i]] = temp;
|
||||
}
|
||||
|
||||
|
||||
// Randomly shuffle remaining edges in M[0,...,mmax - n]
|
||||
for (unsigned int i = mmax - n; i > 0; i--) {
|
||||
unsigned int j = rand() % (i + 1);
|
||||
unsigned int temp = M[i];
|
||||
for (int64_t i = mmax - n; i > 0; i--) {
|
||||
uint32_t j = rand_r_large(seed) % (i + 1);
|
||||
uint32_t temp = M[i];
|
||||
M[i] = M[j];
|
||||
M[j] = temp;
|
||||
}
|
||||
|
||||
// Select the first m - n + 1 additional edges
|
||||
for (unsigned int i = 0; i < m - n + 1; i++) {
|
||||
for (uint64_t i = 0; i < m - n + 1; i++) {
|
||||
T[n - 1 + i] = M[i];
|
||||
}
|
||||
|
||||
// Sort the entire T array
|
||||
qsort(T, m, sizeof(unsigned int), cmpInt);
|
||||
qsort(T, m, sizeof(uint64_t), cmpInt);
|
||||
|
||||
// Convert indices to edges and create the edge array
|
||||
|
||||
unsigned int check = m;
|
||||
for (unsigned int i = 0; i < m; i++) {
|
||||
int u, v;
|
||||
uint64_t check = m;
|
||||
for (uint64_t i = 0; i < m; i++) {
|
||||
uint32_t u, v;
|
||||
|
||||
if (index2uv(T[i], n, &u, &v) == -1) {
|
||||
free(N); free(M); free(T); free(edges);
|
||||
free(T);
|
||||
free(M);
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (T[i] == check){
|
||||
@ -144,7 +167,7 @@ void random_spanning_tree(
|
||||
// Output edges
|
||||
|
||||
// Cleanup
|
||||
free(N);
|
||||
free(M);
|
||||
free(T);
|
||||
free(M);
|
||||
free(N);
|
||||
}
|
||||
|
131
src/random_group_steiner.c
Normal file
131
src/random_group_steiner.c
Normal file
@ -0,0 +1,131 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "random_graph.h"
|
||||
#include "random_groups.h"
|
||||
#include "random_edge_weight.h"
|
||||
#include "random_vertex_weight.h"
|
||||
|
||||
void generate_random_group_steiner_instance(
|
||||
uint32_t n, uint32_t m, uint16_t k, const char *filename,
|
||||
float vertex_a, float vertex_b, const char *vertex_weight_type,
|
||||
float edge_a, float edge_b, const char *edge_weight_family, const char *edge_weight_type, const char *instance_type, uint16_t* seed) {
|
||||
|
||||
// Open file for writing
|
||||
FILE *file = fopen(filename, "w");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Error: Could not open file %s for writing.\n", filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Generate a random connected graph
|
||||
Edge *edges = (Edge *)malloc(m * sizeof(Edge));
|
||||
if (!edges) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for edges.\n");
|
||||
fclose(file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
// uint64_t mmax = (uint64_t)(n * (n - 1) / 2);
|
||||
random_connected_graph(n, m, edges, seed);
|
||||
|
||||
// Embed vertices into 2D space for geometry-based edge weights
|
||||
float *x = (float *)malloc(n * sizeof(float));
|
||||
if (!x) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for array x.\n");
|
||||
free(edges);
|
||||
fclose(file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
float *y = (float *)malloc(n * sizeof(float));
|
||||
if (!y) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for array y.\n");
|
||||
free(x);
|
||||
free(edges);
|
||||
fclose(file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
embed_vertices(n, 100.0, x, y, seed); // Embedding vertices into [0, 100] space
|
||||
|
||||
|
||||
// Allocate memory for groups
|
||||
Group *groups = (Group *)malloc(k * sizeof(Group));
|
||||
if (!groups) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for groups.\n");
|
||||
free(y);
|
||||
free(x);
|
||||
free(edges);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
groups[i].group = (uint32_t *)malloc(n * sizeof(uint32_t));
|
||||
groups[i].size = 0;
|
||||
if (!groups[i].group) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for group %u.\n", i);
|
||||
for (unsigned int j = 0; j < i; j++) {
|
||||
free(groups[j].group);
|
||||
}
|
||||
free(groups);
|
||||
free(y);
|
||||
free(x);
|
||||
free(edges);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
// Generate random groups
|
||||
generate_random_groups(n, k, groups, seed);
|
||||
|
||||
// Write the .stp file header
|
||||
fprintf(file, "0 string 33D32945 STP Steiner Tree Problem File\n");
|
||||
fprintf(file, "SECTION Comment\n");
|
||||
fprintf(file, "Name DWW_NWGST_%s_N=%u_M=%u_k=%u\n",edge_weight_family,n,m,k);
|
||||
fprintf(file, "Remark '%s'\n",instance_type);
|
||||
fprintf(file, "END\n\n");
|
||||
|
||||
// Write the graph section
|
||||
fprintf(file, "SECTION Graph\n");
|
||||
fprintf(file, "Nodes %u\n", n);
|
||||
fprintf(file, "Edges %u\n", m);
|
||||
|
||||
// Write vertex weights
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
float vertex_weight = generate_random_vertex_weight(vertex_weight_type, vertex_a, vertex_b, seed);
|
||||
fprintf(file, "N %.1f\n", vertex_weight);
|
||||
}
|
||||
|
||||
// Write edges
|
||||
for (unsigned int i = 0; i < m; i++) {
|
||||
float edge_weight = generate_random_edge_weight(
|
||||
x, y, n, edges[i].src, edges[i].dest, edge_a, edge_b, edge_weight_family, edge_weight_type, seed);
|
||||
fprintf(file, "E %d %d %.2f\n", edges[i].src, edges[i].dest, edge_weight);
|
||||
}
|
||||
fprintf(file, "END\n\n");
|
||||
|
||||
// Write the terminals section
|
||||
fprintf(file, "SECTION Terminals\n");
|
||||
fprintf(file, "Terminals %u\n", k);
|
||||
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
fprintf(file, "T");
|
||||
for (unsigned int j = 0; j < groups[i].size; j++) {
|
||||
fprintf(file, " %u", groups[i].group[j]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
fprintf(file, "END\n\n");
|
||||
|
||||
// Write EOF
|
||||
fprintf(file, "EOF\n");
|
||||
|
||||
// Clean up
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
free(groups[i].group);
|
||||
}
|
||||
free(groups);
|
||||
free(y);
|
||||
free(x);
|
||||
free(edges);
|
||||
fclose(file);
|
||||
}
|
@ -2,86 +2,80 @@
|
||||
#include "random_graph.h"
|
||||
|
||||
// Helper function to shuffle an array
|
||||
void shuffle(unsigned int *array, unsigned int size) {
|
||||
for (unsigned int i = size - 1; i > 0; i--) {
|
||||
unsigned int j = rand() % (i + 1);
|
||||
unsigned int temp = array[i];
|
||||
void shuffle(uint32_t *array, uint32_t size, uint16_t* seed) {
|
||||
for (uint32_t i = size - 1; i > 0; i--) {
|
||||
uint32_t j = rand_r((unsigned int* )seed) % (i + 1);
|
||||
uint32_t temp = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void generate_random_groups(unsigned int n, unsigned int k, Group **groups_out) {
|
||||
void generate_random_groups(uint32_t n, uint16_t k, Group *groups, uint16_t* seed) {
|
||||
if (k > n) {
|
||||
fprintf(stderr, "Error: Number of groups (k) cannot exceed the number of vertices (n).\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Allocate memory for array N (vertices) and initialize
|
||||
unsigned int *N = (unsigned int *)malloc(n * sizeof(unsigned int));
|
||||
uint32_t *N = (uint32_t *)malloc(n * sizeof(uint32_t));
|
||||
if (!N) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for array N.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int i = 0; i < n; i++) {
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
N[i] = i;
|
||||
}
|
||||
|
||||
// Allocate memory for groups
|
||||
Group *groups = (Group *)malloc(k * sizeof(Group));
|
||||
if (!groups) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for groups.\n");
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
groups[i].group = (unsigned int *)malloc(n * sizeof(unsigned int));
|
||||
groups[i].size = 0;
|
||||
if (!groups[i].group) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for group %u.\n", i);
|
||||
for (unsigned int j = 0; j < i; j++) {
|
||||
free(groups[j].group);
|
||||
}
|
||||
free(groups);
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Generate a random float f in the range (0, 0.5)
|
||||
float f;
|
||||
do {
|
||||
f = (float)rand() / RAND_MAX;
|
||||
} while (f <= 0.0 || f >= 0.5);
|
||||
f = (float) ( rand_r((unsigned int* )seed) / 2.0 ) / RAND_MAX;
|
||||
|
||||
unsigned int offset = (unsigned int)(f * n);
|
||||
|
||||
uint32_t offset = (uint32_t)(f * n);
|
||||
|
||||
// Shuffle the array N
|
||||
shuffle(N, n);
|
||||
shuffle(N, n, seed);
|
||||
if (offset + k > n) {
|
||||
fprintf(stderr, "Error: Number of Steiner vertices (%d) plus k (%d) is greather than n (%d). \n", offset, k, n);
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
uint32_t npool = n - offset - k;
|
||||
uint32_t *I = (uint32_t *)malloc( npool* sizeof(uint32_t));
|
||||
if (!I) {
|
||||
fprintf(stderr, "Error: Memory allocation failed for array I.\n");
|
||||
free(N);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (uint32_t i = 0; i < npool; i++) {
|
||||
I[i] = i;
|
||||
}
|
||||
|
||||
// Distribute elements to the first part of each group
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
for (uint32_t i = 0; i < k; i++) {
|
||||
groups[i].group[groups[i].size++] = N[offset + i];
|
||||
}
|
||||
|
||||
// Distribute remaining elements to groups
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
unsigned int start = offset + k;
|
||||
unsigned int end = offset + k + (n - offset) / k - 1;
|
||||
shuffle(N + start, end - start + 1);
|
||||
|
||||
for (unsigned int j = start; j <= end; j++) {
|
||||
groups[i].group[groups[i].size++] = N[j];
|
||||
uint32_t total = (n - offset) / k - 1;
|
||||
for (uint32_t i = 0; i < k; i++) {
|
||||
|
||||
shuffle(I,npool,seed);
|
||||
for (uint32_t j = 0; j < total; j++) {
|
||||
groups[i].group[groups[i].size++] = N[offset + k + I[j]];
|
||||
}
|
||||
}
|
||||
|
||||
// Sort each group
|
||||
for (unsigned int i = 0; i < k; i++) {
|
||||
qsort(groups[i].group, groups[i].size, sizeof(unsigned int), cmpInt);
|
||||
for (uint32_t i = 0; i < k; i++) {
|
||||
qsort(groups[i].group, groups[i].size, sizeof(uint32_t), cmpInt);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
free(I);
|
||||
free(N);
|
||||
*groups_out = groups;
|
||||
}
|
||||
|
20
src/random_vertex_weight.c
Normal file
20
src/random_vertex_weight.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include "random_vertex_weight.h"
|
||||
#include <stdio.h>
|
||||
|
||||
float generate_random_vertex_weight(const char *weight_type, float a, float b, uint16_t* seed) {
|
||||
if (a > b) {
|
||||
fprintf(stderr, "Error: Lower bound 'a' cannot be greater than upper bound 'b'.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
float random_value = 1 + a + ((float)rand_r((unsigned int* )seed) / RAND_MAX) * (b - a);
|
||||
|
||||
// Check the weight type and cast appropriately
|
||||
if (strcmp(weight_type, "integer") == 0) {
|
||||
return (float)((int)random_value);
|
||||
} else if (strcmp(weight_type, "float") == 0) {
|
||||
return random_value;
|
||||
} else {
|
||||
fprintf(stderr, "Error: Invalid weight type '%s'. Use 'integer' or 'float'.\n", weight_type);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user