MiniBachelor
Öffentliche Methoden | Private Attribute | Aufstellung aller Elemente
SolverHandler Klassenreferenz
Klassendiagramm für SolverHandler:

Öffentliche Methoden

void setInstance (const Instance &data)
 
void solve (SolveResult &_return, const vector< bool > &fix, const int lastBest)
 

Private Attribute

Instance _data
 Server merkt sich die Daten, mit denen er durch solve() arbeiten soll. Mehr ...
 
glp_prob * _lp
 Das "GLPK-Objekt" _lp, welches zum Lösen mit der GLPK-API notwendig ist. Mehr ...
 

Ausführliche Beschreibung

Die Klasse SolverHandler ist die Implementierung von Solver und erbt vom Solver-Interface alles notwendige, damit das thrift-Framework daraus einen Server (mit einem einzelnen "Solve"-Service) erstellen kann.

Dokumentation der Elementfunktionen

void SolverHandler::setInstance ( const Instance &  data)
inline

Diese Methode wird vom Solver-Service (= unser Worker) zur Verfügung gestellt, damit der Client (= unser Farmer) zu Anfang allen die Daten, mit denen gerechnet werden sollen, zusenden kann.

Parameter
[in]dataEnthält die Daten im Datentyp Instance, so wie in der IDL beschreiben
Rückgabe
nichts
58  {
59  _data = data;
60  if (_lp != nullptr) glp_delete_prob(_lp);
61  _lp = glp_create_prob();
62  // Ausgabe von glpk unterdrücken
63  glp_term_out(GLP_OFF);
64 
65  int N = _data._profits.size();
66  int T = _data._budgets.size();
67  // "ia" ist für den Index der Zeile (Bedingung), zu der der Faktor (in ar) gehört
68  int *ia = new int[(T+1)*N +1];
69  // "ja" ist für den Index der Spalte (Variable), zu der der Faktor (in ar) gehört
70  int *ja = new int[(T+1)*N +1];
71  double *ar = new double[(T+1)*N +1];
72 
73  /* Da die GLPK-API auch für andere Programmiersprachen existert,
74  * arbeitet sie mit dem Index 1 statt 0. Daher muss man bei den
75  * Arrays +1 in der Größe hinzu addieren. */
76 
77  glp_set_obj_dir(_lp, GLP_MAX);
78  /* Das T+1, kommt daher, weil zu den T vielen Budget-Grenzen noch eine
79  * weitere Bedingung (untere Grenze) beigefügt wird. Mit dieser Bedingung
80  * lässt sich eine Berechung frühzeitig abbrechen, falls bereits eine
81  * bessere Lösung existert. */
82  glp_add_rows(_lp, T+1);
83  glp_add_cols(_lp, N);
84 
85  // Budgets -------------------------------------------
86  for (int t=0; t < T; ++t) {
87  // obere Grenze je Bedingung festlegen
88  glp_set_row_bnds(_lp, t+1, GLP_UP, 0.0, _data._budgets[t]);
89  }
90 
91  int qq = 1;
92  for (int n=0; n < N; ++n) {
93  for (int t=0; t <= T; ++t) {
94  ia[qq] = t+1;
95  ja[qq] = n+1;
96  if (t < T) {
97  // füllen der "Kostenmatrix"
98  ar[qq] = _data._costs[t][n];
99  } else {
100  /* Die letzte Bedingung enthält die Profite je Projekt, um
101  * zusammen mit einer lower Bound Bedingung eine untere
102  * Grenze für die Lösung zu definieren */
103  ar[qq] = _data._profits[n];
104  }
105  ++qq;
106  }
107  /* der Profit je Projekt ist der Faktor jeder Varible in der Gleichung,
108  * die zu Optimieren ist */
109  glp_set_obj_coef(_lp, n+1, _data._profits[n]);
110  }
111  glp_load_matrix(_lp, (T+1)*N, ia, ja, ar);
112  cout << "Instance ready." << endl;
113  }
glp_prob * _lp
Das "GLPK-Objekt" _lp, welches zum Lösen mit der GLPK-API notwendig ist.
Definition: Worker.cpp:45
Instance _data
Server merkt sich die Daten, mit denen er durch solve() arbeiten soll.
Definition: Worker.cpp:43
void SolverHandler::solve ( SolveResult &  _return,
const vector< bool > &  fix,
const int  lastBest 
)
inline

