Added avl height benchmark
This commit is contained in:
+1
-2
@@ -44,8 +44,7 @@ def plot(program_name, sequences, array_size):
|
|||||||
plt.savefig(f"./benchmarks/{program_name}.png")
|
plt.savefig(f"./benchmarks/{program_name}.png")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# program_names = ["insertion", "selection", "heapsort", "mergesort"]
|
program_names = ["insertion", "selection", "heapsort", "mergesort"]
|
||||||
program_names = ["heapsort"]
|
|
||||||
sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"]
|
sequence_types = ["random", "sorted", "reversed", "constant", "v_shaped"]
|
||||||
array_sizes = [i for i in range(1000, 15001, 1000)]
|
array_sizes = [i for i in range(1000, 15001, 1000)]
|
||||||
tests = 10
|
tests = 10
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
5
|
|
||||||
12
|
|
||||||
65
|
|
||||||
233
|
|
||||||
87
|
|
||||||
23
|
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
benchmark
|
benchmark
|
||||||
results.csv
|
*.csv
|
||||||
charts/
|
charts/
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
Structure,Height
|
||||||
|
2000,10
|
||||||
|
4000,11
|
||||||
|
6000,12
|
||||||
|
8000,12
|
||||||
|
10000,13
|
||||||
|
12000,13
|
||||||
|
14000,13
|
||||||
|
16000,13
|
||||||
|
18000,14
|
||||||
|
20000,14
|
||||||
|
22000,14
|
||||||
|
24000,14
|
||||||
|
26000,14
|
||||||
|
28000,14
|
||||||
|
30000,14
|
||||||
|
32000,14
|
||||||
|
34000,15
|
||||||
|
36000,15
|
||||||
|
38000,15
|
||||||
|
40000,15
|
||||||
|
42000,15
|
||||||
|
44000,15
|
||||||
|
46000,15
|
||||||
|
48000,15
|
||||||
|
50000,15
|
||||||
|
@@ -0,0 +1,86 @@
|
|||||||
|
#include "avl.h"
|
||||||
|
#include "algorithm"
|
||||||
|
|
||||||
|
int getHeight(AVL_tree *root) {
|
||||||
|
if (!root)
|
||||||
|
return 0;
|
||||||
|
return root->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVL_tree *rightRotate(AVL_tree *y) {
|
||||||
|
AVL_tree *x = y->left;
|
||||||
|
AVL_tree *T2 = x->right;
|
||||||
|
|
||||||
|
x->right = y;
|
||||||
|
y->left = T2;
|
||||||
|
|
||||||
|
y->height = 1 + std::max(getHeight(y->left), getHeight(y->right));
|
||||||
|
x->height = 1 + std::max(getHeight(x->left), getHeight(x->right));
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVL_tree *leftRotate(AVL_tree *x) {
|
||||||
|
AVL_tree *y = x->right;
|
||||||
|
AVL_tree *T2 = y->left;
|
||||||
|
|
||||||
|
y->left = x;
|
||||||
|
x->right = T2;
|
||||||
|
|
||||||
|
x->height = 1 + std::max(getHeight(x->left), getHeight(x->right));
|
||||||
|
y->height = 1 + std::max(getHeight(y->left), getHeight(y->right));
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getBalance(AVL_tree *root) {
|
||||||
|
if (!root)
|
||||||
|
return 0;
|
||||||
|
return getHeight(root->left) - getHeight(root->right);
|
||||||
|
}
|
||||||
|
|
||||||
|
AVL_tree *insertAVL(AVL_tree *root, int value) {
|
||||||
|
if (root == nullptr) {
|
||||||
|
return new AVL_tree{value, nullptr, nullptr, 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < root->info) {
|
||||||
|
root->left = insertAVL(root->left, value);
|
||||||
|
} else if (value > root->info) {
|
||||||
|
root->right = insertAVL(root->right, value);
|
||||||
|
} else {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
root->height = 1 + std::max(getHeight(root->left), getHeight(root->right));
|
||||||
|
|
||||||
|
int balance = getBalance(root);
|
||||||
|
|
||||||
|
if (balance > 1 && value < root->left->info) {
|
||||||
|
return rightRotate(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balance < -1 && value > root->right->info) {
|
||||||
|
return leftRotate(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balance > 1 && value > root->left->info) {
|
||||||
|
root->left = leftRotate(root->left);
|
||||||
|
return rightRotate(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balance < -1 && value < root->right->info) {
|
||||||
|
root->right = rightRotate(root->right);
|
||||||
|
return leftRotate(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteAVL(AVL_tree *root){
|
||||||
|
if (root != nullptr) {
|
||||||
|
deleteAVL(root->left);
|
||||||
|
deleteAVL(root->right);
|
||||||
|
delete root;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
struct AVL_tree {
|
||||||
|
int info;
|
||||||
|
AVL_tree *left;
|
||||||
|
AVL_tree *right;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
int getHeight(AVL_tree *root);
|
||||||
|
AVL_tree *insertAVL(AVL_tree *root, int value);
|
||||||
|
AVL_tree *rotateLeft(AVL_tree *root);
|
||||||
|
AVL_tree *rotateRight(AVL_tree *root);
|
||||||
|
AVL_tree *searchAVL(AVL_tree *root, int value);
|
||||||
|
void deleteAVL(AVL_tree *root);
|
||||||
+126
-82
@@ -1,97 +1,123 @@
|
|||||||
|
#include "avl/avl.h"
|
||||||
#include "bst/bst.h"
|
#include "bst/bst.h"
|
||||||
#include "list/list.h"
|
#include "list/list.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
#include <ostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <chrono>
|
#include <set>
|
||||||
|
|
||||||
void measureList(std::set<int> *sequence, FILE *file){
|
void measureList(std::set<int> *sequence, FILE *file) {
|
||||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
std::cout << "- Running list " << i + 1 << "/10\r";
|
std::cout << "- Running list " << i + 1 << "/10\r";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Measure build time
|
// Measure build time
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
List *head = nullptr;
|
List *head = nullptr;
|
||||||
for (int value : *sequence) {
|
for (int value : *sequence) {
|
||||||
head = insert(head, value);
|
head = insert(head, value);
|
||||||
}
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> elapsed_seconds = end - start;
|
|
||||||
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
|
|
||||||
// Now we run the search
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
for (int value : *sequence) {
|
|
||||||
search(head, value);
|
|
||||||
}
|
|
||||||
end = std::chrono::high_resolution_clock::now();
|
|
||||||
elapsed_seconds = end - start;
|
|
||||||
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
|
|
||||||
// Measure deletion time for list
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
while(head != nullptr){
|
|
||||||
head = remove(head);
|
|
||||||
}
|
|
||||||
end = std::chrono::high_resolution_clock::now();
|
|
||||||
elapsed_seconds = end - start;
|
|
||||||
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
}
|
}
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> elapsed_seconds = end - start;
|
||||||
|
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
|
||||||
buildTime /= 10;
|
// Now we run the search
|
||||||
searchTime /= 10;
|
start = std::chrono::high_resolution_clock::now();
|
||||||
deleteTime /= 10;
|
for (int value : *sequence) {
|
||||||
|
search(head, value);
|
||||||
|
}
|
||||||
|
end = std::chrono::high_resolution_clock::now();
|
||||||
|
elapsed_seconds = end - start;
|
||||||
|
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
|
||||||
std::cout << "- List built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl;
|
// Measure deletion time for list
|
||||||
fprintf(file, "List,%f,%f,%f\n", buildTime, searchTime, deleteTime);
|
start = std::chrono::high_resolution_clock::now();
|
||||||
|
while (head != nullptr) {
|
||||||
|
head = remove(head);
|
||||||
|
}
|
||||||
|
end = std::chrono::high_resolution_clock::now();
|
||||||
|
elapsed_seconds = end - start;
|
||||||
|
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTime /= 10;
|
||||||
|
searchTime /= 10;
|
||||||
|
deleteTime /= 10;
|
||||||
|
|
||||||
|
std::cout << "- List built in " << buildTime << "ms | searched in "
|
||||||
|
<< searchTime << "ms | deleted in " << deleteTime << "ms"
|
||||||
|
<< std::endl;
|
||||||
|
fprintf(file, "List,%f,%f,%f\n", buildTime, searchTime, deleteTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void measureBST(std::set<int> *sequence, FILE *file){
|
void measureBST(std::set<int> *sequence, FILE *file) {
|
||||||
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
float buildTime = 0, searchTime = 0, deleteTime = 0;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
std::cout << "- Running bst " << i + 1 << "/10\r";
|
std::cout << "- Running bst " << i + 1 << "/10\r";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
// Measure build time
|
// Measure build time
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
Tree *root = nullptr;
|
Tree *root = nullptr;
|
||||||
for (int value : *sequence) {
|
for (int value : *sequence) {
|
||||||
root = insert(root, value);
|
root = insert(root, value);
|
||||||
}
|
|
||||||
root = balance(root);
|
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
|
||||||
std::chrono::duration<double> elapsed_seconds = end - start;
|
|
||||||
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
|
|
||||||
// Now we run the search
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
for (int value : *sequence) {
|
|
||||||
search(root, value);
|
|
||||||
}
|
|
||||||
end = std::chrono::high_resolution_clock::now();
|
|
||||||
elapsed_seconds = end - start;
|
|
||||||
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
|
|
||||||
// Measure deletion time for tree
|
|
||||||
start = std::chrono::high_resolution_clock::now();
|
|
||||||
deleteTree(root);
|
|
||||||
end = std::chrono::high_resolution_clock::now();
|
|
||||||
elapsed_seconds = end - start;
|
|
||||||
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
|
||||||
}
|
}
|
||||||
|
root = balance(root);
|
||||||
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> elapsed_seconds = end - start;
|
||||||
|
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
|
||||||
buildTime /= 10;
|
// Now we run the search
|
||||||
searchTime /= 10;
|
start = std::chrono::high_resolution_clock::now();
|
||||||
deleteTime /= 10;
|
for (int value : *sequence) {
|
||||||
|
search(root, value);
|
||||||
|
}
|
||||||
|
end = std::chrono::high_resolution_clock::now();
|
||||||
|
elapsed_seconds = end - start;
|
||||||
|
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
|
||||||
std::cout << "- Tree built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl;
|
// Measure deletion time for tree
|
||||||
fprintf(file, "BST,%f,%f,%f\n", buildTime, searchTime, deleteTime);
|
start = std::chrono::high_resolution_clock::now();
|
||||||
|
deleteTree(root);
|
||||||
|
end = std::chrono::high_resolution_clock::now();
|
||||||
|
elapsed_seconds = end - start;
|
||||||
|
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTime /= 10;
|
||||||
|
searchTime /= 10;
|
||||||
|
deleteTime /= 10;
|
||||||
|
|
||||||
|
std::cout << "- Tree built in " << buildTime << "ms | searched in "
|
||||||
|
<< searchTime << "ms | deleted in " << deleteTime << "ms"
|
||||||
|
<< std::endl;
|
||||||
|
fprintf(file, "BST,%f,%f,%f\n", buildTime, searchTime, deleteTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void benchmarkAVL(std::set<int> *sequence, FILE *file) {
|
||||||
|
Tree *bst = nullptr;
|
||||||
|
for (int value : *sequence) {
|
||||||
|
bst = insert(bst, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int heightBST = getHeight(bst, 0);
|
||||||
|
deleteTree(bst);
|
||||||
|
|
||||||
|
AVL_tree *avl = nullptr;
|
||||||
|
for (int value : *sequence) {
|
||||||
|
avl = insertAVL(avl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int heightAVL = getHeight(avl);
|
||||||
|
deleteAVL(avl);
|
||||||
|
|
||||||
|
fprintf(file, "%d,%d\n", heightBST, heightAVL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -100,9 +126,25 @@ int main() {
|
|||||||
std::mt19937 gen(rd());
|
std::mt19937 gen(rd());
|
||||||
std::uniform_int_distribution<> dis(1, 1000000);
|
std::uniform_int_distribution<> dis(1, 1000000);
|
||||||
|
|
||||||
// Open a file for writing results
|
int mode = 1;
|
||||||
FILE *file = fopen("results.csv", "w");
|
std::cout << "Select benchmark to run:\n 1 - Benchmark List vs BST\n 2 - "
|
||||||
fprintf(file, "Elements,Structure,BuildTime,SearchTime,DeleteTime\n");
|
"Benchmark BST vs AVL"
|
||||||
|
<< std::endl;
|
||||||
|
std::cin >> mode;
|
||||||
|
|
||||||
|
if (mode < 1 && mode > 2) {
|
||||||
|
mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
if (mode == 1) {
|
||||||
|
// Open a file for writing results
|
||||||
|
file = fopen("results.csv", "w");
|
||||||
|
fprintf(file, "Structure,BuildTime,SearchTime,DeleteTime\n");
|
||||||
|
} else {
|
||||||
|
file = fopen("avl.csv", "w");
|
||||||
|
std::fprintf(file, "Structure,Height\n");
|
||||||
|
}
|
||||||
|
|
||||||
for (int n = 1; n < 26; n++) {
|
for (int n = 1; n < 26; n++) {
|
||||||
std::set<int> sequence;
|
std::set<int> sequence;
|
||||||
@@ -113,12 +155,14 @@ int main() {
|
|||||||
// Display this like a cascade
|
// Display this like a cascade
|
||||||
std::cout << "Running tests for " << n * 1000 << " elements..."
|
std::cout << "Running tests for " << n * 1000 << " elements..."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
if (mode == 1) {
|
||||||
measureList(&sequence, file);
|
measureList(&sequence, file);
|
||||||
measureBST(&sequence, file);
|
measureBST(&sequence, file);
|
||||||
|
} else {
|
||||||
|
benchmarkAVL(&sequence, file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,3 +58,11 @@ void deleteTree(Tree *root) {
|
|||||||
delete root;
|
delete root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getHeight(Tree *root, int height) {
|
||||||
|
if (root == nullptr) return height;
|
||||||
|
height += 1;
|
||||||
|
int leftHeight = getHeight(root->left, height);
|
||||||
|
int rightHeight = getHeight(root->right, height);
|
||||||
|
return std::max(leftHeight, rightHeight) + 1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ void traverseInOrder(Tree *root,std::vector<int> &vec);
|
|||||||
Tree *rebuild(std::vector<int> *vec, int start, int end);
|
Tree *rebuild(std::vector<int> *vec, int start, int end);
|
||||||
Tree *balance(Tree *root);
|
Tree *balance(Tree *root);
|
||||||
void deleteTree(Tree *root);
|
void deleteTree(Tree *root);
|
||||||
|
int getHeight(Tree *root, int height);
|
||||||
|
|||||||
+14
-3
@@ -1,9 +1,9 @@
|
|||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
def plot(header:str, first:list[int], second:list[int], log=False):
|
def plot(header:str, first:list[int], second:list[int], log=False, labels=("Lista", "Drzewo BST")):
|
||||||
plt.figure(figsize=(10, 6))
|
plt.figure(figsize=(10, 6))
|
||||||
plt.plot(range(1000,25001,1000), first, label="Lista")
|
plt.plot(range(1000,25001,1000), first, label=labels[0])
|
||||||
plt.plot(range(1000,25001,1000), second, label="Drzewo BST")
|
plt.plot(range(1000,25001,1000), second, label=labels[1])
|
||||||
plt.xlabel("Rozmiar tablicy")
|
plt.xlabel("Rozmiar tablicy")
|
||||||
plt.ylabel("Czas (ms)")
|
plt.ylabel("Czas (ms)")
|
||||||
if log:
|
if log:
|
||||||
@@ -45,3 +45,14 @@ if __name__ == "__main__":
|
|||||||
plot("Tworzenie", listTimes['build'], bstTimes['build'])
|
plot("Tworzenie", listTimes['build'], bstTimes['build'])
|
||||||
plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True)
|
plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True)
|
||||||
plot("Usuwanie", listTimes['delete'], bstTimes['delete'])
|
plot("Usuwanie", listTimes['delete'], bstTimes['delete'])
|
||||||
|
|
||||||
|
with open("avl.csv", "r") as file:
|
||||||
|
data = file.read()
|
||||||
|
lines = data.split('\n')
|
||||||
|
headers = lines[0].split(',')
|
||||||
|
values = [line.split(',') for line in lines[1:-1]]
|
||||||
|
|
||||||
|
bstHeights = [int(x[0]) for x in values]
|
||||||
|
avlHeights = [int(x[1]) for x in values]
|
||||||
|
|
||||||
|
plot("AVl", bstHeights, avlHeights, log=True, labels=("Drzewo BST", "Drzewo AVL"))
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
Elements,Structure,BuildTime,SearchTime,DeleteTime
|
||||||
|
List,0.543320,0.520767,0.010243
|
||||||
|
BST,1.544223,0.025997,0.008951
|
||||||
|
List,3.479965,3.461854,0.022565
|
||||||
|
BST,9.890946,0.142389,0.026754
|
||||||
|
List,7.862325,7.733483,0.037077
|
||||||
|
BST,20.342850,0.257188,0.048077
|
||||||
|
List,14.756193,14.451564,0.044844
|
||||||
|
BST,37.088211,0.312305,0.054895
|
||||||
|
List,22.063259,21.787954,0.056064
|
||||||
|
BST,51.029690,0.396568,0.065577
|
||||||
|
List,26.197474,26.072092,0.062295
|
||||||
|
BST,73.239220,0.458283,0.074890
|
||||||
|
List,39.307865,38.355278,0.069399
|
||||||
|
BST,107.733963,0.671136,0.093605
|
||||||
|
List,59.704353,59.331749,0.093153
|
||||||
|
BST,164.595337,1.058345,0.120158
|
||||||
|
List,75.755898,74.383286,0.101044
|
||||||
|
BST,209.177338,1.228530,0.138253
|
||||||
|
List,94.265694,93.193260,0.122636
|
||||||
|
BST,270.258728,1.591327,0.164845
|
||||||
|
List,104.814880,101.211784,0.116452
|
||||||
|
BST,246.079788,0.931309,0.133289
|
||||||
|
List,112.470276,110.182449,0.117044
|
||||||
|
BST,276.451080,0.975446,0.137597
|
||||||
|
List,126.718018,124.866295,0.121890
|
||||||
|
BST,315.444519,1.054176,0.142032
|
||||||
|
List,145.154541,141.603271,0.127330
|
||||||
|
BST,362.195190,1.103273,0.145592
|
||||||
|
List,168.838623,166.042252,0.132073
|
||||||
|
BST,402.726440,1.198986,0.153952
|
||||||
|
List,193.290436,189.238907,0.140827
|
||||||
|
BST,487.910156,1.276635,0.158837
|
||||||
|
List,220.266205,214.658295,0.146799
|
||||||
|
BST,504.256195,1.505627,0.168319
|
||||||
|
List,241.377975,235.950562,0.152117
|
||||||
|
BST,580.977173,1.557522,0.173307
|
||||||
|
List,266.187561,264.576538,0.177301
|
||||||
|
BST,724.846436,2.546352,0.223694
|
||||||
|
List,306.509338,306.340973,0.191684
|
||||||
|
BST,785.615173,2.440228,0.220973
|
||||||
|
List,326.952972,319.279846,0.188148
|
||||||
|
BST,793.774536,1.972353,0.209726
|
||||||
|
List,347.416840,340.725769,0.190998
|
||||||
|
BST,952.154907,2.114705,0.209531
|
||||||
|
List,374.497253,370.216095,0.194421
|
||||||
|
BST,887.039246,2.150400,0.221431
|
||||||
|
List,405.752655,403.273956,0.201055
|
||||||
|
BST,1040.535645,2.334295,0.223531
|
||||||
|
List,449.462952,439.051361,0.209022
|
||||||
|
BST,1124.903564,2.481752,0.235188
|
||||||
|
Reference in New Issue
Block a user