-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsubsimplex.h
More file actions
173 lines (144 loc) · 5.76 KB
/
subsimplex.h
File metadata and controls
173 lines (144 loc) · 5.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#ifndef SUBSIMPLEX_H
#define SUBSIMPLEX_H
/* Subsimplex is a simplex used for solving inner optimization problem, which
* is finding simplex lower bound minimum estimate */
#include <algorithm>
#include <fstream>
#include <sstream>
#include <iostream>
#include <limits>
#include <math.h>
#include <string>
#include <sys/time.h>
#include <vector>
#include "utils.h"
using namespace std;
class SubsimplexTree;
class SubsimplexTreeNode;
class Subsimplex { // Suitable for inner problems, e.g. Simplex lower bound min finding
Subsimplex(const Subsimplex& other){}
Subsimplex& operator=(const Subsimplex& other){}
public:
Subsimplex(double L) {
// _parent = 0;
_D = 0;
_L = L;
_min_vert = 0;
_diameter = 0;
_le_v1 = 0;
_le_v2 = 0;
_min_lb = 0;
_min_lb_value = 0;
_min_vert = 0;
_max_vert = 0;
_max_vert_value = numeric_limits<double>::min();
_min_vert_value = numeric_limits<double>::max();
_should_be_divided = false;
};
Subsimplex(vector<Point*> verts, double L) {
_L = L;
_verts = verts;
_D = 0;
_min_vert = 0;
_diameter = 0;
_le_v1 = 0;
_le_v2 = 0;
_min_lb = 0;
_min_lb_value = 0;
_min_vert = 0;
_max_vert = 0;
_max_vert_value = numeric_limits<double>::min();
_min_vert_value = numeric_limits<double>::max();
_should_be_divided = false;
init_parameters();
};
int _D; // Variable space dimension
double _L; // Predefined inner problem Lipschitz constant
vector<Point*> _verts; // Points with coordinates and values
// Subsimplex* _parent; // For efficiency do not store links to parents
Point* _le_v1; // Longest edge vertexes
Point* _le_v2;
double _diameter; // Longest edge length
Point* _min_vert; // Pointer to vertex with lowest function value
double _min_vert_value; // _min_vert function value
Point* _max_vert;
double _max_vert_value;
Point* _min_lb; // Subsimplexes estimate of accurate lower bound
double _min_lb_value;
double _tolerance; // ||_min_lb - _min_vert|| or ||_min_lb_value - _min_vert_value||
bool _should_be_divided; // Should be divided in next iteration
void init_parameters() { // Called when all _verts have been added
_D = _verts.size() - 1;
// Find _diameter and _le_v1, _le_v2
double edge_length; // Temporary variable
for (int a=0; a < _verts.size(); a++) {
for (int b=0; b < _verts.size(); b++){
if (b > a) {
edge_length = l2norm(_verts[a], _verts[b]);
if (edge_length > _diameter) {
_diameter = edge_length;
_le_v1 = _verts[a];
_le_v2 = _verts[b];
};
};
};
};
// Sort vertexes and set _min_vert, _max_vert
sort(_verts.begin(), _verts.end(), Point::compare_by_value);
_min_vert = _verts[0];
_min_vert_value = _min_vert->_values[0];
_max_vert = _verts[_verts.size()-1];
_max_vert_value = _max_vert->_values[0];
// Find longest edge lower bound
_min_lb_value = find_simplex_lb_min_value_estimate(_le_v1, _le_v2, _L);
// cout << "_min_vert_value is " << _min_vert_value << endl;
// if (_min_vert_value == 2.22507e-308) {
// cout << "_min_vert_value is: " << _min_vert_value << endl;
// exit(0);
// };
// Warrning (reasoning needed): using accurate lb would work better, because function
// Strictly changes by L But it wouldn't be efficient, because calculation would cost more?
_tolerance = fabs(_min_vert_value - _min_lb_value);
// cout << "Calculated tolerance " << _tolerance << " _min_lb_value " << _min_lb_value << endl;
};
double find_simplex_lb_min_value_estimate(Point* _le_v1, Point* _le_v2, double _L) {
/* This is A.Ž. simplex lower bound estimation algorithm Elleme, which do not
* garantee tolerance strict decrease */
/* Elleme: Efficient Lower Longest Edge bound Minimum Estimation */
return (_le_v1->_values[0] + _le_v2->_values[0]) / 2 - _L * (l2norm(_le_v1, _le_v2)) / sqrt(2);
};
// double find_edge_lb_min_value(Point* _le_v1, Point* _le_v2, double _L) {
// /* Finds accurate edge lower bound value */
// };
static bool wont_be_divided(Subsimplex* s) {
return !s->_should_be_divided;
};
static double compare_by_min_lb_value(Subsimplex* s1, Subsimplex* s2) { // sorts ascending
return s1->_min_lb_value < s2->_min_lb_value;
};
void add_vertex(Point* vertex){
_verts.push_back(vertex);
};
int size() {
return _verts.size();
};
void print(){
cout << " Subsimplex (" << _diameter << ", " << _min_lb_value << "):" << endl;
for (int i=0; i < _verts.size(); i++) {
_verts[i]->print();
};
};
static void print(vector<Subsimplex*> subsimplexes, string label="Printing subsimplexes:"){
cout << label << endl;
for (int i=0; i < subsimplexes.size(); i++){
subsimplexes[i]->print();
};
};
virtual ~Subsimplex(){ // Several subsimplexes can have same points - pakartotinis jų panaikinimas sukelia problemų, reikia struktūros, kurioje būtų saugomi unikalūs taškai, kuriuos būtų galima sunaikinti
// for (int i=0; i < _verts.size(); i++) {
// delete _verts[i];
// };
_verts.clear();
};
};
#endif