7 # include <tpl_dynMat.H>
8 # include <tpl_dynDlist.H>
41 enum State { Not_Solved, Solving, Unbounded, Solved, Unfeasible };
49 int compute_pivot_col()
const
51 T minimum = numeric_limits<T>::max();
53 for (
int i = 0, M = num_var + num_rest; i < M; i++)
55 const T & c = m->read(0, i);
62 return minimum >= 0 ? -1 : p;
69 int compute_pivot_row(
int p)
const
72 I(p >= 0 and p < num_var + num_rest);
75 T min_ratio = numeric_limits<T>::max();
76 for (
int i = q + 1, M = num_var + num_rest; i <= num_rest; i++)
78 const T val = m->read(i, M);
82 const T den = m->read(i, p);
86 const T ratio = val / den;
87 if (ratio < min_ratio)
95 State select_pivot(
int & p,
int & q)
98 I(state == Not_Solved or state == Solving);
100 const int col = compute_pivot_col();
102 return state = Solved;
104 const int row = compute_pivot_row(col);
106 return state = Unbounded;
111 return state = Solving;
113 void to_pivot(
size_t p,
size_t q)
116 I(p <= num_rest and q <= num_var + num_rest);
118 const int M = num_var + num_rest;
119 const T pivot = m->read(p, q);
120 for (
int j = 0; j <= M; j++)
122 m->write(p, j, m->read(p, j) / pivot);
126 for (
int i = 0; i <= num_rest; i++)
127 for (
int j = 0; j <= M; j++)
128 if (i != p and j != q)
129 m->write(i, j, m->read(i,j) - m->read(i,q)*m->read(p,j));
131 for (
int i = 0; i <= num_rest; i++)
135 T find_value(
const size_t j)
const
141 for (
int i = 1,
count = 0; i < num_rest; i++)
143 const T & value = m->read(i, j);
149 ret_val = m->read(i, num_var + num_rest);
174 void verify_var_index(
int i)
177 throw std::out_of_range
178 (gnu::autosprintf(
"index %d out of range (%d max)", i, num_var - 1));
181 T * create_restriction()
183 T * ptr =
new T [num_var + 1];
186 for (
int i = 0; i <= num_var; i++)
193 m =
new DynMatrix<T> (num_rest + 1, num_var + num_rest + 1);
196 for (; i < num_var; i++)
197 m->write(0, i, -objetive[i]);
202 it.has_current(); it.next(), i++)
204 T * rest = it.get_current();
206 for (
int j = 0; j < num_var; j++)
207 m->write(i, j, rest[j]);
209 m->write(i, num_var + i - 1, 1);
211 m->write(i, num_var + num_rest, rest[num_var]);
228 : m(NULL), objetive(NULL), num_var(n), num_rest(0), state(Not_Solved)
230 objetive =
new T [num_var];
233 solution =
new T [num_var];
255 for (
int i = 0; i < num_var; i++)
263 for (
int i = 0; i < num_var; i++)
282 T * rest = create_restriction();
287 for (
int i = 0; i <= num_var; ++i)
297 if (rest_num >= num_rest)
298 throw std::out_of_range
299 (gnu::autosprintf(
"index %d out of range (%d max)",
300 rest_num, num_rest - 1));
303 it.has_current(); it.next())
305 return it.get_current();
322 T * rest = create_restriction();
324 for (
int i = 0; i <= num_var; ++i)
330 State latex_solve(
char * name = NULL)
332 latex_matrix(gnu::autosprintf(
"%s-0.tex", name));
333 for (
int i, j, k = 1;
true; k++)
337 string str = gnu::autosprintf(
"%s-%d.tex", name, k);
341 latex_matrix(str.c_str());
345 latex_matrix(str.c_str(), 2, i, j);
348 latex_matrix(name, i, j);
368 if (state != Not_Solved)
369 throw std::logic_error(
"solve() has already been called");
371 throw std::logic_error(
"linear program without restrictions");
373 for (
int i, j;
true;)
385 for (
int j = 0; j < num_var; j++)
386 solution[j] = find_value(j);
401 for (
int i = 0; i < num_var; i++)
402 sum += solution[i]*objetive[i];
411 it.has_current(); it.next())
413 T * rest = it.get_current();
415 for (
int j = 0; j < num_var; j++)
416 sum += rest[j]*solution[j];
418 if (sum > rest[num_var])
426 for (
int i = 0; i <= num_rest; ++i)
428 for (
int j = 0; j <= num_var + num_rest; j++)
429 cout << float_f(m->read(i, j), 2) <<
" ";
435 void latex_matrix(
const char * name,
int d = 2,
int p = -1,
int q = -1)
437 ofstream out(name, ios::out);
439 const int cols = num_var + num_rest;
441 out <<
"$\\left(\\begin{array}{c";
442 for (
int i = 0; i < cols; i++)
446 for (
int i = 0; i <= num_rest; ++i)
448 for (
int j = 0; j <= cols; j++)
450 if (i == p and j == q)
451 out <<
"\\circled{" << float_f(m->read(i, j), d) <<
"}" <<
" ";
453 out << float_f(m->read(i, j), d) <<
" ";
463 out <<
"\\end{array}\\right)$" << endl;
466 void latex_linear_program(
char * name)
468 ofstream out(name, ios::out);
469 out <<
"\\begin{equation*}" << endl
471 for (
int i = 0; i < num_var; i++)
473 if (objetive[i] == 0.0)
479 if (objetive[i] != 1.0)
484 <<
"\\end{equation*}" << endl
485 <<
"Sujeto a:" << endl
486 <<
"\\begin{eqnarray*}" << endl;
489 it.has_current(); it.next())
491 T * rest = it.get_current();
493 for (
int i = 0; i < num_rest; i++)
506 out <<
" & \\leq & " << rest[num_rest];
508 if (not it.is_in_last())
513 out <<
"\\end{eqnarray*}" << endl;
516 size_t get_num_restrictions()
const {
return num_rest; }
518 size_t get_num_vars()
const {
return num_var; }
529 T * get_objetive_function()
537 verify_var_index(idx);
542 void put_restriction_coef(
int rest_num,
int idx,
const T & coef)
547 void prepare_linear_program()
T * put_restriction(DynArray< T > &coefs)
Definition: Simplex.H:320
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Definition: ahAlgo.H:127
T & get_restriction_coef(int rest_num, int idx)
retorna el coeficiente idx de la restricci{on rest_num
Definition: Simplex.H:535
void put_objetive_function(T coefs[])
Definition: Simplex.H:261
Definition: tpl_dynMat.H:43
State solve()
Definition: Simplex.H:365
T * get_restriction(int rest_num)
Retorna un punero al arreglo restricción num_rest.
Definition: Simplex.H:294
void put_objetive_function_coef(int i, const T &coef)
Definition: Simplex.H:244
T objetive_value() const
Retorna el valor de la función objetivo.
Definition: Simplex.H:398
void put_objetive_function(DynArray< T > &coefs)
Definition: Simplex.H:253
void load_solution()
Carga los valores de las variables solución.
Definition: Simplex.H:383
State
Estados del sistema.
Definition: Simplex.H:41
const T & get_solution(size_t i) const
Definition: Simplex.H:391
bool verify_solution() const
Definition: Simplex.H:408
Simplex(int n)
Definition: Simplex.H:226
Definition: tpl_dynArray.H:70
T * put_restriction(T *coefs=NULL)
Definition: Simplex.H:279
T & append(const T &item)
Definition: tpl_dynDlist.H:106