Diese Methode wird vom Solver-Service (= unser Worker) zur Verfügung gestellt, damit der Client (= unser Farmer) zu Anfang allen die Daten, mit denen gerechnet werden sollen, zusenden kann.

Parameter
[out]_returnEnthält das Ergebnis der Berechnung
[in]fixfix enthält die Projekt-Vorbelegung
[in]lastBestlastBest enthält eine bisher beste Lösung und soll als untere Grenze dienen
Rückgabe
nichts; Rückgabe ist in der Referenz _return enthalten
128  {
129  int errCode;
130  int N = _data._profits.size();
131  int T = _data._budgets.size();
132  int fi = fix.size();
133 
134  /* Zu den T Bedingungen eine weitere beifügen, die die
135  * bisher beste Lösung als untere Grenze festlegt */
136  glp_set_row_bnds(_lp, T+1, GLP_LO, lastBest, 0.0);
137 
138  for(int n=0; n < N; ++n) {
139  if(n > fi-1) {
140  // Die Variablen als B inäre V ariable für die Integer-Optimierung festlegen
141  glp_set_col_kind(_lp, n+1, GLP_BV);
142  // Für das Simplex-Verfahren die Variablengrenzen (Double Bounded) zwischen 0..1 setzen
143  glp_set_col_bnds(_lp, n+1, GLP_DB, 0.0, 1.0);
144  } else {
145  // Variablen als "Fix" setzen, die durch Vorbelegung nicht geändert werden dürfen.
146  if(fix[n] == true) {
147  glp_set_col_bnds(_lp, n+1, GLP_FX, 1.0, 1.0);
148  } else {
149  glp_set_col_bnds(_lp, n+1, GLP_FX, 0.0, 0.0);
150  }
151  }
152  }
153 
154  // initial: erstmal Simplex Verfahren (schnell!!) ======
155  glp_smcp para1;
156  glp_init_smcp(&para1); // default Parameter setzen
157 
158  errCode = glp_simplex(_lp, &para1);
159  if (errCode != 0) {
160  // keine bessere Loesung gefunden (-> cut)
161  _return._flag = Flag::CUT;
162  return;
163  }
164  _return._flag = Flag::OK;
165 
166  // Binaere Loesung mit Integer-Optimerung suchen ========
167  glp_iocp para2;
168  glp_init_iocp(&para2);
169  para2.tm_lim = _data._timeoutMs; // Zeitlimit setzen
170 
171  errCode = glp_intopt(_lp, &para2);
172  switch(errCode) {
173  case 0:
174  // ok (Ergebnis >= lastBest)
175  _return._flag = Flag::OK;
176  break;
177  case GLP_ETMLIM:
178  // nicht fertig geworden (-> neu vorbelegen)
179  _return._flag = Flag::TIMEOUT;
180  return;
181  default:
182  // keine bessere Loesung gefunden (-> cut)
183  _return._flag = Flag::CUT;
184  return;
185  }
186 
187  _return._projects.resize(N);
188  for (int n=0; n<N; ++n) {
189  if (glp_mip_col_val(_lp, n+1) > 0)
190  _return._projects[n] = true;
191  else
192  _return._projects[n] = false;
193  }
194  _return._optimum = glp_mip_obj_val(_lp);
195  }
glp_prob * _lp
Das "GLPK-Objekt" _lp, welches zum Lösen mit der GLPK-API notwendig ist.
Definition: Worker.cpp:45
Instance _data
Server merkt sich die Daten, mit denen er durch solve() arbeiten soll.
Definition: Worker.cpp:43

Dokumentation der Datenelemente

Instance SolverHandler::_data
private

Server merkt sich die Daten, mit denen er durch solve() arbeiten soll.

glp_prob* SolverHandler::_lp
private

Das "GLPK-Objekt" _lp, welches zum Lösen mit der GLPK-API notwendig ist.


Die Dokumentation für diese Klasse wurde erzeugt aufgrund der Datei: