mirror of https://github.com/CGAL/cgal
- various refactorings:
- mps reader is now derived from a model that allows to set
up and manipulate a program entrywise
- old copying models removed
- free models removed (they are utterly useless)
- a() -> get_a() etc.
- the solver can now solve problems with no variables :-)
- manual:
- added maker pages
- adapted to above changes
This commit is contained in:
parent
ea71b8eaa1
commit
a2712eb429
|
|
@ -1834,12 +1834,6 @@ QP_solver/doc_tex/QP_solver/first_qp.eps -text svneol=unset#application/postscri
|
|||
QP_solver/doc_tex/QP_solver/first_qp.fig -text svneol=unset#application/octet-stream
|
||||
QP_solver/doc_tex/QP_solver/first_qp.gif -text svneol=unset#image/gif
|
||||
QP_solver/doc_tex/QP_solver/first_qp.pdf -text svneol=unset#application/pdf
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_linear_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_linear_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_linear_program_from_pointers.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Free_quadratic_program_from_pointers.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Linear_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Linear_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Linear_program_from_mps.tex -text
|
||||
|
|
@ -1847,15 +1841,19 @@ QP_solver/doc_tex/QP_solver_ref/Linear_program_from_pointers.tex -text
|
|||
QP_solver/doc_tex/QP_solver_ref/MPSFormat.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_mps.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_linear_program_from_pointers.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_mps.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Nonnegative_quadratic_program_from_pointers.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Quadratic_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Quadratic_program_from_mps.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Quadratic_program_from_pointers.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Sparse_linear_program_from_mps.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/Sparse_quadratic_program_from_mps.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/make_linear_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/make_nonnegative_linear_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/make_nonnegative_quadratic_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/make_quadratic_program_from_iterators.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/print_linear_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/print_nonnegative_linear_program.tex -text
|
||||
QP_solver/doc_tex/QP_solver_ref/print_nonnegative_quadratic_program.tex -text
|
||||
|
|
@ -1876,6 +1874,7 @@ QP_solver/examples/QP_solver/unboundedness_certificate.cpp -text
|
|||
QP_solver/maintainer -text
|
||||
QP_solver/test/QP_solver/create_test_solver_cin -text
|
||||
QP_solver/test/QP_solver/debug_bug.cpp -text
|
||||
QP_solver/test/QP_solver/test_empty_qp.cpp -text
|
||||
QP_solver/test/QP_solver/test_random_qp.cpp -text
|
||||
QP_solver/test/QP_solver/test_solver.cout -text
|
||||
Qt_widget/demo/Qt_widget/hellosegment.vcproj eol=crlf
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
\begin{ccRefClass}{Free_linear_program<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges;
|
||||
if you only need to wrap existing iterators, you may use the classes
|
||||
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Free_linear_program_from_pointers<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{template <A_it, B_it, R_it, C_it>
|
||||
Free_linear_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
\ccc{Free_linear_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
\begin{ccRefClass}{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class is simply a wrapper for existing iterators, and it does not
|
||||
copy the program data (if you need a copy, you may use the class
|
||||
\ccc{Free_linear_program<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccConstructor{Free_linear_program_from_iterators(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_linear_program_from_pointers<NT>}\\
|
||||
\ccc{Free_linear_program<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
\begin{ccRefClass}{Free_linear_program_from_pointers<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class specializes the class
|
||||
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} for the case where all iterators are of type
|
||||
\ccc{NT**} (for
|
||||
$A$) and \ccc{NT*} otherwise, for some number type \ccc{NT}.
|
||||
The class is simply a wrapper for
|
||||
existing pointers, and it does not copy the program data (if you need
|
||||
a copy, you may use the class \ccc{Free_linear_program<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
\ccc{Free_linear_program<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
\begin{ccRefClass}{Free_quadratic_program<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a convex quadratic program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
|
||||
quadratic objective function),
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges;
|
||||
if you only need to wrap existing iterators, you may use the classes
|
||||
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Free_quadratic_program_from_pointers<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{template <A_it, B_it, R_it, D_it, C_it>
|
||||
Free_quadratic_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Free_quadratic_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
\begin{ccRefClass}{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a convex quadratic program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
|
||||
quadratic objective function),
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class is simply a wrapper for existing iterators, and it does not
|
||||
copy the program data (if you need a copy, you may use the class
|
||||
\ccc{Free_quadratic_program<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{Free_quadratic_program_from_iterators(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{Free_quadratic_program<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
\begin{ccRefClass}{Free_quadratic_program_from_pointers<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a convex quadratic program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$. The term ``free'' refers
|
||||
to the fact that there are no explicit bounds on the variables.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
|
||||
quadratic objective function),
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class specializes the class
|
||||
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} for the case where all iterators are of type
|
||||
\ccc{NT**} (for
|
||||
$A$ and $D$) and \ccc{NT*} otherwise, for some number type \ccc{NT}.
|
||||
The class is simply a wrapper for
|
||||
existing pointers, and it does not copy the program data (if you need
|
||||
a copy, you may use the class \ccc{Free_quadratic_program<NT>}).
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Free_quadratic_program<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
A model of \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
|
|
@ -25,13 +25,14 @@ $x$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The description is given by appropriate \emph{random-access}
|
||||
iterators over the program data, see below. The program therefore
|
||||
comes in \emph{dense} representation which includes zero entries.
|
||||
|
||||
\ccHasModels
|
||||
\ccc{CGAL::Linear_program<NT>}\\
|
||||
\ccc{CGAL::Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Linear_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Linear_program<NT>}\\
|
||||
\ccc{CGAL::Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Free_linear_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Free_linear_program<NT>}\\
|
||||
\ccc{CGAL::Linear_program_from_mps<NT>}\\
|
||||
|
||||
\ccTypes
|
||||
|
|
@ -69,54 +70,56 @@ $x$,
|
|||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{int n() const;}{returns the number $n$ of variables (number
|
||||
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
|
||||
of columns of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{int m() const;}{returns the number $m$ of constraints
|
||||
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
|
||||
(number of rows of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
|
||||
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
|
||||
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
|
||||
iterator for column $j$.}
|
||||
|
||||
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
|
||||
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
|
||||
of $b$.}
|
||||
|
||||
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
|
||||
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
|
||||
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
|
||||
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
|
||||
stands for $\geq$.}
|
||||
|
||||
\ccMethod{const FL_iterator& fl() const;}{returns an iterator over the
|
||||
\ccMethod{FL_iterator get_fl() const;}{returns an iterator over the
|
||||
existence of the lower bounds $l_j, j=0,\ldots,n-1$. If
|
||||
$\ccVar.\ccc{fl()}[j]=true$, the variable $x_j$ has a lower
|
||||
bound, otherwise it has no lower bound.}
|
||||
|
||||
\ccMethod{const L_iterator& l() const;}{returns an iterator for the
|
||||
\ccMethod{L_iterator get_l() const;}{returns an iterator for the
|
||||
entries of $l$. If $\ccVar.\ccc{fl()}[j]=\ccc{false}$, the value
|
||||
$\ccVar.\ccc{l()}[j]$ is not accessed.}
|
||||
|
||||
\ccMethod{const FU_iterator& fu() const;}{returns an iterator over the
|
||||
\ccMethod{FU_iterator get_fu() const;}{returns an iterator over the
|
||||
existence of the upper bounds $u_j, j=0,\ldots,n-1$. If
|
||||
$\ccVar.\ccc{fu()}[j]=true$, the variable $x_j$ has an upper
|
||||
bound, otherwise it has no upper bound.}
|
||||
|
||||
\ccMethod{const U_iterator& u() const;}{returns an iterator over the
|
||||
\ccMethod{U_iterator get_u() const;}{returns an iterator over the
|
||||
entries of $u$. If $\ccVar.\ccc{fu()}[j]=\ccc{false}$, the value
|
||||
$\ccVar.\ccc{u()}[j]$ is not accessed.}
|
||||
|
||||
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
|
||||
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
|
||||
of $c$.}
|
||||
|
||||
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
|
||||
term $c_0$ of the objective function.}
|
||||
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}
|
||||
{returns the constant term $c_0$ of the objective function.}
|
||||
|
||||
\ccRequirements
|
||||
|
||||
The value types of all iterator types (nested iterator types,
|
||||
respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
|
||||
respectively, for \ccc{A_iterator}) must be
|
||||
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
|
||||
|
||||
\ccSeeAlso
|
||||
|
||||
\ccc{QuadraticProgramInterface}\\
|
||||
\ccc{NonnegativeQuadraticProgramInterface}\\
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
|
|
@ -27,40 +27,71 @@ $x$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges; this
|
||||
is useful if the iterators that you have are not random-access.
|
||||
The time taken to copy the data is $\Theta(nm+n^2)$, though, even if
|
||||
the program description is very sparse. Usually,
|
||||
you only need to wrap existing (random-access)
|
||||
iterators, and then you may use the classes
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Linear_program_from_pointers<NT>}).
|
||||
This class allows you to build your program entry by entry, using
|
||||
the set-methods below. If you only need to wrap existing (random-access)
|
||||
iterators, then you may use the classes
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Linear_program_from_pointers<NT>}). If you want
|
||||
to read a linear program in \ccc{MPSFormat} from a file, please use
|
||||
the model \ccc{Linear_program_from_mps<NT>}.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
The following constructor is a template, so you can provide input
|
||||
iterators of any types.
|
||||
\ccConstructor{
|
||||
Linear_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
|
||||
{constructs a linear program with no variables and no constraints, ready
|
||||
for data to be added. Unless
|
||||
bounds are explicitly set using one of the methods below, bounds will be
|
||||
$x\geq 0$. Unless relations are explicitly set, relations will be of type
|
||||
\ccc{default_r}. Numerical entries that are not explicitly set will
|
||||
default to $0$.}
|
||||
|
||||
\ccConstructor{template <A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
|
||||
Linear_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const FL_it& fl,
|
||||
const L_it& l,
|
||||
const FU_it& fu,
|
||||
const U_it& u,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}.}
|
||||
\ccOperations
|
||||
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} iff
|
||||
the bounds of \ccVar\ are $x\geq 0$.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Linear_program_from_pointers<NT>}
|
||||
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
\ccc{Linear_program_from_pointers<NT>}\\
|
||||
\ccc{Linear_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
|
|
@ -52,7 +52,8 @@ copy the program data (if you need a copy, you may use the class
|
|||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Linear_program<NT>}\\
|
||||
\ccc{Linear_program_from_pointers<NT>}\\
|
||||
\ccc{Linear_program<NT>}
|
||||
\ccc{Linear_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
|
|
@ -30,45 +30,68 @@ $x$,
|
|||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}.
|
||||
|
||||
\textbf{Note:} The space required to store the program is $\Theta(nm +
|
||||
n^2)$, even if these matrix $A$ is very sparse. This might be
|
||||
prohibitive. In this case, you may use the model
|
||||
\ccc{Sparse_linear_program_from_mps<NT>} whose space requirements
|
||||
are bounded by the number of nonzero entries in the program
|
||||
description. In this latter model, access to the iterators in
|
||||
\ccc{LinearProgramInterface} will be a little slower, though.
|
||||
|
||||
As a rule of thumb, however, if there is a need for the sparse model,
|
||||
then \cgal's linear programming solver will probably not be able to
|
||||
solve it anyway.
|
||||
into type \ccc{NT}. The constructed program can be further manipulated
|
||||
by using the set-methods below.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccConstructor{Sparse_linear_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
|
||||
\ccConstructor{Linear_program_from_mps(std::istream& in)}
|
||||
{reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded linear program could be extracted from the input stream.}
|
||||
|
||||
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
\ccMethod{const std::string& get_name_of_variable (int j) const;}
|
||||
{returns the name of the $j$-th variable.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the linear program read into \ccVar\ is a nonnegative program
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}.}
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only
|
||||
if the linear program read into \ccVar\ is a nonnegative program.}
|
||||
|
||||
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
|
||||
this method returns an error message explaining why the input does not
|
||||
conform to the \ccc{MPSFormat}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Sparse_linear_program_from_mps<NT>}\\
|
||||
\ccc{Linear_program<NT>}\\
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
\ccc{Linear_program_from_pointers<NT>}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
|
|
@ -37,8 +37,12 @@ a copy, you may use the class \ccc{Linear_program<NT>}).
|
|||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Linear_program<NT>}\\
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
\ccc{Linear_program<NT>}
|
||||
\ccc{Linear_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,9 @@ of one or two sequences of three tokens $j i val$, where $j$ is the
|
|||
name of a variable (here, we have variables \texttt{x0,x1}), $i$ is
|
||||
the name of a constraint or the objective function, and $val$ is the
|
||||
value $A_{ij}$ (if $i$ names a constraint), or $c_j$ (if $i$ names the
|
||||
linear objective function). Values that are not specified in this
|
||||
section default to $0$.
|
||||
linear objective function). Values for pairs $(i,j)$ that are not
|
||||
specified in this section default to $0$. Otherwise, for every pair
|
||||
$(i,j)$, the \emph{last} specified value determines $A_{ij}$ or $c_j$.
|
||||
|
||||
\section*{RHS section}
|
||||
This (mandatory) section encodes the right-hand side vector $b$ and
|
||||
|
|
@ -86,10 +87,13 @@ encode several right-hand sides $b$ by using several such identifiers,
|
|||
but we ignore all lines having an identifier different from that of
|
||||
the first line.
|
||||
|
||||
The second token $i$ in every line names a constraint or the linear
|
||||
objective function, and the third token $val$ is the value $b_i$ (if
|
||||
The right-hand side identifier is succeeded by one or two sequences
|
||||
of tokens $i val$, where $i$ names a constraint or the linear
|
||||
objective function, and $val$ specifies the value $b_i$ (if
|
||||
$i$ names a constraint), or $-c_0$ (if $i$ names the linear objective
|
||||
function). Values that are not specified in this section default to $0$.
|
||||
Otherwise, for every $i$, the \emph{last} specified value determines
|
||||
$b_{i}$ or $-c_0$.
|
||||
|
||||
\section*{BOUNDS section}
|
||||
This (optional) section encodes the lower and upper bound vectors $l$
|
||||
|
|
@ -114,7 +118,7 @@ they are processed in order of appearance.
|
|||
|
||||
\begin{tabular}{l|l}
|
||||
bound type & resulting bound \\ \hline
|
||||
FX & $x_j \leq val$ (lower bound remains unchanged) \\
|
||||
FX & $x_j = val$ ($x_j$ becomes a fixed variable) \\
|
||||
LO & $x_j \geq val$ (upper bound remains unchanged) \\
|
||||
UP & $x_j \leq val$ (lower bound remains unchanged, except if $val<0$; then,
|
||||
a zero lower bound is reset to $-\infty$)\\
|
||||
|
|
@ -133,16 +137,17 @@ or \texttt{QUADOBJ}), or $D_{ij}$ (in case of \texttt{DMATRIX}).
|
|||
In case of \texttt{QMATRIX} and \texttt{DMATRIX}, \emph{all} nonzero
|
||||
entries must be specified: if there is a line $i j val$, then there
|
||||
must also be a line $j i val$, since $D$ is required to be symmetric.
|
||||
In case of \texttt{QUADOBJ}, only the entries of $2D$ on or below the
|
||||
diagonal must be specified, and the entries above the diagonal are
|
||||
deduced from symmetry.
|
||||
In case of \texttt{QUADOBJ}, only the entries of $2D$ on or below the
|
||||
diagonal must be specified, entries above the diagonal are deduced from
|
||||
symmetry. It is not allowed to specify two or more \emph{different}
|
||||
nonzero values for an unordered pair $\{i,j\}$.
|
||||
|
||||
If this seftion is missing or does not contain nonzero values, the
|
||||
If this section is missing or does not contain nonzero values, the
|
||||
program is a model of the concept \ccc{LinearProgramInterface}.
|
||||
|
||||
\section*{Miscellaneous}
|
||||
Our MPS format also supports an (optional) \texttt{RANGES} section,
|
||||
but we won't explain this here.
|
||||
but we don't explain this here.
|
||||
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
A model of \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x\geq \mathbf{0}
|
||||
& & x\geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -21,11 +21,15 @@ from $\{\leq, =, \geq\}$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The description is given by appropriate \emph{random-access}
|
||||
iterators over the program data, see below. The program therefore
|
||||
comes in \emph{dense} representation which includes zero entries.
|
||||
|
||||
\ccHasModels
|
||||
\ccc{CGAL::Nonnegative_linear_program<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Nonnegative_linear_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_linear_program<NT>}\\
|
||||
\ccc{CGAL::Linear_program_from_mps<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_linear_program_from_mps<NT>}\\
|
||||
|
||||
\ccTypes
|
||||
|
||||
|
|
@ -48,36 +52,38 @@ from $\{\leq, =, \geq\}$,
|
|||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{int n() const;}{returns the number $n$ of variables (number
|
||||
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
|
||||
of columns of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{int m() const;}{returns the number $m$ of constraints
|
||||
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
|
||||
(number of rows of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
|
||||
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
|
||||
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
|
||||
iterator for column $j$.}
|
||||
|
||||
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
|
||||
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
|
||||
of $b$.}
|
||||
|
||||
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
|
||||
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
|
||||
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
|
||||
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
|
||||
stands for $\geq$.}
|
||||
|
||||
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
|
||||
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
|
||||
of $c$.}
|
||||
|
||||
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
|
||||
term $c_0$ of the objective function.}
|
||||
\ccMethod{std::iterator_traits<C_iterator>::value_type get_c0() const;}
|
||||
{returns the constant term $c_0$ of the objective function.}
|
||||
|
||||
\ccRequirements
|
||||
|
||||
The value types of all iterator types (nested iterator types,
|
||||
respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
|
||||
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
|
||||
respectively, for \ccc{A_iterator}) must be convertible to some common
|
||||
\ccc{IntegralDomain} \ccc{ET}.
|
||||
|
||||
\ccSeeAlso
|
||||
|
||||
\ccc{QuadraticProgramInterface}\\
|
||||
\ccc{LinearProgramInterface}\\
|
||||
\ccc{NonnegativeQuadraticProgramInterface}
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ A model of \ccRefName\ describes a convex quadratic program of the form
|
|||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x\geq \mathbf{0}
|
||||
& & x\geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -23,11 +23,15 @@ from $\{\leq, =, \geq\}$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The description is given by appropriate \emph{random-access}
|
||||
iterators over the program data, see below. The program therefore
|
||||
comes in \emph{dense} representation which includes zero entries.
|
||||
|
||||
\ccHasModels
|
||||
\ccc{CGAL::Nonnegative_quadratic_program<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Nonnegative_quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_quadratic_program<NT>}\\
|
||||
\ccc{CGAL::Quadratic_program_from_mps<NT>}\\
|
||||
\ccc{CGAL::Nonnegative_quadratic_program_from_mps<NT>}\\
|
||||
|
||||
\ccTypes
|
||||
|
||||
|
|
@ -56,32 +60,32 @@ from $\{\leq, =, \geq\}$,
|
|||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{int n() const;}{returns the number $n$ of variables (number
|
||||
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
|
||||
of columns of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{int m() const;}{returns the number $m$ of constraints
|
||||
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
|
||||
(number of rows of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
|
||||
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
|
||||
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
|
||||
iterator for column $j$.}
|
||||
|
||||
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
|
||||
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
|
||||
of $b$.}
|
||||
|
||||
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
|
||||
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
|
||||
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
|
||||
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
|
||||
stands for $\geq$.}
|
||||
|
||||
\ccMethod{const D_iterator& d() const;}{returns an iterator for the rows of
|
||||
\ccMethod{D_iterator get_d() const;}{returns an iterator for the rows of
|
||||
$2D$. For $i=0,\ldots,n-1$, $\ccc{*(d()+i)}$ is a random access
|
||||
iterator for the entries in row $i$ below or on the diagonal.}
|
||||
|
||||
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
|
||||
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
|
||||
of $c$.}
|
||||
|
||||
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
|
||||
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}{returns the constant
|
||||
term $c_0$ of the objective function.}
|
||||
|
||||
\ccRequirements
|
||||
|
|
@ -91,5 +95,7 @@ respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
|
|||
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
|
||||
|
||||
\ccSeeAlso
|
||||
|
||||
\ccc{QuadraticProgramInterface}\\
|
||||
\ccc{LinearProgramInterface}\\
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -23,31 +23,59 @@ from $\{\leq, =, \geq\}$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges;
|
||||
if you only need to wrap existing iterators, you may use the classes
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>} and \ccc{Nonnegative_linear_program_from_pointers<NT>}).
|
||||
This class allows you to build your program entry by entry, using
|
||||
the set-methods below. If you only need to wrap existing (random-access)
|
||||
iterators, then you may use the classes
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} and \ccc{Nonnegative_linear_program_from_pointers<NT>}).
|
||||
If you want to read a nonnegative linear program in \ccc{MPSFormat} from a
|
||||
file, please use the model \ccc{Nonnegative_linear_program_from_mps<NT>}.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
The following constructor is a template, so you can provide input
|
||||
iterators of any types.
|
||||
\ccConstructor{
|
||||
Nonnegative_linear_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
|
||||
{constructs a nonnegative
|
||||
linear program with no variables and no constraints, ready
|
||||
for data to be added. Unless relations are explicitly set,
|
||||
relations will be of type \ccc{default_r}.
|
||||
Numerical entries that are not explicitly set will default to $0$.}
|
||||
|
||||
\ccConstructor{template <A_it, B_it, R_it, C_it>
|
||||
Nonnegative_linear_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
\ccOperations
|
||||
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
|
||||
\ccc{Nonnegative_linear_program_from_pointers<NT>}
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
|
||||
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
|
||||
\ccc{Nonnegative_linear_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -44,7 +44,7 @@ copy the program data (if you need a copy, you may use the class
|
|||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_linear_program<NT>}\\
|
||||
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
|
||||
\ccc{Nonnegative_linear_program<NT>}
|
||||
|
||||
\ccc{Nonnegative_linear_program_from_mps<NT>}
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
\begin{ccRefClass}{Nonnegative_linear_program_from_mps<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}. The constructed program can be further manipulated
|
||||
by using the set-methods below.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccConstructor{Nonnegative_linear_program_from_mps(std::istream& in)}
|
||||
{reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded nonnegative linear program could be extracted from the input
|
||||
stream.}
|
||||
|
||||
\ccMethod{const std::string& get_name_of_variable (int j) const;}
|
||||
{returns the name of the $j$-th variable.}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
|
||||
this method returns an error message explaining why the input does not
|
||||
conform to the \ccc{MPSFormat}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_linear_program<NT>}\\
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
|
||||
\ccc{Nonnegative_linear_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
\mbox{(LP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -34,8 +34,12 @@ a copy, you may use the class \ccc{Nonnegative_linear_program<NT>}).
|
|||
\ccIsModel
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_linear_program<NT>}\\
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
|
||||
\ccc{Nonnegative_linear_program<NT>}
|
||||
\ccc{Nonnegative_linear_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
|
|||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -25,33 +25,65 @@ from $\{\leq, =, \geq\}$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges;
|
||||
if you only need to wrap existing iterators, you may use the classes
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>} and \ccc{Nonnegative_quadratic_program_from_pointers<NT>}).
|
||||
This class allows you to build your program entry by entry, using
|
||||
the set-methods below. If you only need to wrap existing (random-access)
|
||||
iterators, then you may use the classes
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Nonnegative_quadratic_program_from_pointers<NT>}). If you want
|
||||
to read a quadratic program in \ccc{MPSFormat} from a file, please use
|
||||
the model \ccc{Nonnegative_quadratic_program_from_mps<NT>}.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{NonnegativeQuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
The following constructor is a template, so you can provide input
|
||||
iterators of any types.
|
||||
\ccConstructor{
|
||||
Nonnegative_quadratic_program(CGAL::Comparison_result default_r =
|
||||
CGAL::EQUAL);}
|
||||
{constructs a nonnegative quadratic program with no variables and no
|
||||
constraints, ready for data to be added. Unless relations are explicitly set,
|
||||
relations will be of type \ccc{default_r}. Numerical entries that are not
|
||||
explicitly set will default to $0$.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} iff the
|
||||
objective function matrix of \ccVar\ satisfies $D=0$.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
|
||||
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccConstructor{template <A_it, B_it, R_it, D_it, C_it>
|
||||
Nonnegative_quadratic_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}
|
||||
|
||||
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
|
|||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -47,7 +47,7 @@ copy the program data (if you need a copy, you may use the class
|
|||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_quadratic_program<NT>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{Nonnegative_quadratic_program<NT>}
|
||||
|
||||
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
\begin{ccRefClass}{Nonnegative_quadratic_program_from_mps<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a convex quadratic program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
|
||||
quadratic objective function),
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}. The constructed program can be further manipulated
|
||||
by using the set-methods below.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{NonnegativeQuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{Nonnegative_quadratic_program_from_mps(std::istream& in)}
|
||||
{reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded nonnegative
|
||||
quadratic program could be extracted from the input stream.}
|
||||
|
||||
\ccMethod{const std::string& get_name_of_variable (int j) const;}
|
||||
{returns the name of the $j$-th variable.}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true}.}
|
||||
|
||||
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
|
||||
this method returns an error message explaining why the input does not
|
||||
conform to the \ccc{MPSFormat}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
|
||||
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_quadratic_program<NT>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -8,7 +8,7 @@ An object of class \ccRefName\ describes a convex quadratic program of the form
|
|||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & x \geq \mathbf{0}
|
||||
& & x \geq 0
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
|
|
@ -35,8 +35,12 @@ a copy, you may use the class \ccc{Nonnegative_quadratic_program<NT>}).
|
|||
\ccIsModel
|
||||
\ccc{NonnegativeQuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_quadratic_program<NT>}\\
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
|
||||
\ccc{Nonnegative_quadratic_program<NT>}
|
||||
\ccc{Nonnegative_quadratic_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,14 @@ $x$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The description is given by appropriate \emph{random-access}
|
||||
iterators over the program data, see below. The program therefore
|
||||
comes in \emph{dense} representation which includes zero entries.
|
||||
|
||||
\ccHasModels
|
||||
\ccc{CGAL::Quadratic_program<NT>}\\
|
||||
\ccc{CGAL::Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Quadratic_program<NT>}\\
|
||||
\ccc{CGAL::Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{CGAL::Free_quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{CGAL::Free_quadratic_program<NT>}\\
|
||||
\ccc{CGAL::Quadratic_program_from_mps<NT>}\\
|
||||
|
||||
\ccTypes
|
||||
|
|
@ -77,51 +78,51 @@ $x$,
|
|||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{int n() const;}{returns the number $n$ of variables (number
|
||||
\ccMethod{int get_n() const;}{returns the number $n$ of variables (number
|
||||
of columns of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{int m() const;}{returns the number $m$ of constraints
|
||||
\ccMethod{int get_m() const;}{returns the number $m$ of constraints
|
||||
(number of rows of $A$) in \ccVar.}
|
||||
|
||||
\ccMethod{const A_iterator& a() const;}{returns an iterator over the columns
|
||||
\ccMethod{A_iterator get_a() const;}{returns an iterator over the columns
|
||||
of $A$. For $j=0,\ldots,n-1$, $\ccc{*(a()+j)}$ is a random access
|
||||
iterator for column $j$.}
|
||||
|
||||
\ccMethod{const B_iterator& b() const;}{returns an iterator over the entries
|
||||
\ccMethod{B_iterator get_b() const;}{returns an iterator over the entries
|
||||
of $b$.}
|
||||
|
||||
\ccMethod{const R_iterator& r() const;}{returns an iterator over the entries
|
||||
\ccMethod{R_iterator get_r() const;}{returns an iterator over the entries
|
||||
of $\qprel$. The value \ccc{CGAL::SMALLER} stands
|
||||
for $\leq$, \ccc{CGAL::EQUAL} stands for $=$, and \ccc{CGAL::LARGER}
|
||||
stands for $\geq$.}
|
||||
|
||||
\ccMethod{const FL_iterator& fl() const;}{returns an iterator over the
|
||||
\ccMethod{FL_iterator get_fl() const;}{returns an iterator over the
|
||||
existence of the lower bounds $l_j, j=0,\ldots,n-1$. If
|
||||
$\ccVar.\ccc{fl()}[j]=true$, the variable $x_j$ has a lower
|
||||
bound, otherwise it has no lower bound.}
|
||||
|
||||
\ccMethod{const L_iterator& l() const;}{returns an iterator for the
|
||||
\ccMethod{L_iterator get_l() const;}{returns an iterator for the
|
||||
entries of $l$. If $\ccVar.\ccc{fl()}[j]=\ccc{false}$, the value
|
||||
$\ccVar.\ccc{l()}[j]$ is not accessed.}
|
||||
|
||||
\ccMethod{const FU_iterator& fu() const;}{returns an iterator over the
|
||||
\ccMethod{FU_iterator get_fu() const;}{returns an iterator over the
|
||||
existence of the upper bounds $u_j, j=0,\ldots,n-1$. If
|
||||
$\ccVar.\ccc{fu()}[j]=true$, the variable $x_j$ has an upper
|
||||
bound, otherwise it has no upper bound.}
|
||||
|
||||
\ccMethod{const U_iterator& u() const;}{returns an iterator over the
|
||||
\ccMethod{U_iterator get_u() const;}{returns an iterator over the
|
||||
entries of $u$. If $\ccVar.\ccc{fu()}[j]=\ccc{false}$, the value
|
||||
$\ccVar.\ccc{u()}[j]$ is not accessed.}
|
||||
|
||||
\ccMethod{const D_iterator& d() const;}{returns an iterator for the rows of
|
||||
\ccMethod{D_iterator get_d() const;}{returns an iterator for the rows of
|
||||
$2D$. For $i=0,\ldots,n-1$, $\ccc{*(d()+i)}$ is a random access
|
||||
iterator for the entries in row $i$ below or on the diagonal.}
|
||||
|
||||
\ccMethod{const C_iterator& c() const;}{returns an iterator over the entries
|
||||
\ccMethod{C_iterator get_c() const;}{returns an iterator over the entries
|
||||
of $c$.}
|
||||
|
||||
\ccMethod{const std::iterator_traits<C_iterator>::value_type& c0() const;}{returns the constant
|
||||
term $c_0$ of the objective function.}
|
||||
\ccMethod{std::iterator_traits<C_iterator>::value_type c0() const;}
|
||||
{returns the constant term $c_0$ of the objective function.}
|
||||
|
||||
\ccRequirements
|
||||
|
||||
|
|
@ -130,5 +131,7 @@ respectively, for \ccc{A_iterator} and \ccc{D_iterator}) must be
|
|||
convertible to some common \ccc{IntegralDomain} \ccc{ET}.
|
||||
|
||||
\ccSeeAlso
|
||||
|
||||
\ccc{NonnegativeQuadraticProgramInterface}\\
|
||||
\ccc{LinearProgramInterface}\\
|
||||
\ccc{NonnegativeLinearProgramInterface}
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -29,41 +29,77 @@ $x$,
|
|||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
This class copies the program data from given iterator ranges;this
|
||||
is useful if the iterators that you have are not random-access.
|
||||
The time taken to copy the data is $\Theta(nm+n^2)$, though, even if the
|
||||
program description is very sparse. Usually,
|
||||
you only need to wrap existing (random-access)
|
||||
iterators, and then you may use the classes
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Quadratic_program_from_pointers<NT>}).
|
||||
This class allows you to build your program entry by entry, using
|
||||
the set-methods below. If you only need to wrap existing (random-access)
|
||||
iterators, then you may use the classes
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} and \ccc{Quadratic_program_from_pointers<NT>}). If you want
|
||||
to read a quadratic program in \ccc{MPSFormat} from a file, please use
|
||||
the model \ccc{Quadratic_program_from_mps<NT>}.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
The following constructor is a template, so you can provide input
|
||||
iterators of any types.
|
||||
\ccConstructor{
|
||||
Quadratic_program(CGAL::Comparison_result default_r = CGAL::EQUAL);}
|
||||
{constructs a quadratic program with no variables and no constraints, ready
|
||||
for data to be added. Unless
|
||||
bounds are explicitly set using one of the methods below, bounds will be
|
||||
$x\geq 0$. Unless relations are explicitly set, relations will be of type
|
||||
\ccc{default_r}. Numerical entries that are not explicitly set will
|
||||
default to $0$.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} iff the
|
||||
objective function matrix of \ccVar\ satisfies $D=0$.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} iff
|
||||
the bounds of \ccVar\ are $x\geq 0$.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
|
||||
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccConstructor{template<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
|
||||
Quadratic_program(int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const FL_it& fl,
|
||||
const L_it& l,
|
||||
const FU_it& fu,
|
||||
const U_it& u,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
const std::iterator_traits<C_it>value_type& c0 = 0
|
||||
)}{constructs \ccVar\ from given input iterators and the constant \ccc{c0}.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Quadratic_program_from_pointers<NT>}
|
||||
|
||||
\ccc{Quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{Quadratic_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ copy the program data (if you need a copy, you may use the class
|
|||
)}{constructs \ccVar\ from given random-access iterators and the constant \ccc{c0}. The passed iterators are merely stored, no copying of the program data takes place. }
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Quadratic_program<NT>}\\
|
||||
\ccc{Quadratic_program_from_pointers<NT>}\\
|
||||
\ccc{Quadratic_program<NT>}
|
||||
\ccc{Quadratic_program_from_mps<NT>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -32,48 +32,69 @@ $x$,
|
|||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}.
|
||||
|
||||
\textbf{Note:}
|
||||
The space required to store the matrices
|
||||
$A$ and $D$ is $\Theta(nm + n^2)$, even if these matrices are very sparse. This
|
||||
might be prohibitive (for example, if there are many variables, but only
|
||||
few of them are involved in the quadratic objective function). In this
|
||||
case, you may use the model \ccc{Sparse_quadratic_program_from_mps<NT>}
|
||||
whose space requirements are bounded by the number of nonzero entries
|
||||
in the program description. In this latter model, access to the iterators
|
||||
in \ccc{QuadraticProgramInterface} will be a little slower, though.
|
||||
|
||||
As a rule of thumb, however, if there is a need for the sparse model
|
||||
\emph{because both $m$ and $n$ are large}, then \cgal's quadratic
|
||||
programming solver will probably not be able to solve it anyway.
|
||||
into type \ccc{NT}. The constructed program can be further manipulated
|
||||
by using the set-methods below.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{Quadratic_program_from_mps(std::istream& in)} {reads \ccVar\ fromthe input stream \ccc{in}.}
|
||||
\ccConstructor{Quadratic_program_from_mps(std::istream& in)}
|
||||
{reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded program could be extracted from the input stream.}
|
||||
MPS-encoded quadratic program could be extracted from the input stream.}
|
||||
|
||||
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
\ccMethod{const std::string& get_name_of_variable (int j) const;}
|
||||
{returns the name of the $j$-th variable.}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}.}
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program.}
|
||||
|
||||
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
|
||||
\ccMethod{const std::string& get_error() const;}{if !\ccVar\ccc{.is_valid()},
|
||||
this method returns an error message explaining why the input does not
|
||||
conform to the \ccc{MPSFormat}.}
|
||||
|
||||
\ccMethod{void set_a (int j, int i, const NT& val);}{sets the entry $A_{ij}$
|
||||
in column $j$ and row $i$ of the constraint matrix $A$ of \ccVar\ to
|
||||
\ccc{val}. An existing entry is overwritten. \ccVar\ is enlarged if
|
||||
necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_b (int i, const NT& val);}{sets the entry $b_i$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_l (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $l_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $l_j$ to $-\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_u (int j, bool is_finite, const NT& val = NT(0));}
|
||||
{if \ccc{is_finite}, this sets the entry $u_j$ of \ccVar\ to \ccc{val},
|
||||
otherwise it sets $u_j$ to $\infty$. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c (int j, const NT& val);}{sets the entry $c_j$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccMethod{void set_c0 (const NT& val);}{sets the entry $c_0$
|
||||
of \ccVar\ to \ccc{val}. An existing entry is overwritten.}
|
||||
|
||||
\ccMethod{void set_d (int i, int j, const NT& val);}{sets the entry
|
||||
$2D_{ij}$ of \ccVar\ to \ccc{val}. An existing entry is overwritten.
|
||||
\ccVar\ is enlarged if necessary to accomodate this entry.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Sparse_quadratic_program_from_mps<NT>}\\
|
||||
\ccc{Quadratic_program<NT>}\\
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Quadratic_program_from_pointers<NT>}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,13 @@ a copy, you may use the class \ccc{Quadratic_program<NT>}).
|
|||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccTypes
|
||||
\ccNestedType{NT}{The number type of the program entries.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Quadratic_program<NT>}\\
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Quadratic_program<NT>}
|
||||
\ccc{Quadratic_program_from_mps<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
\begin{ccRefClass}{Sparse_linear_program_from_mps<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a linear program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $l$ is an $n$-dimensional vector of lower
|
||||
bounds for $x$,
|
||||
\item $u$ is an $n$-dimensional vector of upper bounds for
|
||||
$x$,
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}.
|
||||
|
||||
\textbf{Note:}
|
||||
The space requirements are bounded by the number of nonzero entries
|
||||
in the program description. However, if you can afford space
|
||||
$\Theta(nm)$, the model \ccc{Linear_program_from_mps<NT>}
|
||||
might be preferrable, since in the latter model, access to the
|
||||
iterators in \ccc{LinearProgramInterface} will be faster.
|
||||
|
||||
As a rule of thumb, if there is a need for this sparse model,
|
||||
then \cgal's linear programming solver will probably not be able to
|
||||
solve it anyway.
|
||||
\ccIsModel
|
||||
\ccc{LinearProgramInterface}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{lp}
|
||||
|
||||
\ccConstructor{Sparse_linear_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded linear program could be extracted from the input stream.}
|
||||
|
||||
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the linear program read into \ccVar\ is a nonnegative program
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}.}
|
||||
|
||||
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Linear_program_from_mps<NT>}\\
|
||||
\ccc{Linear_program<NT>}\\
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Linear_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
\begin{ccRefClass}{Sparse_quadratic_program_from_mps<NT>}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
\ccDefinition
|
||||
An object of class \ccRefName\ describes a convex quadratic program of the form
|
||||
%%
|
||||
\begin{eqnarray*}
|
||||
\mbox{(QP)}& \mbox{minimize} & x^{T}Dx+c^{T}x+c_0 \\
|
||||
&\mbox{subject to} & Ax\qprel b, \\
|
||||
& & l \leq x \leq u
|
||||
\end{eqnarray*}
|
||||
%%
|
||||
in $n$ real variables $x=(x_0,\ldots,x_{n-1})$.
|
||||
Here,
|
||||
\begin{itemize}
|
||||
\item $A$ is an $m\times n$ matrix (the constraint matrix),
|
||||
\item $b$ is an $m$-dimensional vector (the right-hand side),
|
||||
\item $\qprel$ is an $m$-dimensional vector of relations
|
||||
from $\{\leq, =, \geq\}$,
|
||||
\item $l$ is an $n$-dimensional vector of lower
|
||||
bounds for $x$,
|
||||
\item $u$ is an $n$-dimensional vector of upper bounds for
|
||||
$x$,
|
||||
\item $D$ is a symmetric positive-semidefinite $n\times n$ matrix (the
|
||||
quadratic objective function),
|
||||
\item $c$ is an $n$-dimensional vector (the linear objective
|
||||
function), and
|
||||
\item $c_0$ is a constant.
|
||||
\end{itemize}
|
||||
|
||||
The program data are read from an input stream in \ccc{MPSFormat}. This is
|
||||
a commonly used format for encoding linear and quadratic programs that
|
||||
is understood by many solvers. All values are expected to be readable
|
||||
into type \ccc{NT}.
|
||||
|
||||
\textbf{Note:}
|
||||
The space requirements are bounded by the number of nonzero entries
|
||||
in the program description. However, if you can afford space
|
||||
$\Theta(nm + n^2)$, the model \ccc{Quadratic_program_from_mps<NT>}
|
||||
might be preferrable, since in the latter model, access to the iterators
|
||||
in \ccc{QuadraticProgramInterface} will be faster.
|
||||
|
||||
As a rule of thumb, if there is a need for the sparse model
|
||||
\emph{because both $m$ and $n$ are large}, then \cgal's quadratic
|
||||
programming solver will probably not be able to solve it anyway.
|
||||
|
||||
\ccIsModel
|
||||
\ccc{QuadraticProgramInterface}
|
||||
|
||||
\ccCreation
|
||||
\ccIndexClassCreation
|
||||
\ccCreationVariable{qp}
|
||||
|
||||
\ccConstructor{Sparse_quadratic_program_from_mps(std::istream& in)} {reads \ccVar\ from the input stream \ccc{in}.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{bool is_valid() const;}{returns \ccc{true} if and only if an
|
||||
MPS-encoded program could be extracted from the input stream.}
|
||||
|
||||
\ccMethod{const std::string& name_of_variable (int i) const;} {returns the name of the $i$-th variable.\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
|
||||
\ccMethod{bool is_linear() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a linear program.
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}}
|
||||
|
||||
\ccMethod{bool is_nonnegative() const;}{returns \ccc{true} if and only if the quadratic program read into \ccVar\ is a nonnegative program
|
||||
\ccPrecond \ccVar\ccc{.is_valid()}.}
|
||||
|
||||
\ccMethod{const std::string& error() const;}{returns an error message explaining why the input is not in MPS format \ccPrecond \ccc{!} \ccVar\ccc{.is_valid()}}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Quadratic_program_from_mps<NT>}\\
|
||||
\ccc{Quadratic_program<NT>}\\
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
\ccc{Quadratic_program_from_pointers<NT>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -11,9 +11,9 @@ $\quad$ (for quadratic programs with variable bounds $l\leq x \leq u$) \\
|
|||
\ccRefConceptPage{LinearProgramInterface} \\
|
||||
$\quad$(for linear programs with variable bounds $l\leq x \leq u$)\\
|
||||
\ccRefConceptPage{NonnegativeQuadraticProgramInterface}\\
|
||||
$\quad$ (for quadratic programs with variable bounds $x\geq\mathbf{0}$) \\
|
||||
$\quad$ (for quadratic programs with variable bounds $x\geq 0$) \\
|
||||
\ccRefConceptPage{NonnegativeLinearProgramInterface}\\
|
||||
$\quad$ (for linear programs with variable bounds $x\geq\mathbf{0}$)
|
||||
$\quad$ (for linear programs with variable bounds $x\geq 0$)
|
||||
|
||||
\ccRefConceptPage{MPSFormat}\\
|
||||
$\quad$ (the format used for reading and writing linear and quadratic
|
||||
|
|
@ -34,74 +34,67 @@ Here are the models that conform to the concept
|
|||
\ccc{QuadraticProgramInterface}.
|
||||
|
||||
\ccc{Quadratic_program<NT>}\\
|
||||
$\quad$ (for quadratic programs that copy data from iterator ranges) \\
|
||||
$\quad$ (for quadratic programs that own their data and are built entry-wise; probably the most useful model)\\
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
$\quad$ (for quadratic programs that wrap given iterators, without copying
|
||||
data) \\
|
||||
\ccc{Quadratic_program_from_pointers<NT>}\\
|
||||
$\quad$ (for quadratic programs that wrap given pointers, without copying
|
||||
data) \\
|
||||
\ccc{Free_quadratic_program<NT>}\\
|
||||
$\quad$ (for quadratic programs with no variable bounds, copied from iterator ranges)\\
|
||||
\ccc{Free_quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}\\
|
||||
$\quad$ (for quadratic programs with no variable bounds, wrapping given iterators)\\
|
||||
\ccc{Free_quadratic_program_from_pointers<NT>}\\
|
||||
$\quad$ (for quadratic programs with no variable bounds, wrapping given pointers)\\
|
||||
\ccc{Quadratic_program_from_mps<NT>}\\
|
||||
$\quad$ (for quadratic programs copied from an input stream in
|
||||
\ccc{MPSFormat})\\
|
||||
\ccc{Sparse_quadratic_program_from_mps<NT>}\\
|
||||
$\quad$ (for sparse quadratic programs copied from an input stream in
|
||||
\ccc{MPSFormat})
|
||||
|
||||
$\quad$ (for quadratic programs read from an input stream in
|
||||
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
|
||||
|
||||
These are the models for \ccc{LinearProgramInterface}.
|
||||
|
||||
\ccc{Linear_program<NT>}\\
|
||||
$\quad$ (for linear programs that copy data from iterator ranges) \\
|
||||
$\quad$ (for linear programs that own their data and are built entry-wise; probably the most useful model)\\
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
$\quad$ (for linear programs that wrap given iterators, without copying
|
||||
data) \\
|
||||
\ccc{Linear_program_from_pointers<NT>}\\
|
||||
$\quad$ (for linear programs that wrap given pointers, without copying
|
||||
data) \\
|
||||
\ccc{Free_linear_program<NT>}\\
|
||||
$\quad$ (for linear programs with no variable bounds, copied from iterator ranges)\\
|
||||
\ccc{Free_linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}\\
|
||||
$\quad$ (for linear programs with no variable bounds, wrapping given
|
||||
iterators)\\
|
||||
\ccc{Free_linear_program_from_pointers<NT>}\\
|
||||
$\quad$ (for linear programs with no variable bounds, wrapping given
|
||||
pointers)\\
|
||||
\ccc{Linear_program_from_mps<NT>}\\
|
||||
$\quad$ (for linear programs copied from an input stream in
|
||||
\ccc{MPSFormat})\\
|
||||
\ccc{Sparse_linear_program_from_mps<NT>}\\
|
||||
$\quad$ (for sparse linear programs copied from an input stream in
|
||||
\ccc{MPSFormat})
|
||||
$\quad$ (for linear programs read from an input stream in
|
||||
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
|
||||
|
||||
For \ccc{NonnegativeQuadraticProgramInterface}, we offer these
|
||||
three models.
|
||||
four models.
|
||||
|
||||
\ccc{Nonnegative_quadratic_program<NT>}\\
|
||||
$\quad$ (for nonnegative quadratic programs, copied from iterator ranges)\\
|
||||
$\quad$ (for nonnegative quadratic programs that own their data and are built entry-wise; probably the most useful model)\\
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}\\
|
||||
$\quad$ (for nonnegative quadratic programs, wrapping given iterators)\\
|
||||
\ccc{Nonnegative_quadratic_program_from_pointers<NT>}\\
|
||||
$\quad$ (for nonnegative quadratic programs, wrapping given pointers)
|
||||
$\quad$ (for nonnegative quadratic programs, wrapping given pointers)\\
|
||||
\ccc{Nonnegative_quadratic_program_from_mps<NT>}\\
|
||||
$\quad$ (for nonnegative quadratic programs read from an input stream in
|
||||
\ccc{MPSFormat}; the constructed program can be manipulate entry-wise)
|
||||
|
||||
And finally, the three models for \ccc{NonnegativeLinearProgramInterface}.
|
||||
And finally, the four models for \ccc{NonnegativeLinearProgramInterface}.
|
||||
|
||||
\ccc{Nonnegative_linear_program<NT>}\\
|
||||
$\quad$ (for nonnegative linear programs, copied from iterator ranges)\\
|
||||
$\quad$ (for nonnegative linear programs that own their data and are built entry-wise; probably the most useful model)\\
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}\\
|
||||
$\quad$ (for nonnegative linear programs, wrapping given iterators)\\
|
||||
\ccc{Nonnegative_linear_program_from_pointers<NT>}\\
|
||||
$\quad$ (for nonnegative linear programs, wrapping given pointers)\\
|
||||
|
||||
\ccc{Nonnegative_linear_program_from_mps<NT>}\\
|
||||
$\quad$ (for nonnegative linear programs read from an input stream in
|
||||
\ccc{MPSFormat}; the constructed programt can be manipulate entry-wise)
|
||||
|
||||
\ccHeading{Functions}
|
||||
|
||||
In case you want to construct a program from complicated iterators
|
||||
(whose types you don't know, or simply don't want to bother with),
|
||||
we provide four makers.
|
||||
|
||||
\ccc{make_quadratic_program_from_iterators}\\
|
||||
\ccc{make_linear_program_from_iterators}\\
|
||||
\ccc{make_nonnegative_quadratic_program_from_iterators}\\
|
||||
\ccc{make_nonnegative_linear_program_from_iterators}
|
||||
|
||||
There are four functions to solve a program, one for each program
|
||||
concept.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,28 +15,27 @@
|
|||
\input{QP_solver_ref/Quadratic_program}
|
||||
\input{QP_solver_ref/Quadratic_program_from_iterators}
|
||||
\input{QP_solver_ref/Quadratic_program_from_pointers}
|
||||
\input{QP_solver_ref/Free_quadratic_program}
|
||||
\input{QP_solver_ref/Free_quadratic_program_from_iterators}
|
||||
\input{QP_solver_ref/Free_quadratic_program_from_pointers}
|
||||
\input{QP_solver_ref/Quadratic_program_from_mps}
|
||||
\input{QP_solver_ref/Sparse_quadratic_program_from_mps}
|
||||
|
||||
\input{QP_solver_ref/Linear_program}
|
||||
\input{QP_solver_ref/Linear_program_from_iterators}
|
||||
\input{QP_solver_ref/Linear_program_from_pointers}
|
||||
\input{QP_solver_ref/Free_linear_program}
|
||||
\input{QP_solver_ref/Free_linear_program_from_iterators}
|
||||
\input{QP_solver_ref/Free_linear_program_from_pointers}
|
||||
\input{QP_solver_ref/Linear_program_from_mps}
|
||||
\input{QP_solver_ref/Sparse_linear_program_from_mps}
|
||||
|
||||
\input{QP_solver_ref/Nonnegative_quadratic_program}
|
||||
\input{QP_solver_ref/Nonnegative_quadratic_program_from_iterators}
|
||||
\input{QP_solver_ref/Nonnegative_quadratic_program_from_pointers}
|
||||
\input{QP_solver_ref/Nonnegative_quadratic_program_from_mps}
|
||||
|
||||
\input{QP_solver_ref/Nonnegative_linear_program}
|
||||
\input{QP_solver_ref/Nonnegative_linear_program_from_iterators}
|
||||
\input{QP_solver_ref/Nonnegative_linear_program_from_pointers}
|
||||
\input{QP_solver_ref/Nonnegative_linear_program_from_mps}
|
||||
|
||||
\input{QP_solver_ref/make_quadratic_program_from_iterators.tex}
|
||||
\input{QP_solver_ref/make_linear_program_from_iterators.tex}
|
||||
\input{QP_solver_ref/make_nonnegative_quadratic_program_from_iterators.tex}
|
||||
\input{QP_solver_ref/make_nonnegative_linear_program_from_iterators.tex}
|
||||
|
||||
\input{QP_solver_ref/solve_quadratic_program.tex}
|
||||
\input{QP_solver_ref/solve_linear_program.tex}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
\begin{ccRefFunction}{make_linear_program_from_iterators}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
This template function creates an instance of
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>} from given iterators. This function can be useful if the types of these
|
||||
iterators are too complicated (or of too little interest for you)
|
||||
to write them down explicitly.
|
||||
|
||||
\ccFunction{template <
|
||||
typename A_it,
|
||||
typename B_it,
|
||||
typename R_it,
|
||||
typename FL_it,
|
||||
typename L_it,
|
||||
typename FU_it,
|
||||
typename U_it,
|
||||
typename C_it >
|
||||
Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>
|
||||
make_linear_program_from_iterators (
|
||||
int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const FL_it& fl,
|
||||
const L_it& l,
|
||||
const FU_it& fu,
|
||||
const U_it& u,
|
||||
const C_it& c,
|
||||
typename std::iterator_traits<C_it>::value_type c0 =
|
||||
typename std::iterator_traits<C_it>::value_type(0));}
|
||||
{returns an instance of \ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}, constructed from the given iterators.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Linear_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, C_it>}
|
||||
\end{ccRefFunction}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
\begin{ccRefFunction}{make_nonnegative_linear_program_from_iterators}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
This template function creates an instance of
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}
|
||||
from given iterators. This function can be useful if the types of these
|
||||
iterators are too complicated (or of too little interest for you)
|
||||
to write them down explicitly.
|
||||
|
||||
\ccFunction{template <
|
||||
typename A_it,
|
||||
typename B_it,
|
||||
typename R_it,
|
||||
typename C_it >
|
||||
Nonnegative_linear_program_from_iterators
|
||||
<A_it, B_it, R_it, C_it>
|
||||
make_nonnegative_linear_program_from_iterators (
|
||||
int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const C_it& c,
|
||||
typename std::iterator_traits<C_it>::value_type c0 =
|
||||
typename std::iterator_traits<C_it>::value_type(0));}
|
||||
{returns an instance of \ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}, constructed from the given iterators.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_linear_program_from_iterators<A_it, B_it, R_it, C_it>}
|
||||
\end{ccRefFunction}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
\begin{ccRefFunction}{make_nonnegative_quadratic_program_from_iterators}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
This template function creates an instance of
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>} from given iterators. This function can be useful if the types of these
|
||||
iterators are too complicated (or of too little interest for you)
|
||||
to write them down explicitly.
|
||||
|
||||
\ccFunction{template <
|
||||
typename A_it,
|
||||
typename B_it,
|
||||
typename R_it,
|
||||
typename D_it,
|
||||
typename C_it >
|
||||
Nonnegative_quadratic_program_from_iterators
|
||||
<A_it, B_it, R_it, D_it, C_it>
|
||||
make_nonnegative_quadratic_program_from_iterators (
|
||||
int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
typename std::iterator_traits<C_it>::value_type c0 =
|
||||
typename std::iterator_traits<C_it>::value_type(0));}
|
||||
{returns an instance of \ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}, constructed from the given iterators.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Nonnegative_quadratic_program_from_iterators<A_it, B_it, R_it, D_it, C_it>}
|
||||
\end{ccRefFunction}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
\begin{ccRefFunction}{make_quadratic_program_from_iterators}
|
||||
|
||||
\ccInclude{CGAL/QP_models.h}
|
||||
|
||||
This template function creates an instance of
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>} from given iterators. This function can be useful if the types of these
|
||||
iterators are too complicated (or of too little interest for you)
|
||||
to write them down explicitly.
|
||||
|
||||
\ccFunction{template <
|
||||
typename A_it,
|
||||
typename B_it,
|
||||
typename R_it,
|
||||
typename FL_it,
|
||||
typename L_it,
|
||||
typename FU_it,
|
||||
typename U_it,
|
||||
typename D_it,
|
||||
typename C_it >
|
||||
Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>
|
||||
make_quadratic_program_from_iterators (
|
||||
int n, int m,
|
||||
const A_it& a,
|
||||
const B_it& b,
|
||||
const R_it& r,
|
||||
const FL_it& fl,
|
||||
const L_it& l,
|
||||
const FU_it& fu,
|
||||
const U_it& u,
|
||||
const D_it& d,
|
||||
const C_it& c,
|
||||
typename std::iterator_traits<C_it>::value_type c0 =
|
||||
typename std::iterator_traits<C_it>::value_type(0));}
|
||||
{returns an instance of \ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}, constructed from the given iterators.}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccc{Quadratic_program_from_iterators<A_it, B_it, R_it, FL_it, L_it, FU_it, U_it, D_it, C_it>}
|
||||
\end{ccRefFunction}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
\ccInclude{CGAL/QP_functions.h}
|
||||
|
||||
This function writes a linear program to an output stream.
|
||||
This function writes a linear program to an output stream (in
|
||||
\ccc{MPSFormat}). The time
|
||||
complexity is $\Theta (mn)$, even if the program is very sparse.
|
||||
|
||||
\ccFunction{template <LinearProgramInterface>
|
||||
void print_linear_program
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
\ccInclude{CGAL/QP_functions.h}
|
||||
|
||||
This function writes a nonnegative linear program to an output stream.
|
||||
This function writes a nonnegative linear program to an output stream
|
||||
(in \ccc{MPSFormat}). The time
|
||||
complexity is $\Theta (mn)$, even if the program is very sparse.
|
||||
|
||||
\ccFunction{template <NonnegativeLinearProgramInterface>
|
||||
void print_nonnegative_linear_program
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
\ccInclude{CGAL/QP_functions.h}
|
||||
|
||||
This function writes a nonnegative quadratic program to an output stream.
|
||||
This function writes a nonnegative quadratic program
|
||||
to an output stream (in \ccc{MPSFormat}). The time
|
||||
complexity is $\Theta (n^2 + mn)$, even if the program is very sparse.
|
||||
|
||||
\ccFunction{template <NonnegativeQuadraticProgramInterface>
|
||||
void print_nonnegative_quadratic_program
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
\ccInclude{CGAL/QP_functions.h}
|
||||
|
||||
This function writes a quadratic program to an output stream.
|
||||
This function writes a quadratic program to an output stream (in
|
||||
\ccc{MPSFormat}). The time complexity is $\Theta (n^2 + mn)$, even
|
||||
if the program is very sparse.
|
||||
|
||||
\ccFunction{template <QuadraticProgramInterface>
|
||||
void print_quadratic_program
|
||||
|
|
|
|||
|
|
@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{lp} are convertible to
|
|||
runtime-checks to ensure consistency during the solution process.
|
||||
However, these checks slow down the computations by a considerable
|
||||
factor. For maximum efficiency, it is advisable to define the macros
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
|
||||
\texttt{NDEBUG}.
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
|
||||
\end{ccRefFunction}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{lp} are convertible to
|
|||
runtime-checks to ensure consistency during the solution process.
|
||||
However, these checks slow down the computations by a considerable
|
||||
factor. For maximum efficiency, it is advisable to define the macros
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
|
||||
\texttt{NDEBUG}.
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
|
||||
\end{ccRefFunction}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{qp} are convertible to
|
|||
runtime-checks to ensure consistency during the solution process.
|
||||
However, these checks slow down the computations by a considerable
|
||||
factor. For maximum efficiency, it is advisable to define the macros
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
|
||||
\texttt{NDEBUG}.
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
|
||||
\end{ccRefFunction}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,5 @@ be an exact type, and all entries of \ccc{qp} are convertible to
|
|||
runtime-checks to ensure consistency during the solution process.
|
||||
However, these checks slow down the computations by a considerable
|
||||
factor. For maximum efficiency, it is advisable to define the macros
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or (still better)
|
||||
\texttt{NDEBUG}.
|
||||
\texttt{CGAL\_QP\_NO\_ASSERTIONS} or \texttt{NDEBUG}.
|
||||
\end{ccRefFunction}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ int main(const int argNr,const char **args) {
|
|||
using std::endl;
|
||||
|
||||
// get desired level of additional logging output:
|
||||
const int verbosity = argNr < 2? 1 : std::atoi(args[1]);
|
||||
//const int verbosity = argNr < 2? 1 : std::atoi(args[1]);
|
||||
|
||||
// construct QP instance:
|
||||
typedef double IT;
|
||||
|
|
@ -55,11 +55,11 @@ int main(const int argNr,const char **args) {
|
|||
#endif
|
||||
|
||||
typedef CGAL::Quadratic_program_from_mps<IT> QP;
|
||||
QP qp(std::cin,true,verbosity);
|
||||
QP qp(std::cin);
|
||||
// check for format errors in MPS f\ile:
|
||||
if (!qp.is_valid()) {
|
||||
cout << "Input is not a valid MPS file." << endl
|
||||
<< "Error: " << qp.error() << endl;
|
||||
<< "Error: " << qp.get_error() << endl;
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
|
|
@ -75,8 +75,8 @@ int main(const int argNr,const char **args) {
|
|||
cout << "Variable values:" << endl;
|
||||
Solution::Variable_value_iterator vit =
|
||||
s.variable_values_begin() ;
|
||||
for (int i=0; i < qp.n(); ++vit, ++i)
|
||||
cout << " " << qp.name_of_variable(i) << " = "
|
||||
for (int i=0; i < qp.get_n(); ++vit, ++i)
|
||||
cout << " " << qp.get_name_of_variable(i) << " = "
|
||||
<< CGAL::to_double(*vit) << endl;
|
||||
|
||||
cout << "Basic variables (index, value):" << endl;
|
||||
|
|
|
|||
|
|
@ -44,10 +44,12 @@ namespace QP_functions_detail {
|
|||
Is_linear is_linear,
|
||||
Is_nonnegative is_nonnegative);
|
||||
|
||||
// internal routine:
|
||||
// test whether the system is of the form A x == b (equations only)
|
||||
template <typename R>
|
||||
bool is_in_equational_form (const R& r);
|
||||
|
||||
// internal routine:
|
||||
// test whether the row vectors of A that correpsond to equations
|
||||
// are linearly independent; this is done using type ET. The value
|
||||
// type of LinearInequalitySystem must be convertible to ET
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -231,85 +231,85 @@ public:
|
|||
|
||||
Quotient<ET> solution() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->solution();
|
||||
}
|
||||
|
||||
QP_status status() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->status();
|
||||
}
|
||||
|
||||
Variable_value_iterator variable_values_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->original_variable_values_begin();
|
||||
}
|
||||
|
||||
Variable_value_iterator variable_values_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->original_variable_values_end();
|
||||
}
|
||||
|
||||
Variable_numerator_iterator variable_numerators_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->original_variables_numerator_begin();
|
||||
}
|
||||
|
||||
Variable_numerator_iterator variable_numerators_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->original_variables_numerator_end();
|
||||
}
|
||||
|
||||
// ET variable_numerator_value (int i) const
|
||||
// {
|
||||
// CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
// CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
// return (*(this->Ptr()))->variable_numerator_value(i);
|
||||
// }
|
||||
|
||||
const ET& variables_common_denominator() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->variables_common_denominator();
|
||||
}
|
||||
|
||||
Index_iterator basic_variable_indices_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->basic_original_variable_indices_begin();
|
||||
}
|
||||
|
||||
Index_iterator basic_variable_indices_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->basic_original_variable_indices_end();
|
||||
}
|
||||
|
||||
int number_of_basic_variables() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->number_of_basic_original_variables();
|
||||
}
|
||||
|
||||
Index_iterator basic_constraint_indices_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->basic_constraint_indices_begin();
|
||||
}
|
||||
|
||||
Index_iterator basic_constraint_indices_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->basic_constraint_indices_end();
|
||||
}
|
||||
|
||||
int number_of_basic_constraints() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
return (*(this->Ptr()))->number_of_basic_constraints();
|
||||
}
|
||||
|
||||
|
|
@ -319,46 +319,46 @@ public:
|
|||
// ----------
|
||||
// ET optimality_certificate_numerator (int i)
|
||||
// {
|
||||
// CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
// CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
// return (*(this->Ptr()))->
|
||||
// }
|
||||
|
||||
Optimality_certificate_numerator_iterator
|
||||
optimality_certifcate_numerator_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_OPTIMAL);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_OPTIMAL);
|
||||
return (*(this->Ptr()))->optimality_certifcate_numerator_begin();
|
||||
}
|
||||
|
||||
Optimality_certificate_numerator_iterator
|
||||
optimality_certifcate_numerator_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_OPTIMAL);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_OPTIMAL);
|
||||
return (*(this->Ptr()))->optimality_certifcate_numerator_end();
|
||||
}
|
||||
|
||||
Optimality_certificate_iterator
|
||||
optimality_certificate_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_OPTIMAL);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_OPTIMAL);
|
||||
return (*(this->Ptr()))->optimality_certificate_begin();
|
||||
}
|
||||
|
||||
Optimality_certificate_iterator
|
||||
optimality_certificate_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_OPTIMAL);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_OPTIMAL);
|
||||
return (*(this->Ptr()))->optimality_certificate_end();
|
||||
}
|
||||
|
||||
ET optimality_certificate_denominator() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_OPTIMAL);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_OPTIMAL);
|
||||
return (*(this->Ptr()))->optimality_certificate_denominator();
|
||||
}
|
||||
|
||||
|
|
@ -367,16 +367,16 @@ public:
|
|||
Infeasibility_certificate_iterator
|
||||
infeasibility_certificate_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_INFEASIBLE);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_INFEASIBLE);
|
||||
return (*(this->Ptr()))->optimality_certificate_numerator_begin();
|
||||
}
|
||||
|
||||
Infeasibility_certificate_iterator
|
||||
infeasibility_certificate_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_INFEASIBLE);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_INFEASIBLE);
|
||||
return (*(this->Ptr()))->optimality_certificate_numerator_end();
|
||||
}
|
||||
|
||||
|
|
@ -384,15 +384,15 @@ public:
|
|||
// -------------
|
||||
Unboundedness_certificate_iterator unboundedness_certificate_begin() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_UNBOUNDED);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_UNBOUNDED);
|
||||
return (*(this->Ptr()))->unbounded_direction_begin();
|
||||
}
|
||||
|
||||
Unboundedness_certificate_iterator unboundedness_certificate_end() const
|
||||
{
|
||||
CGAL_qpe_precondition_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_precondition(status() == QP_UNBOUNDED);
|
||||
CGAL_qpe_assertion_msg(*(this->ptr()) != 0, "Solution not initialized");
|
||||
CGAL_qpe_assertion(status() == QP_UNBOUNDED);
|
||||
return (*(this->Ptr()))->unbounded_direction_end();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -534,14 +534,14 @@ private:
|
|||
// ----------
|
||||
// pivot step
|
||||
QP_status pivot( )
|
||||
{ CGAL_qpe_precondition( phase() > 0);
|
||||
CGAL_qpe_precondition( phase() < 3);
|
||||
{ CGAL_qpe_assertion( phase() > 0);
|
||||
CGAL_qpe_assertion( phase() < 3);
|
||||
pivot_step();
|
||||
return status(); }
|
||||
|
||||
// solve QP
|
||||
QP_status solve( )
|
||||
{ CGAL_qpe_precondition( phase() > 0);
|
||||
{ CGAL_qpe_assertion( phase() > 0);
|
||||
while ( phase() < 3) { pivot_step(); }
|
||||
return status(); }
|
||||
|
||||
|
|
@ -686,15 +686,15 @@ public: // only the pricing strategies (including user-defined ones
|
|||
|
||||
bool is_basic( int j) const
|
||||
{
|
||||
CGAL_qpe_precondition(j >= 0);
|
||||
CGAL_qpe_precondition(j < number_of_working_variables());
|
||||
CGAL_qpe_assertion(j >= 0);
|
||||
CGAL_qpe_assertion(j < number_of_working_variables());
|
||||
return (in_B[ j] >= 0);
|
||||
}
|
||||
|
||||
bool is_original(int j) const
|
||||
{
|
||||
CGAL_qpe_precondition(j >= 0);
|
||||
CGAL_qpe_precondition(j < number_of_working_variables());
|
||||
CGAL_qpe_assertion(j >= 0);
|
||||
CGAL_qpe_assertion(j < number_of_working_variables());
|
||||
return (j < qp_n);
|
||||
}
|
||||
|
||||
|
|
@ -726,7 +726,7 @@ public: // only the pricing strategies (including user-defined ones
|
|||
// Returns w[j] for an original variable x_j.
|
||||
ET w_j_numerator(int j) const
|
||||
{
|
||||
CGAL_qpe_precondition((0 <= j) && (j < qp_n) && is_phaseII);
|
||||
CGAL_qpe_assertion((0 <= j) && (j < qp_n) && is_phaseII);
|
||||
return w[j];
|
||||
}
|
||||
|
||||
|
|
@ -1970,7 +1970,7 @@ template < typename Q, typename ET, typename Tags > inline
|
|||
bool QP_solver<Q, ET, Tags>::
|
||||
basis_matrix_stays_regular()
|
||||
{
|
||||
CGAL_qpe_precondition( is_phaseII);
|
||||
CGAL_qpe_assertion( is_phaseII);
|
||||
int new_row, k;
|
||||
|
||||
if ( has_ineq && (i >= qp_n)) { // slack variable
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
set_D(const Q& qp, Tag_false /*is_linear*/)
|
||||
{
|
||||
qp_D = qp.d();
|
||||
qp_D = qp.get_d();
|
||||
}
|
||||
|
||||
template < typename Q, typename ET, typename Tags >
|
||||
|
|
@ -84,15 +84,15 @@ void QP_solver<Q, ET, Tags>::
|
|||
set(const Q& qp)
|
||||
{
|
||||
// assertions:
|
||||
CGAL_qpe_precondition(qp.n() > 0);
|
||||
CGAL_qpe_precondition(qp.m() >= 0);
|
||||
CGAL_qpe_assertion(qp.get_n() >= 0);
|
||||
CGAL_qpe_assertion(qp.get_m() >= 0);
|
||||
|
||||
// store QP
|
||||
qp_n = qp.n(); qp_m = qp.m();
|
||||
qp_A = qp.a(); qp_b = qp.b(); qp_c = qp.c(); qp_c0 = qp.c0();
|
||||
qp_n = qp.get_n(); qp_m = qp.get_m();
|
||||
qp_A = qp.get_a(); qp_b = qp.get_b(); qp_c = qp.get_c(); qp_c0 = qp.get_c0();
|
||||
|
||||
set_D(qp, Is_linear());
|
||||
qp_r = qp.r();
|
||||
qp_r = qp.get_r();
|
||||
|
||||
// set up slack variables and auxiliary problem
|
||||
// --------------------------------------------
|
||||
|
|
@ -171,10 +171,10 @@ set_explicit_bounds(const Q& /*qp*/, Tag_true) {
|
|||
template < typename Q, typename ET, typename Tags >
|
||||
void QP_solver<Q, ET, Tags>::
|
||||
set_explicit_bounds(const Q& qp, Tag_false) {
|
||||
qp_fl = qp.fl();
|
||||
qp_l = qp.l();
|
||||
qp_fu = qp.fu();
|
||||
qp_u = qp.u();
|
||||
qp_fl = qp.get_fl();
|
||||
qp_l = qp.get_l();
|
||||
qp_fu = qp.get_fu();
|
||||
qp_u = qp.get_u();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ init()
|
|||
init_solution();
|
||||
|
||||
// initialize pricing strategy
|
||||
CGAL_qpe_precondition(strategyP != static_cast< Pricing_strategy*>(0));
|
||||
CGAL_qpe_assertion(strategyP != static_cast< Pricing_strategy*>(0));
|
||||
strategyP->init(0);
|
||||
|
||||
// basic feasible solution already available?
|
||||
|
|
@ -389,8 +389,8 @@ init_basis()
|
|||
// we only have equality constraints
|
||||
|
||||
// art_A.push_back(std::make_pair(s_i, !slack_A[s_i].second));
|
||||
CGAL_qpe_precondition(s_i_absolute >= 0);
|
||||
CGAL_qpe_precondition(s_i_absolute == slack_A[s_i].first);
|
||||
CGAL_qpe_assertion(s_i_absolute >= 0);
|
||||
CGAL_qpe_assertion(s_i_absolute == slack_A[s_i].first);
|
||||
art_A.push_back(std::make_pair(s_i_absolute, !slack_A[s_i].second));
|
||||
}
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ init_solution()
|
|||
// latter restricted to basic variables B_O:
|
||||
if (!minus_c_B.empty()) minus_c_B.clear();
|
||||
minus_c_B.insert(minus_c_B.end(), l, -et1); // todo: what is minus_c_B?
|
||||
CGAL_qpe_precondition(l >= (int)art_A.size());
|
||||
CGAL_qpe_assertion(l >= (int)art_A.size());
|
||||
if (art_s_i > 0)
|
||||
minus_c_B[art_A.size()-1] *= ET(qp_n+qp_m); // Note: the idea here is to
|
||||
// give more weight to the
|
||||
|
|
|
|||
|
|
@ -103,12 +103,12 @@ class QP_basis_inverse {
|
|||
// special matrix-vector multiplication functions for LPs
|
||||
template < class ForwardIterator, class OutputIterator > inline
|
||||
void multiply_l( ForwardIterator v_x_it, OutputIterator y_l_it) const
|
||||
{ CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
{ CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
multiply__l( v_x_it, y_l_it); }
|
||||
|
||||
template < class ForwardIterator, class OutputIterator > inline
|
||||
void multiply_x( ForwardIterator v_l_it, OutputIterator y_x_it) const
|
||||
{ CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
{ CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
multiply__x( v_l_it, y_x_it); }
|
||||
|
||||
// vector-matrix multiplication ( x^T = u^T M )
|
||||
|
|
@ -221,10 +221,10 @@ class QP_basis_inverse {
|
|||
|
||||
// swap functions
|
||||
void swap_variable( unsigned int j) // ``to the end'' of R
|
||||
{ CGAL_qpe_precondition( j < b);
|
||||
{ CGAL_qpe_assertion( j < b);
|
||||
swap_variable( j, Is_LP()); }
|
||||
void swap_constraint( unsigned int i) // ``to the end'' of P
|
||||
{ CGAL_qpe_precondition( i < s);
|
||||
{ CGAL_qpe_assertion( i < s);
|
||||
swap_constraint( i, Is_LP()); }
|
||||
|
||||
private:
|
||||
|
|
@ -323,13 +323,13 @@ class QP_basis_inverse {
|
|||
void
|
||||
init( unsigned int art_size, InputIterator art_first)
|
||||
{
|
||||
CGAL_qpe_precondition_msg( art_size <= l, \
|
||||
CGAL_qpe_assertion_msg( art_size <= l, \
|
||||
"There are more equality constraints than original variables!");
|
||||
|
||||
init( art_size, art_first, Is_LP());
|
||||
d = et1;
|
||||
CGAL_qpe_postcondition( s == art_size);
|
||||
CGAL_qpe_postcondition( b == art_size);
|
||||
CGAL_qpe_assertion( s == art_size);
|
||||
CGAL_qpe_assertion( b == art_size);
|
||||
|
||||
is_phaseI = true;
|
||||
is_phaseII = false;
|
||||
|
|
@ -438,7 +438,7 @@ class QP_basis_inverse {
|
|||
// update matrix in-place
|
||||
// ----------------------
|
||||
// handle sign of new denominator
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
bool z_neg = ( z < et0);
|
||||
|
||||
// update matrix
|
||||
|
|
@ -478,7 +478,7 @@ class QP_basis_inverse {
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -502,7 +502,7 @@ class QP_basis_inverse {
|
|||
Tag_false()); // ignore 1st argument
|
||||
ET z = -inner_product_x( x_x.begin(), u_x_it);
|
||||
bool z_neg = ( z < et0);
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
|
||||
// update matrix
|
||||
update_inplace_QP( x_l.begin(), x_x.begin(), z, ( z_neg ? -d : d));
|
||||
|
|
@ -535,7 +535,7 @@ class QP_basis_inverse {
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -548,8 +548,8 @@ class QP_basis_inverse {
|
|||
enter_original_leave_original( RandomAccessIterator y_x_it, unsigned int k)
|
||||
{
|
||||
// assert LP case or phase I
|
||||
CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
CGAL_qpe_precondition( k < b);
|
||||
CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
CGAL_qpe_assertion( k < b);
|
||||
|
||||
// update matrix in place
|
||||
// ----------------------
|
||||
|
|
@ -599,7 +599,7 @@ class QP_basis_inverse {
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
// diagnostic output
|
||||
CGAL_qpe_debug {
|
||||
|
|
@ -613,8 +613,8 @@ class QP_basis_inverse {
|
|||
enter_slack_leave_slack( ForwardIterator u_x_it, unsigned int k)
|
||||
{
|
||||
// assert LP case or phase I
|
||||
CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
CGAL_qpe_precondition( k < s);
|
||||
CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
CGAL_qpe_assertion( k < s);
|
||||
|
||||
// compute new row of basis inverse
|
||||
multiply__l( u_x_it, x_x.begin());
|
||||
|
|
@ -663,7 +663,7 @@ class QP_basis_inverse {
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
// diagnostic output
|
||||
CGAL_qpe_debug {
|
||||
|
|
@ -677,7 +677,7 @@ class QP_basis_inverse {
|
|||
ForwardIterator2 u_x_it)
|
||||
{
|
||||
// assert LP case or phase I
|
||||
CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
|
||||
// update matrix in-place
|
||||
// ----------------------
|
||||
|
|
@ -685,7 +685,7 @@ class QP_basis_inverse {
|
|||
multiply__l( u_x_it, x_x.begin());
|
||||
ET z = d*u_x_it[ b] - inner_product_x( y_x_it, u_x_it);
|
||||
bool z_neg = ( z < et0);
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
|
||||
// update matrix
|
||||
update_inplace_LP( x_x.begin(), y_x_it, z, ( z_neg ? -d : d));
|
||||
|
|
@ -722,7 +722,7 @@ class QP_basis_inverse {
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -762,21 +762,21 @@ class QP_basis_inverse {
|
|||
// append row in Q if no allocated row available
|
||||
void ensure_physical_row (unsigned int row) {
|
||||
unsigned int rows = M.size();
|
||||
CGAL_qpe_precondition(rows >= row);
|
||||
CGAL_qpe_assertion(rows >= row);
|
||||
if (rows == row) {
|
||||
M.push_back(Row(row+1, et0));
|
||||
|
||||
// do we have to grow x_x?
|
||||
CGAL_qpe_precondition(x_x.size() >= row-l);
|
||||
CGAL_qpe_assertion(x_x.size() >= row-l);
|
||||
if (x_x.size() == row-l)
|
||||
x_x.push_back(et0);
|
||||
|
||||
// do we have to grow tmp_x?
|
||||
CGAL_qpe_precondition(tmp_x.size() >= row-l);
|
||||
CGAL_qpe_assertion(tmp_x.size() >= row-l);
|
||||
if (tmp_x.size() == row-l)
|
||||
tmp_x.push_back(et0);
|
||||
|
||||
CGAL_qpe_postcondition(M[row].size()==row+1);
|
||||
CGAL_qpe_assertion(M[row].size()==row+1);
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) {
|
||||
vout << "physical row " << (row) << " appended in Q\n";
|
||||
|
|
@ -1101,8 +1101,8 @@ template < class ET_, class Is_LP_ > inline
|
|||
const ET_& QP_basis_inverse<ET_,Is_LP_>::
|
||||
entry( unsigned int r, unsigned int c, Tag_false) const
|
||||
{
|
||||
CGAL_qpe_precondition( ( r < s) || ( ( r >= l) && ( r < l+b)));
|
||||
CGAL_qpe_precondition( ( c < s) || ( ( c >= l) && ( c < l+b)));
|
||||
CGAL_qpe_assertion( ( r < s) || ( ( r >= l) && ( r < l+b)));
|
||||
CGAL_qpe_assertion( ( c < s) || ( ( c >= l) && ( c < l+b)));
|
||||
return ( c < r ? M[ r][ c] : M[ c][ r]);
|
||||
}
|
||||
|
||||
|
|
@ -1111,8 +1111,8 @@ template < class ET_, class Is_LP_ > inline
|
|||
const ET_& QP_basis_inverse<ET_,Is_LP_>::
|
||||
entry( unsigned int r, unsigned int c, Tag_true) const
|
||||
{
|
||||
CGAL_qpe_precondition( r < s);
|
||||
CGAL_qpe_precondition( c < b);
|
||||
CGAL_qpe_assertion( r < s);
|
||||
CGAL_qpe_assertion( c < b);
|
||||
return M[ r][ c];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ template < class ET_, class Is_LP_ >
|
|||
void QP_basis_inverse<ET_,Is_LP_>::
|
||||
set( int n, int m, int nr_equalities)
|
||||
{
|
||||
CGAL_qpe_precondition( n > 0);
|
||||
//CGAL_qpe_precondition( m > 0);
|
||||
CGAL_qpe_assertion( n >= 0);
|
||||
CGAL_qpe_assertion( m >= 0);
|
||||
b = s = 0;
|
||||
// l is the maximum size of the basis in phase I
|
||||
l = (std::min)( n+nr_equalities+1, m);
|
||||
|
|
@ -69,7 +69,7 @@ leave_original( )
|
|||
--b;
|
||||
ET z = M[ l+b][ l+b];
|
||||
bool z_neg = ( z < et0);
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
|
||||
// update matrix in place
|
||||
update_inplace_QP( M[ l+b].begin(), M[ l+b].begin()+l,
|
||||
|
|
@ -77,7 +77,7 @@ leave_original( )
|
|||
|
||||
// store new denominator
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -96,7 +96,7 @@ enter_slack( )
|
|||
--s;
|
||||
ET z = M[ s][ s];
|
||||
bool z_neg = ( z < et0);
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
|
||||
// update matrix in place
|
||||
typename Matrix::iterator col_it;
|
||||
|
|
@ -111,7 +111,7 @@ enter_slack( )
|
|||
|
||||
// store new denominator
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -124,7 +124,7 @@ void QP_basis_inverse<ET_,Is_LP_>::
|
|||
enter_slack_leave_original( )
|
||||
{
|
||||
// assert LP case or phase I
|
||||
CGAL_qpe_precondition( is_LP || is_phaseI);
|
||||
CGAL_qpe_assertion( is_LP || is_phaseI);
|
||||
|
||||
// update matrix in-place
|
||||
// ----------------------
|
||||
|
|
@ -145,7 +145,7 @@ enter_slack_leave_original( )
|
|||
}
|
||||
ET z = (*matrix_it)[ b];
|
||||
bool z_neg = ( z < et0);
|
||||
CGAL_qpe_precondition( z != et0);
|
||||
CGAL_qpe_assertion( z != et0);
|
||||
|
||||
// update matrix
|
||||
update_inplace_LP( matrix_it->begin(), x_x.begin(), -z, ( z_neg ? d : -d));
|
||||
|
|
@ -153,7 +153,7 @@ enter_slack_leave_original( )
|
|||
// store new denominator
|
||||
// ---------------------
|
||||
d = ( z_neg ? -z : z);
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -172,7 +172,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
|
|||
{
|
||||
|
||||
// assert QP case and phaseII
|
||||
CGAL_qpe_precondition(is_QP && is_phaseII);
|
||||
CGAL_qpe_assertion(is_QP && is_phaseII);
|
||||
|
||||
|
||||
// prepare \hat{k}_{1} -scalar
|
||||
|
|
@ -197,7 +197,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
|
|||
// prepare \hat{k}_{2} -scalar
|
||||
ET hat_k_2 = s_nu - (et2 * s_delta * hat_k_1);
|
||||
|
||||
CGAL_qpe_precondition( d != et0);
|
||||
CGAL_qpe_assertion( d != et0);
|
||||
|
||||
// update matrix in place
|
||||
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
|
||||
|
|
@ -206,7 +206,7 @@ z_replace_original_by_original(ForwardIterator y_l_it,
|
|||
// store new denominator
|
||||
d = CGAL::integral_division(hat_k_1 * hat_k_1, d);
|
||||
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -223,7 +223,7 @@ z_replace_original_by_slack( )
|
|||
{
|
||||
|
||||
// assert QP case and phaseII
|
||||
CGAL_qpe_precondition(is_QP && is_phaseII);
|
||||
CGAL_qpe_assertion(is_QP && is_phaseII);
|
||||
|
||||
// adapt s and b
|
||||
--s; --b;
|
||||
|
|
@ -240,7 +240,7 @@ z_replace_original_by_slack( )
|
|||
// prepare \hat{\xi} -scalar
|
||||
ET hat_xi = M[s][s];
|
||||
|
||||
CGAL_qpe_precondition( d != et0);
|
||||
CGAL_qpe_assertion( d != et0);
|
||||
|
||||
// update matrix in place
|
||||
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
|
||||
|
|
@ -249,7 +249,7 @@ z_replace_original_by_slack( )
|
|||
// store new denominator
|
||||
d = CGAL::integral_division(hat_kappa * hat_kappa, d);
|
||||
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -269,13 +269,13 @@ z_replace_slack_by_original(ForwardIterator y_l_it,
|
|||
const ET& hat_nu)
|
||||
{
|
||||
// assert QP case and phaseII
|
||||
CGAL_qpe_precondition(is_QP && is_phaseII);
|
||||
CGAL_qpe_assertion(is_QP && is_phaseII);
|
||||
|
||||
// get copies of y_l_it and y_x_it for later use
|
||||
ForwardIterator y_l_it_copy = y_l_it;
|
||||
ForwardIterator y_x_it_copy = y_x_it;
|
||||
|
||||
CGAL_qpe_precondition( d != et0);
|
||||
CGAL_qpe_assertion( d != et0);
|
||||
|
||||
// prepare \hat{\phi}
|
||||
|
||||
|
|
@ -349,7 +349,7 @@ z_replace_slack_by_original(ForwardIterator y_l_it,
|
|||
// store new denominator
|
||||
d = CGAL::integral_division(hat_kappa * hat_kappa, d);
|
||||
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
@ -367,7 +367,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
|
|||
{
|
||||
|
||||
// assert QP case and phaseII
|
||||
CGAL_qpe_precondition(is_QP && is_phaseII);
|
||||
CGAL_qpe_assertion(is_QP && is_phaseII);
|
||||
|
||||
// prepare \hat{v} -vector in x_l, x_x
|
||||
multiply(u_x_it, u_x_it, x_l.begin(), x_x.begin(),Tag_false(),
|
||||
|
|
@ -383,7 +383,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
|
|||
// prepare \hat{k}_{3} -scalar
|
||||
ET hat_k_3 = -M[k_j][k_j];
|
||||
|
||||
CGAL_qpe_precondition( d != et0);
|
||||
CGAL_qpe_assertion( d != et0);
|
||||
|
||||
// update matrix in place
|
||||
z_update_inplace(x_l.begin(), x_x.begin(), tmp_l.begin(), tmp_x.begin(),
|
||||
|
|
@ -392,7 +392,7 @@ z_replace_slack_by_slack(ForwardIterator u_x_it, unsigned int k_j)
|
|||
// store new denominator
|
||||
d = CGAL::integral_division(hat_k_1 * hat_k_1, d);
|
||||
|
||||
CGAL_qpe_postcondition( d > et0);
|
||||
CGAL_qpe_assertion( d > et0);
|
||||
|
||||
CGAL_qpe_debug {
|
||||
if ( vout.verbose()) print();
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ namespace QP_functions_detail {
|
|||
template <typename R>
|
||||
bool is_in_equational_form (const R& r)
|
||||
{
|
||||
typename R::R_iterator it = r.r();
|
||||
typename R::R_iterator end = it + r.m();
|
||||
typename R::R_iterator it = r.get_r();
|
||||
typename R::R_iterator end = it + r.get_m();
|
||||
for (; it < end; ++it)
|
||||
if (*it != CGAL::EQUAL) return false;
|
||||
return true;
|
||||
|
|
@ -67,7 +67,7 @@ namespace QP_functions_detail {
|
|||
typename Ar::R_iterator, C_iterator> LP;
|
||||
|
||||
// auxiliary LP
|
||||
LP lp (ar.n(), ar.m(), ar.a(), B_iterator(0), ar.r(), C_iterator(0));
|
||||
LP lp (ar.get_n(), ar.get_m(), ar.get_a(), B_iterator(0), ar.get_r(), C_iterator(0));
|
||||
|
||||
// solver Tags
|
||||
typedef QP_solver_impl::QP_tags<
|
||||
|
|
@ -98,11 +98,11 @@ namespace QP_functions_detail {
|
|||
(std::ostream& out, const P& p,
|
||||
CGAL::Tag_false /*is_nonnegative*/)
|
||||
{
|
||||
typename P::FL_iterator fl = p.fl();
|
||||
typename P::FU_iterator fu = p.fu();
|
||||
typename P::L_iterator l = p.l();
|
||||
typename P::U_iterator u = p.u();
|
||||
int n = p.n();
|
||||
typename P::FL_iterator fl = p.get_fl();
|
||||
typename P::FU_iterator fu = p.get_fu();
|
||||
typename P::L_iterator l = p.get_l();
|
||||
typename P::U_iterator u = p.get_u();
|
||||
int n = p.get_n();
|
||||
out << "BOUNDS\n";
|
||||
for (int j=0; j<n; ++j, ++fl, ++l, ++fu, ++u) {
|
||||
if (!*fl || !CGAL::is_zero(*l)) {
|
||||
|
|
@ -131,8 +131,8 @@ namespace QP_functions_detail {
|
|||
(std::ostream& out, const P& p,
|
||||
CGAL::Tag_false /*is_linear*/)
|
||||
{
|
||||
typename P::D_iterator it = p.d();
|
||||
int n = p.n();
|
||||
typename P::D_iterator it = p.get_d();
|
||||
int n = p.get_n();
|
||||
bool empty_D = true;
|
||||
for (int i=0; i<n; ++i, ++it) {
|
||||
// handle only entries on/below diagonal
|
||||
|
|
@ -160,22 +160,22 @@ namespace QP_functions_detail {
|
|||
{
|
||||
bool return_val = true;
|
||||
// check n
|
||||
if (qp1.n() != qp2.n()) {
|
||||
if (qp1.get_n() != qp2.get_n()) {
|
||||
std::cerr << "Equality test fails with n: "
|
||||
<< qp1.n() << " vs. " << qp2.n() << std::endl;
|
||||
<< qp1.get_n() << " vs. " << qp2.get_n() << std::endl;
|
||||
return false; // wildly wrong, abort now
|
||||
}
|
||||
// check m
|
||||
if (qp1.m() != qp2.m()) {
|
||||
if (qp1.get_m() != qp2.get_m()) {
|
||||
std::cerr << "Equality test fails with m: "
|
||||
<< qp1.m() << " vs. " << qp2.m() << std::endl;
|
||||
<< qp1.get_m() << " vs. " << qp2.get_m() << std::endl;
|
||||
return false; // wildly wrong, abort now
|
||||
}
|
||||
int n = qp1.n();
|
||||
int m = qp1.m();
|
||||
int n = qp1.get_n();
|
||||
int m = qp1.get_m();
|
||||
// check A
|
||||
typename Quadratic_program1::A_iterator a1 = qp1.a();
|
||||
typename Quadratic_program2::A_iterator a2 = qp2.a();
|
||||
typename Quadratic_program1::A_iterator a1 = qp1.get_a();
|
||||
typename Quadratic_program2::A_iterator a2 = qp2.get_a();
|
||||
for (int j=0; j<n; ++j, ++a1, ++a2)
|
||||
for (int i=0; i<m; ++i)
|
||||
if (*((*a1)+i) != *((*a2)+i)) {
|
||||
|
|
@ -185,8 +185,8 @@ namespace QP_functions_detail {
|
|||
return_val = false;
|
||||
}
|
||||
// check b
|
||||
typename Quadratic_program1::B_iterator b1 = qp1.b();
|
||||
typename Quadratic_program2::B_iterator b2 = qp2.b();
|
||||
typename Quadratic_program1::B_iterator b1 = qp1.get_b();
|
||||
typename Quadratic_program2::B_iterator b2 = qp2.get_b();
|
||||
for (int i=0; i<m; ++i, ++b1, ++b2)
|
||||
if (*b1 != *b2) {
|
||||
std::cerr << "Equality test fails with b[" << i << "]: "
|
||||
|
|
@ -194,8 +194,8 @@ namespace QP_functions_detail {
|
|||
return_val = false;
|
||||
}
|
||||
// check r
|
||||
typename Quadratic_program1::R_iterator r1 = qp1.r();
|
||||
typename Quadratic_program2::R_iterator r2 = qp2.r();
|
||||
typename Quadratic_program1::R_iterator r1 = qp1.get_r();
|
||||
typename Quadratic_program2::R_iterator r2 = qp2.get_r();
|
||||
for (int i=0; i<m; ++i, ++r1, ++r2)
|
||||
if (*r1 != *r2) {
|
||||
std::cerr << "Equality test fails with r[" << i << "]: "
|
||||
|
|
@ -203,10 +203,10 @@ namespace QP_functions_detail {
|
|||
return_val = false;
|
||||
}
|
||||
// check fl, l
|
||||
typename Quadratic_program1::FL_iterator fl1 = qp1.fl();
|
||||
typename Quadratic_program2::FL_iterator fl2 = qp2.fl();
|
||||
typename Quadratic_program1::L_iterator l1 = qp1.l();
|
||||
typename Quadratic_program2::L_iterator l2 = qp2.l();
|
||||
typename Quadratic_program1::FL_iterator fl1 = qp1.get_fl();
|
||||
typename Quadratic_program2::FL_iterator fl2 = qp2.get_fl();
|
||||
typename Quadratic_program1::L_iterator l1 = qp1.get_l();
|
||||
typename Quadratic_program2::L_iterator l2 = qp2.get_l();
|
||||
for (int j=0; j<n; ++j, ++fl1, ++fl2, ++l1, ++l2) {
|
||||
if (*fl1 != *fl2) {
|
||||
std::cerr << "Equality test fails with fl[" << j << "]: "
|
||||
|
|
@ -221,10 +221,10 @@ namespace QP_functions_detail {
|
|||
}
|
||||
|
||||
// check fu, u
|
||||
typename Quadratic_program1::FU_iterator fu1 = qp1.fu();
|
||||
typename Quadratic_program2::FU_iterator fu2 = qp2.fu();
|
||||
typename Quadratic_program1::U_iterator u1 = qp1.u();
|
||||
typename Quadratic_program2::U_iterator u2 = qp2.u();
|
||||
typename Quadratic_program1::FU_iterator fu1 = qp1.get_fu();
|
||||
typename Quadratic_program2::FU_iterator fu2 = qp2.get_fu();
|
||||
typename Quadratic_program1::U_iterator u1 = qp1.get_u();
|
||||
typename Quadratic_program2::U_iterator u2 = qp2.get_u();
|
||||
for (int j=0; j<n; ++j, ++fu1, ++fu2, ++u1, ++u2) {
|
||||
if (*fu1 != *fu2) {
|
||||
std::cerr << "Equality test fails with fu[" << j << "]: "
|
||||
|
|
@ -238,8 +238,8 @@ namespace QP_functions_detail {
|
|||
}
|
||||
}
|
||||
// check d
|
||||
typename Quadratic_program1::D_iterator d1 = qp1.d();
|
||||
typename Quadratic_program2::D_iterator d2 = qp2.d();
|
||||
typename Quadratic_program1::D_iterator d1 = qp1.get_d();
|
||||
typename Quadratic_program2::D_iterator d2 = qp2.get_d();
|
||||
for (int i=0; i<n; ++i, ++d1, ++d2)
|
||||
for (int j=0; j<i+1; ++j) // only access entries on/below diagonal
|
||||
if (*((*d1)+j) != *((*d2)+j)) {
|
||||
|
|
@ -249,8 +249,8 @@ namespace QP_functions_detail {
|
|||
return_val = false;
|
||||
}
|
||||
// check c
|
||||
typename Quadratic_program1::C_iterator c1 = qp1.c();
|
||||
typename Quadratic_program2::C_iterator c2 = qp2.c();
|
||||
typename Quadratic_program1::C_iterator c1 = qp1.get_c();
|
||||
typename Quadratic_program2::C_iterator c2 = qp2.get_c();
|
||||
for (int j=0; j<n; ++j, ++c1, ++c2)
|
||||
if (*c1 != *c2) {
|
||||
std::cerr << "Equality test fails with c[" << j << "]: "
|
||||
|
|
@ -258,8 +258,8 @@ namespace QP_functions_detail {
|
|||
return_val = false;
|
||||
}
|
||||
// check c0
|
||||
typename Quadratic_program1::C_entry c01 = qp1.c0();
|
||||
typename Quadratic_program2::C_entry c02 = qp2.c0();
|
||||
typename Quadratic_program1::C_entry c01 = qp1.get_c0();
|
||||
typename Quadratic_program2::C_entry c02 = qp2.get_c0();
|
||||
if (c01 != c02) {
|
||||
std::cerr << "Equality test fails with c0: "
|
||||
<< c01 << " vs. " << c02 << std::endl;
|
||||
|
|
@ -278,11 +278,11 @@ namespace QP_functions_detail {
|
|||
// NAME:
|
||||
out << "NAME " << problem_name << "\n";
|
||||
|
||||
int n = p.n();
|
||||
int m = p.m();
|
||||
int n = p.get_n();
|
||||
int m = p.get_m();
|
||||
|
||||
// ROWS section:
|
||||
typename P::R_iterator r = p.r();
|
||||
typename P::R_iterator r = p.get_r();
|
||||
out << "ROWS\n"
|
||||
<< " N obj\n"; // for the objective function
|
||||
for (int i=0; i<m; ++i, ++r) {
|
||||
|
|
@ -298,8 +298,8 @@ namespace QP_functions_detail {
|
|||
}
|
||||
|
||||
// COLUMNS section:
|
||||
typename P::A_iterator a = p.a();
|
||||
typename P::C_iterator c = p.c();
|
||||
typename P::A_iterator a = p.get_a();
|
||||
typename P::C_iterator c = p.get_c();
|
||||
typedef
|
||||
typename std::iterator_traits<typename P::C_iterator>::value_type IT;
|
||||
out << "COLUMNS\n";
|
||||
|
|
@ -322,10 +322,10 @@ namespace QP_functions_detail {
|
|||
}
|
||||
|
||||
// RHS section:
|
||||
typename P::B_iterator b = p.b();
|
||||
typename P::B_iterator b = p.get_b();
|
||||
out << "RHS\n";
|
||||
if (!CGAL_NTS is_zero (p.c0()))
|
||||
out << " rhs obj " << -p.c0() << "\n";
|
||||
if (!CGAL_NTS is_zero (p.get_c0()))
|
||||
out << " rhs obj " << -p.get_c0() << "\n";
|
||||
for (int i=0; i<m; ++i, ++b)
|
||||
if (!CGAL_NTS is_zero (*b))
|
||||
out << " rhs c" << i << " " << *b << "\n";
|
||||
|
|
|
|||
|
|
@ -1,682 +0,0 @@
|
|||
// Copyright (c) 1997-2001 ETH Zurich (Switzerland).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Sven Schoenherr <sven@inf.fu-berlin.de>
|
||||
// Bernd Gaertner <gaertner@inf.ethz.ch>
|
||||
// Franz Wessendorp <fransw@inf.ethz.ch>
|
||||
// Kaspar Fischer <fischerk@inf.ethz.ch>
|
||||
|
||||
#include <CGAL/Quotient.h>
|
||||
#include <CGAL/MP_Float.h>
|
||||
#include <CGAL/Gmpz.h>
|
||||
#include <CGAL/Gmpq.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::
|
||||
QP_from_mps(std::istream& in,bool use_CPLEX_convention,
|
||||
int verbosity)
|
||||
: has_linear_tag (check_tag(Is_linear_())),
|
||||
verbosity_(verbosity), from(in),
|
||||
is_format_okay_(false),
|
||||
is_linear_(true),
|
||||
use_CPLEX_convention(use_CPLEX_convention),
|
||||
it0(0),
|
||||
is_nonnegative_cached(false),
|
||||
use_put_back_token(false)
|
||||
{
|
||||
// read NAME section:
|
||||
if (!name_section())
|
||||
return;
|
||||
|
||||
// read ROWS section:
|
||||
if (!rows_section())
|
||||
return;
|
||||
|
||||
// read COLUMNS section:
|
||||
if (!columns_section())
|
||||
return;
|
||||
|
||||
// read RHS section:
|
||||
if (!rhs_section())
|
||||
return;
|
||||
|
||||
// check for (optional) RANGES section:
|
||||
if (!ranges_section())
|
||||
return;
|
||||
|
||||
// read optional BOUNDS section:
|
||||
if (!bounds_section())
|
||||
return;
|
||||
|
||||
// initialize matrix D (in the linear case, this is not needed,
|
||||
// since we return a Const_oneset_iterator that never accesses D
|
||||
if (!has_linear_tag)
|
||||
initialize_D(var_names.size(), Sparse_D());
|
||||
|
||||
// read optional QMATRIX section:
|
||||
if (!qmatrix_section())
|
||||
return;
|
||||
|
||||
// check for ENDATA:
|
||||
const std::string end = token();
|
||||
if (end != "ENDATA") {
|
||||
err1("ENDDATA expected but found '%'",end);
|
||||
return;
|
||||
}
|
||||
|
||||
//std::cout << "MPS stream successfully read." << std::endl;
|
||||
is_format_okay_ = true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::is_valid() const
|
||||
{
|
||||
return is_format_okay_;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
const std::string& QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::error() const
|
||||
{
|
||||
CGAL_qpe_assertion(!is_valid());
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
const std::string& QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::comment() const
|
||||
{
|
||||
return comment_;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_, Sparse_D_, Sparse_A_>
|
||||
::is_symmetric(Tag_false /*sparse_D*/, unsigned int&i, unsigned int&j) const
|
||||
{
|
||||
// only called if we have a qp, i.e. if D is initialized
|
||||
const unsigned int var_nr = var_names.size();
|
||||
for (i=0; i<var_nr; ++i)
|
||||
for (j=i+1; j<var_nr; ++j)
|
||||
if (D_[i][j] != D_[j][i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_, Sparse_D_, Sparse_A_>
|
||||
::is_symmetric(Tag_true /*sparse_D*/, unsigned int&i, unsigned int&j) const
|
||||
{
|
||||
// only called if we have a qp, i.e. if D is initialized
|
||||
const unsigned int var_nr = var_names.size();
|
||||
for (i=0; i<var_nr; ++i) {
|
||||
typename Map::const_iterator b = D_[i].begin();
|
||||
typename Map::const_iterator e = D_[i].end();
|
||||
for (; b != e; ++b) {
|
||||
j = b->first;
|
||||
// check entry (j, i)
|
||||
IT expected_val = b->second;
|
||||
IT found_val = it0;
|
||||
typename Map::const_iterator it = D_[j].find(i);
|
||||
if (it != D_[j].end()) found_val = it->second;
|
||||
if (expected_val != found_val) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::name_section()
|
||||
{
|
||||
const std::string t = token();
|
||||
if (t != "NAME")
|
||||
return err("expected 'NAME'");
|
||||
// NAME: everything found until line break; whitespaces are allowed
|
||||
char c;
|
||||
std::string token;
|
||||
std::string whitespaces;
|
||||
if (whitespace())
|
||||
// line break eaten, name is empty
|
||||
return true;
|
||||
do {
|
||||
from.get(c);
|
||||
if (c == '\r' || c == '\n') break;
|
||||
if (isspace(c))
|
||||
whitespaces.push_back(c); // save whitespace
|
||||
else {
|
||||
// new actual character found: previous whitespaces belong to name
|
||||
name += whitespaces;
|
||||
whitespaces.clear();
|
||||
name.push_back(c);
|
||||
}
|
||||
} while (true);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::rows_section()
|
||||
{
|
||||
std::string t = token();
|
||||
if (t != "ROWS")
|
||||
return err1("expected 'ROWS' but found '%'",t);
|
||||
|
||||
// read 'N', 'G', 'L', or 'E', and the name of the constraint:
|
||||
t = token();
|
||||
while (t != "COLUMNS") {
|
||||
const char type = t[0];
|
||||
const std::string symbol(t); // for error message below
|
||||
t = token();
|
||||
switch (type) {
|
||||
case 'N':
|
||||
// register name of objective row:
|
||||
if (obj.size() == 0) // remember first (and ignore others)
|
||||
obj = t;
|
||||
break;
|
||||
case 'G':
|
||||
case 'L':
|
||||
case 'E':
|
||||
{
|
||||
// register name of >=, <=, or = constraint:
|
||||
const unsigned int index = row_types_.size();
|
||||
row_types_.push_back(type == 'G'? CGAL::LARGER :
|
||||
(type == 'E'? CGAL::EQUAL : CGAL::SMALLER));
|
||||
if (row_names.find(t) != row_names.end())
|
||||
return err1("duplicate row name '%' in section ROWS",t);
|
||||
row_names.insert(String_int_pair(t,index));
|
||||
row_by_index.push_back(t);
|
||||
b_.push_back(IT(0));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return err1(
|
||||
"expected 'N', 'L', 'E', or 'G' in ROWS section but found '%'",
|
||||
symbol);
|
||||
}
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::columns_section()
|
||||
{
|
||||
std::string t = token();
|
||||
if (t != "COLUMNS")
|
||||
return err1("expected 'COLUMNS' but found '%'",t);
|
||||
|
||||
t = token();
|
||||
while (t != "RHS") {
|
||||
// find variable name:
|
||||
unsigned int var_index;
|
||||
std::string col_name;
|
||||
const Index_map::const_iterator var_name = var_names.find(t);
|
||||
if (var_name == var_names.end()) { // new variable?
|
||||
var_index = var_names.size();
|
||||
col_name = t;
|
||||
var_names.insert(String_int_pair(t,var_index));
|
||||
var_by_index.push_back(t);
|
||||
add_column (Sparse_A_());
|
||||
c_.push_back(IT(0));
|
||||
fl_.push_back(true); // default lower bound is finite...
|
||||
l_.push_back(IT(0)); // ...namely zero
|
||||
fu_.push_back(false); // default upper bound is infinite
|
||||
u_.push_back(IT()); // (dummy value)
|
||||
} else { // variable that is already known?
|
||||
var_index = var_name->second;
|
||||
col_name = var_name->first;
|
||||
}
|
||||
|
||||
bool doItAgain = true;
|
||||
for (int i=0; doItAgain; ++i) {
|
||||
// read row identifier:
|
||||
t = token();
|
||||
|
||||
// read number:
|
||||
IT val;
|
||||
if (!number(val))
|
||||
return err2("number expected after row identifier '%' in '%' COLUMNS record",t,col_name);
|
||||
|
||||
// store number:
|
||||
if (t == obj) { // objective row?
|
||||
c_[var_index] = val;
|
||||
} else { // not objective row?
|
||||
const Index_map::const_iterator row_name = row_names.find(t);
|
||||
if (row_name == row_names.end())
|
||||
return err1("unknown row identifier '%' in section COLUMNS",t);
|
||||
set_entry_in_A (var_index, row_name->second, val, Sparse_A_());
|
||||
}
|
||||
|
||||
// determine if we need to read another number:
|
||||
doItAgain = i==0 && !whitespace();
|
||||
}
|
||||
|
||||
// read next token:
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::rhs_section()
|
||||
{
|
||||
c_0 = IT(0); // no constant term yet
|
||||
std::string t = token();
|
||||
if (t != "RHS")
|
||||
return err1("expected 'RHS' but found '%'",t);
|
||||
|
||||
t = token();
|
||||
std::string rhs_id;
|
||||
while (t != "RANGES" && t != "BOUNDS" &&
|
||||
t != "DMATRIX" && t != "QMATRIX" && t != "QUADOBJ" &&
|
||||
t != "ENDATA") {
|
||||
// read rhs identifier and if it is different from the one
|
||||
// from the previous iteration, ignore the whole row:
|
||||
bool ignore = false;
|
||||
std::string ignored;
|
||||
if (rhs_id.size() == 0) { // first time we enter the loop?
|
||||
rhs_id = t;
|
||||
} else { // rhs_id already set
|
||||
if (t != rhs_id) {
|
||||
ignore = true; // ignore other rhs identifiers
|
||||
ignored = t;
|
||||
}
|
||||
}
|
||||
|
||||
bool doItAgain = true;
|
||||
for (int i=0; doItAgain; ++i) {
|
||||
// read row identifier:
|
||||
t = token();
|
||||
|
||||
// read number:
|
||||
IT val;
|
||||
if (!number(val))
|
||||
return err1("number expected after '%' in this RHS record",t);
|
||||
|
||||
// store number:
|
||||
const Index_map::const_iterator row_name = row_names.find(t);
|
||||
if (row_name == row_names.end()) {
|
||||
// no corresponding constraint; is it the constant term?
|
||||
if (t == obj)
|
||||
c_0 = -val;
|
||||
else
|
||||
return err1("unknown row identifier '%' in section RHS",t);
|
||||
} else {
|
||||
// we have an actual constraint
|
||||
if (!ignore) {
|
||||
b_[row_name->second] = val;
|
||||
} else {
|
||||
warn1("rhs with identifier '%' ignored", ignored);
|
||||
}
|
||||
}
|
||||
|
||||
// determine if we need to read another number:
|
||||
doItAgain = i==0 && !whitespace();
|
||||
}
|
||||
|
||||
// read next token:
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::ranges_section()
|
||||
{
|
||||
std::string t = token();
|
||||
if (t != "RANGES") { // (Note: RANGES section is optional.)
|
||||
put_token_back(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
t = token();
|
||||
std::string range_id;
|
||||
while ((t != "BOUNDS" && t != "QMATRIX" &&
|
||||
t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA")) {
|
||||
// read rhs identifier and if it is different from the one
|
||||
// from the previous iteration, ignore the whole row:
|
||||
bool ignore = false;
|
||||
std::string ignored;
|
||||
if (range_id.size() == 0) { // first time we enter the loop?
|
||||
range_id = t;
|
||||
} else { // range_id already set
|
||||
if (t != range_id) {
|
||||
ignore = true; // ignore other range identifiers
|
||||
ignored = t;
|
||||
}
|
||||
}
|
||||
bool doItAgain = true;
|
||||
for (int i=0; doItAgain; ++i) {
|
||||
// read row identifier:
|
||||
t = token();
|
||||
|
||||
// read number:
|
||||
IT val;
|
||||
if (!number(val))
|
||||
return err1("number expected after '%' in this RANGES record",t);
|
||||
|
||||
// duplicate the constraint, depending on sign of val and type
|
||||
// of constraint
|
||||
const Index_map::const_iterator row_name = row_names.find(t);
|
||||
if (row_name == row_names.end()) {
|
||||
return err1("unknown row identifier '%' in section RANGES",t);
|
||||
} else {
|
||||
if (!ignore) {
|
||||
int index = row_name->second;
|
||||
CGAL::Comparison_result type = row_types_[index];
|
||||
// duplicate the row, unless it has already been duplicated
|
||||
const Index_map::const_iterator duplicated_row_name =
|
||||
duplicated_row_names.find(t);
|
||||
if (duplicated_row_name != duplicated_row_names.end())
|
||||
return err1("duplicate row identifier '%' in section RANGES",t);
|
||||
duplicated_row_names.insert(*row_name);
|
||||
int new_index = b_.size();
|
||||
for (unsigned int j=0; j<var_names.size(); ++j) {
|
||||
IT val = get_entry_in_A (j, index, Sparse_A_());
|
||||
add_entry_in_A (j, new_index, val, Sparse_A_());
|
||||
}
|
||||
// determine rhs for this new row. Here are the rules:
|
||||
// if r is the ranges value and b is the old right-hand
|
||||
// side, then we have h <= constraint <= u according to
|
||||
// this table:
|
||||
//
|
||||
// row type sign of r h u
|
||||
// ----------------------------------------------
|
||||
// G + or - b b + |r|
|
||||
// L + or - b - |r| b
|
||||
// E + b b + |r|
|
||||
// E - b - |r| b
|
||||
|
||||
switch (type) {
|
||||
case CGAL::LARGER: // introduce "<= b+|r|"
|
||||
row_types_.push_back(CGAL::SMALLER);
|
||||
b_.push_back(b_[index] + CGAL::abs(val));
|
||||
break;
|
||||
case CGAL::SMALLER: // introduce ">= b-|r|"
|
||||
row_types_.push_back(CGAL::LARGER);
|
||||
b_.push_back(b_[index] - CGAL::abs(val));
|
||||
break;
|
||||
case CGAL::EQUAL:
|
||||
if (CGAL_NTS is_positive (val)) {
|
||||
// introduce "<= b+|r|"
|
||||
row_types_.push_back(CGAL::SMALLER);
|
||||
} else {
|
||||
// introduce ">= b-|r|"
|
||||
row_types_.push_back(CGAL::LARGER);
|
||||
}
|
||||
b_.push_back(b_[index] + val);
|
||||
break;
|
||||
default:
|
||||
CGAL_qpe_assertion(false);
|
||||
}
|
||||
} else {
|
||||
warn1("range with identifier '%' ignored", ignored);
|
||||
}
|
||||
}
|
||||
|
||||
// determine if we need to read another number:
|
||||
doItAgain = i==0 && !whitespace();
|
||||
}
|
||||
|
||||
// read next token:
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::bounds_section()
|
||||
{
|
||||
std::string t = token();
|
||||
if (t != "BOUNDS") { // (Note: BOUNDS section is optional.)
|
||||
put_token_back(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
t = token();
|
||||
std::string bound_id;
|
||||
while (t != "QMATRIX" && t != "DMATRIX" && t != "QUADOBJ" && t != "ENDATA") {
|
||||
// process type of bound:
|
||||
enum Bound_type { LO, UP, FX, FR, MI, PL};
|
||||
Bound_type type;
|
||||
if (t=="LO")
|
||||
type = LO;
|
||||
else if (t=="UP")
|
||||
type = UP;
|
||||
else if (t=="FX")
|
||||
type = FX;
|
||||
else if (t=="FR")
|
||||
type = FR;
|
||||
else if (t=="MI")
|
||||
type = MI;
|
||||
else if (t=="PL")
|
||||
type = PL;
|
||||
else
|
||||
return
|
||||
err1("expected 'LO', 'UP', 'FX', 'FR', 'MI', or 'PL' here but found '%'",t);
|
||||
|
||||
// remember bound:
|
||||
const std::string bound = t;
|
||||
|
||||
// find bound label; there may be several, but we only process
|
||||
// the bounds having the first bound label that occurs. This
|
||||
// label may be empty, though
|
||||
t = token(); // bound label or variable name (case of empty bound label)
|
||||
if (bound_id.size() == 0) { // first time we see a bound label / variable?
|
||||
const Index_map::const_iterator var_name = var_names.find(t);
|
||||
if (var_name != var_names.end()) { // is the token a variable?
|
||||
bound_id = " "; // there is no bound label
|
||||
put_token_back(t); // the variable name is processed below
|
||||
} else
|
||||
bound_id = t; // we found a bound label
|
||||
} else {
|
||||
// now we already know the bound label
|
||||
if (bound_id == " ") // empty bound label?
|
||||
put_token_back(t); // the variable name is processed below
|
||||
else
|
||||
if (t != bound_id) {
|
||||
warn1("ignoring all bounds for bound label '%'",t);
|
||||
warn1("(only bounds for bound label '%' are accepted)",bound_id);
|
||||
}
|
||||
}
|
||||
|
||||
// find variable name;
|
||||
t = token();
|
||||
const Index_map::const_iterator var_name = var_names.find(t);
|
||||
if (var_name == var_names.end()) // unknown variable?
|
||||
return err1("unknown variable '%' in BOUNDS section",t);
|
||||
const unsigned int var_index = var_name->second;;
|
||||
|
||||
// read value of bound, if appropriate:
|
||||
IT val;
|
||||
if (type==LO || type==UP || type==FX)
|
||||
if (!number(val))
|
||||
return err2("expected number after '%' in % bound",t,bound);
|
||||
|
||||
// store bound:
|
||||
switch (type) {
|
||||
case FX:
|
||||
fu_[var_index] = true;
|
||||
u_ [var_index] = val;
|
||||
case LO:
|
||||
fl_[var_index] = true;
|
||||
l_ [var_index] = val;
|
||||
break;
|
||||
case UP:
|
||||
fu_[var_index] = true;
|
||||
u_ [var_index] = val;
|
||||
if (val <= 0 && fl_[var_index] == true && l_[var_index] == 0)
|
||||
if (val < 0 || !use_CPLEX_convention)
|
||||
fl_[var_index] = false;
|
||||
break;
|
||||
case FR:
|
||||
fu_[var_index] = false;
|
||||
fl_[var_index] = false;
|
||||
break;
|
||||
case MI:
|
||||
fl_[var_index] = false;
|
||||
break;
|
||||
case PL:
|
||||
fu_[var_index] = false;
|
||||
break;
|
||||
default:
|
||||
CGAL_qpe_assertion(false);
|
||||
}
|
||||
|
||||
// read next token:
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IT_, typename Is_linear_,
|
||||
typename Sparse_D_,
|
||||
typename Sparse_A_>
|
||||
bool QP_from_mps<IT_, Is_linear_,
|
||||
Sparse_D_,
|
||||
Sparse_A_>::qmatrix_section()
|
||||
{
|
||||
std::string t = token();
|
||||
if (t!="QMATRIX" && t!="DMATRIX" && t!="QUADOBJ") { // optional
|
||||
put_token_back(t);
|
||||
return true;
|
||||
}
|
||||
|
||||
// remember section name:
|
||||
D_section = t;
|
||||
const bool multiply_by_two = t=="DMATRIX";
|
||||
const bool only_get_lower_part = t =="QUADOBJ";
|
||||
|
||||
t = token();
|
||||
std::string bound_id;
|
||||
while (t != "ENDATA") {
|
||||
// find first variable name;
|
||||
const Index_map::const_iterator var1_name = var_names.find(t);
|
||||
if (var1_name == var_names.end()) // unknown variable?
|
||||
return err2("unknown first variable '%' in '%' section", t, D_section);
|
||||
const unsigned int var1_index = var1_name->second;;
|
||||
//std::cout << "qvar1 " << t << std::endl;
|
||||
|
||||
// find second variable name;
|
||||
t = token();
|
||||
const Index_map::const_iterator var2_name = var_names.find(t);
|
||||
if (var2_name == var_names.end()) // unknown variable?
|
||||
return err2("unknown second variable '%' in '%' section",t, D_section);
|
||||
const unsigned int var2_index = var2_name->second;;
|
||||
//std::cout << "qvar2 " << t << std::endl;
|
||||
|
||||
// read value:
|
||||
IT val;
|
||||
if (!number(val))
|
||||
return err1("expected number after '%' in section QMATRIX",t);
|
||||
|
||||
// multiply by two if approriate:
|
||||
if (multiply_by_two)
|
||||
val *= IT(2);
|
||||
|
||||
// mark problem as nonlinear if value is nonzero, and
|
||||
// bail out if we are supposed to read a linear program
|
||||
if (is_linear_ && !CGAL::is_zero(val)) {
|
||||
is_linear_ = false;
|
||||
if (has_linear_tag)
|
||||
return err1
|
||||
("nonzero value in '%' section while reading linear program",
|
||||
D_section);
|
||||
}
|
||||
|
||||
// set entry in D:
|
||||
set_entry_in_D(var1_index, var2_index, val, Sparse_D());
|
||||
if (only_get_lower_part)
|
||||
// duplicate entry if not on diagonal
|
||||
if (var1_index != var2_index)
|
||||
set_entry_in_D(var2_index, var1_index, val, Sparse_D());
|
||||
|
||||
// read next token:
|
||||
t = token();
|
||||
}
|
||||
put_token_back(t);
|
||||
|
||||
// now check symmetry
|
||||
unsigned int bad_i, bad_j;
|
||||
if (!is_symmetric(Sparse_D(), bad_i, bad_j)) {
|
||||
std::string bad_i_name = var_by_index[bad_i];
|
||||
std::string bad_j_name = var_by_index[bad_j];
|
||||
return
|
||||
err3("nonsymmetric '%' section for variables '%' and '%'",
|
||||
D_section, bad_i_name, bad_j_name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
|
@ -203,7 +203,7 @@ pricing_helper(int& direction, Tag_false /*is_in_standard_form*/)
|
|||
it != this->inactive_set_end(); ++it) {
|
||||
|
||||
// don't price basics/artificials
|
||||
CGAL_qpe_precondition (!this->solver().is_basic(*it));
|
||||
CGAL_qpe_assertion (!this->solver().is_basic(*it));
|
||||
if (this->solver().is_artificial( *it)) continue;
|
||||
|
||||
// compute mu_j
|
||||
|
|
|
|||
|
|
@ -173,8 +173,8 @@ template <typename NT>
|
|||
bool QP_pricing_strategy<Q, ET, Tags>::
|
||||
is_improving (int j, const NT& mu, const NT& nt0 ) const
|
||||
{
|
||||
CGAL_qpe_precondition(!this->solver().is_basic(j));
|
||||
CGAL_qpe_precondition(!this->solver().is_artificial(j));
|
||||
CGAL_qpe_assertion(!this->solver().is_basic(j));
|
||||
CGAL_qpe_assertion(!this->solver().is_artificial(j));
|
||||
if (this->solver().is_original(j)) {
|
||||
const Bound_index bnd_ind =
|
||||
this->solver().nonbasic_original_variable_bound_index(j);
|
||||
|
|
@ -207,8 +207,8 @@ template <typename NT>
|
|||
bool QP_pricing_strategy<Q, ET, Tags>::
|
||||
price_dantzig (int j, const NT& mu, const NT& nt0,
|
||||
int& min_j, NT& min_mu, int& direction) {
|
||||
CGAL_qpe_precondition(!this->solver().is_basic(j));
|
||||
CGAL_qpe_precondition(!this->solver().is_artificial(j));
|
||||
CGAL_qpe_assertion(!this->solver().is_basic(j));
|
||||
CGAL_qpe_assertion(!this->solver().is_artificial(j));
|
||||
if (this->solver().is_original(j)) {
|
||||
// original variable
|
||||
const Bound_index bnd_ind =
|
||||
|
|
|
|||
|
|
@ -1690,7 +1690,7 @@ void
|
|||
QP_solver<Q, ET, Tags>::
|
||||
enter_variable( )
|
||||
{
|
||||
CGAL_qpe_precondition (is_phaseII);
|
||||
CGAL_qpe_assertion (is_phaseII);
|
||||
CGAL_qpe_debug {
|
||||
vout2 << "--> nonbasic (" << variable_type( j) << ") variable "
|
||||
<< j << " enters basis" << std::endl << std::endl;
|
||||
|
|
@ -1711,7 +1711,7 @@ enter_variable( )
|
|||
// correct size). We check here
|
||||
// whether we need to enlarge
|
||||
// them.
|
||||
CGAL_qpe_precondition(minus_c_B.size() == B_O.size());
|
||||
CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
|
||||
minus_c_B.push_back(et0);
|
||||
q_x_O.push_back(et0);
|
||||
tmp_x .push_back(et0);
|
||||
|
|
@ -2184,7 +2184,7 @@ z_replace_variable_slack_by_original( )
|
|||
// correct size). We check here
|
||||
// whether we need to enlarge
|
||||
// them.
|
||||
CGAL_qpe_precondition(minus_c_B.size() == B_O.size());
|
||||
CGAL_qpe_assertion(minus_c_B.size() == B_O.size());
|
||||
minus_c_B.push_back(et0);
|
||||
q_x_O.push_back(et0);
|
||||
tmp_x .push_back(et0);
|
||||
|
|
@ -2950,8 +2950,8 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
set_pricing_strategy( Pricing_strategy *strategy)
|
||||
{
|
||||
CGAL_qpe_precondition( phase() != 1);
|
||||
CGAL_qpe_precondition( phase() != 2);
|
||||
CGAL_qpe_assertion( phase() != 1);
|
||||
CGAL_qpe_assertion( phase() != 2);
|
||||
|
||||
if (defaultStrategy != static_cast< Pricing_strategy*>( 0))
|
||||
delete defaultStrategy;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
multiply__A_CxN_O(Value_iterator out) const
|
||||
{
|
||||
CGAL_qpe_precondition(!check_tag(Is_nonnegative()));
|
||||
CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
|
||||
|
||||
// initialize with zero vector:
|
||||
std::fill_n(out, C.size(), et0);
|
||||
|
|
@ -157,7 +157,7 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
multiply__2D_OxN_O(Value_iterator out) const
|
||||
{
|
||||
CGAL_qpe_precondition(!check_tag(Is_nonnegative()));
|
||||
CGAL_qpe_assertion(!check_tag(Is_nonnegative()));
|
||||
|
||||
// initialize with zero vector:
|
||||
std::fill_n(out, B_O.size(), et0);
|
||||
|
|
@ -203,7 +203,7 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
init_r_B_O()
|
||||
{
|
||||
CGAL_qpe_precondition(!check_tag(Is_nonnegative()) &&
|
||||
CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
|
||||
!check_tag(Is_linear()));
|
||||
r_B_O.resize(B_O.size());
|
||||
multiply__2D_B_OxN_O(r_B_O.begin());
|
||||
|
|
@ -217,7 +217,7 @@ template < typename Q, typename ET, typename Tags >
|
|||
void QP_solver<Q, ET, Tags>::
|
||||
init_w()
|
||||
{
|
||||
CGAL_qpe_precondition(!check_tag(Is_nonnegative()) &&
|
||||
CGAL_qpe_assertion(!check_tag(Is_nonnegative()) &&
|
||||
!check_tag(Is_linear()));
|
||||
w.resize(qp_n);
|
||||
multiply__2D_OxN_O(w.begin());
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ template < typename Q, typename ET, typename Tags >
|
|||
ET QP_solver<Q, ET, Tags>::optimality_certificate_numerator(int i) const
|
||||
{
|
||||
// we use the vector lambda which conforms to C (basic constraints)
|
||||
CGAL_qpe_precondition (i >= 0);
|
||||
CGAL_qpe_precondition (i <= qp_m);
|
||||
CGAL_qpe_assertion (i >= 0);
|
||||
CGAL_qpe_assertion (i <= qp_m);
|
||||
if (no_ineq)
|
||||
return lambda[i];
|
||||
else {
|
||||
|
|
@ -710,7 +710,7 @@ bool QP_solver<Q, ET, Tags>::is_solution_unbounded() const
|
|||
// w^TDw = 0, (C11)
|
||||
// (c^T+2x^TD)w < 0. (C12)
|
||||
|
||||
CGAL_expensive_precondition(is_solution_feasible());
|
||||
CGAL_expensive_assertion(is_solution_feasible());
|
||||
|
||||
// get solution vector of original problem (multiplied by d):
|
||||
Values x(qp_n, et0);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ public:
|
|||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef typename Map::difference_type difference_type;
|
||||
typedef typename Map::mapped_type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type* pointer;
|
||||
typedef const value_type& reference;
|
||||
|
||||
typedef Fake_random_access_const_iterator Self;
|
||||
typedef difference_type Diff;
|
||||
|
|
@ -118,8 +118,8 @@ public:
|
|||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef Diff difference_type;
|
||||
typedef typename Op::result_type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type* pointer;
|
||||
typedef const value_type& reference;
|
||||
|
||||
typedef Transform_diff_const_iterator Self;
|
||||
typedef value_type Val;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <boost/iterator/zip_iterator.hpp>
|
||||
|
||||
#include <CGAL/Gmpq.h>
|
||||
#include <CGAL/MP_Float.h>
|
||||
#include <CGAL/QP_solver.h>
|
||||
#include <CGAL/QP_solver/QP_full_exact_pricing.h>
|
||||
#include <CGAL/QP_solver/QP_exact_bland_pricing.h>
|
||||
|
|
@ -37,13 +38,6 @@
|
|||
#include <CGAL/QP_models.h>
|
||||
#include <CGAL/QP_functions.h>
|
||||
|
||||
using CGAL::Tag_true;
|
||||
using CGAL::Tag_false;
|
||||
|
||||
typedef Tag_false Sparse_D;
|
||||
typedef Tag_false Sparse_A;
|
||||
typedef Tag_false Is_linear;
|
||||
|
||||
// Routines to output to MPS format:
|
||||
namespace QP_from_mps_detail {
|
||||
|
||||
|
|
@ -151,8 +145,7 @@ template<typename IT, // input number type
|
|||
typename ET> // exact number type compatible with IT (ET is used,
|
||||
// for instance, by QP in the query methods
|
||||
// has_equalities_only_and_full_rank())
|
||||
void create_shifted_instance(CGAL::QP_from_mps
|
||||
<IT, Is_linear, Sparse_D, Sparse_A>& qp,
|
||||
void create_shifted_instance(const CGAL::Quadratic_program_from_mps <IT>& qp,
|
||||
const char *file, // Note: "Bernd3" and
|
||||
// not "Bernd3.mps".
|
||||
const char *dir)
|
||||
|
|
@ -172,8 +165,8 @@ void create_shifted_instance(CGAL::QP_from_mps
|
|||
// where v = [1,...,n]^T.
|
||||
|
||||
// extract data from qp:
|
||||
const int n = qp.n();
|
||||
const int m = qp.m();
|
||||
const int n = qp.get_n();
|
||||
const int m = qp.get_m();
|
||||
|
||||
// offset vector:
|
||||
std::vector<IT> v(n);
|
||||
|
|
@ -184,13 +177,13 @@ void create_shifted_instance(CGAL::QP_from_mps
|
|||
std::vector<IT> Av(m, IT(0));
|
||||
for (int i=0; i<m; ++i)
|
||||
for (int j=0; j<n; ++j)
|
||||
Av[i] += qp.a()[j][i] * v[j];
|
||||
Av[i] += qp.get_a()[j][i] * v[j];
|
||||
|
||||
// compute - 2 v^T D into mvTD:
|
||||
std::vector<IT> mvTD(n, IT(0)); // -2D^Tv
|
||||
for (int i=0; i<n; ++i) {
|
||||
for (int j=0; j<n; ++j)
|
||||
mvTD[i] += qp.d()[j][i] * v[j];
|
||||
mvTD[i] += ( j <= i ? qp.get_d()[i][j] : qp.get_d()[j][i]) * v[j];
|
||||
mvTD[i] *= -1;
|
||||
}
|
||||
|
||||
|
|
@ -204,46 +197,30 @@ void create_shifted_instance(CGAL::QP_from_mps
|
|||
"", // deduce number-type
|
||||
"Shifted instance of original file",
|
||||
"master_mps_to_derivatives-create_shifted_instance",
|
||||
qp.problem_name(),
|
||||
qp.get_problem_name(),
|
||||
CGAL::make_quadratic_program_from_iterators(
|
||||
n,
|
||||
m,
|
||||
qp.a(),
|
||||
qp.get_a(),
|
||||
make_transform_iterator(
|
||||
make_zip_iterator(make_tuple(qp.b(),Av.begin())),
|
||||
make_zip_iterator(make_tuple(qp.get_b(),Av.begin())),
|
||||
tuple_add<IT>()),
|
||||
qp.r(),
|
||||
qp.fl(),
|
||||
qp.get_r(),
|
||||
qp.get_fl(),
|
||||
make_transform_iterator(
|
||||
make_zip_iterator(make_tuple(qp.l(),v.begin())),
|
||||
make_zip_iterator(make_tuple(qp.get_l(),v.begin())),
|
||||
tuple_add<IT>()),
|
||||
qp.fu(),
|
||||
qp.get_fu(),
|
||||
make_transform_iterator(
|
||||
make_zip_iterator(make_tuple(qp.u(),v.begin())),
|
||||
make_zip_iterator(make_tuple(qp.get_u(),v.begin())),
|
||||
tuple_add<IT>()),
|
||||
qp.d(),
|
||||
qp.get_d(),
|
||||
make_transform_iterator(
|
||||
make_zip_iterator(make_tuple(qp.c(),mvTD.begin())),
|
||||
make_zip_iterator(make_tuple(qp.get_c(),mvTD.begin())),
|
||||
tuple_add<IT>()),
|
||||
qp.c0()
|
||||
qp.get_c0()
|
||||
)
|
||||
);
|
||||
// n, m,
|
||||
// qp.a(),
|
||||
// make_transform_iterator(
|
||||
// make_zip_iterator(make_tuple(qp.b(),Av.begin())),
|
||||
// tuple_add<IT>()),
|
||||
// make_transform_iterator(
|
||||
// make_zip_iterator(make_tuple(qp.c(),mvTD.begin())),
|
||||
// tuple_add<IT>()), qp.c0(),
|
||||
// qp.d(), qp.fu(), qp.fl(),
|
||||
// make_transform_iterator(
|
||||
// make_zip_iterator(make_tuple(qp.u(),v.begin())),
|
||||
// tuple_add<IT>()),
|
||||
// make_transform_iterator(
|
||||
// make_zip_iterator(make_tuple(qp.l(),v.begin())),
|
||||
// tuple_add<IT>()),
|
||||
// qp.r());
|
||||
out->close();
|
||||
}
|
||||
|
||||
|
|
@ -251,8 +228,7 @@ template<typename IT, // input number type
|
|||
typename ET> // exact number type compatible with IT (ET is used,
|
||||
// for instance, by QP in the query methods
|
||||
// has_equalities_only_and_full_rank())
|
||||
void create_free_instance(CGAL::QP_from_mps<IT, Is_linear,
|
||||
Sparse_D, Sparse_A>& qp_,
|
||||
void create_free_instance(CGAL::Quadratic_program_from_mps<IT>& qp,
|
||||
const char *file, // Note: "Bernd3" and
|
||||
// not "Bernd3.mps".
|
||||
const char *dir)
|
||||
|
|
@ -266,78 +242,46 @@ void create_free_instance(CGAL::QP_from_mps<IT, Is_linear,
|
|||
// (and fl and fu are adjusted as well).
|
||||
|
||||
// extract data from qp:
|
||||
const unsigned int n = qp_.n();
|
||||
const unsigned int m = qp_.m();
|
||||
|
||||
// allocate storage (admittedly, I don't care about efficiency and
|
||||
// elegance here...):
|
||||
typedef CGAL::QP_from_mps<IT, Is_linear, Sparse_D, Sparse_A> QP_MPS;
|
||||
typedef typename QP_MPS::Vector Vector;
|
||||
typedef typename QP_MPS::B_iterator Vector_iterator;
|
||||
typedef typename QP_MPS::A_Matrix Matrix;
|
||||
typedef typename QP_MPS::A_Beginner A_Beginner;
|
||||
typedef typename QP_MPS::A_iterator A_iterator;
|
||||
typedef CGAL::Comparison_result Row_type;
|
||||
typedef typename QP_MPS::R_vector R_vector;
|
||||
|
||||
// copy the qp
|
||||
QP_MPS qp (qp_);
|
||||
|
||||
// copy some of its vectors (they get manipulated)
|
||||
Vector b = qp.b_vector();
|
||||
R_vector row_types = qp.r_vector();
|
||||
const unsigned int n = qp.get_n();
|
||||
unsigned int m = qp.get_m();
|
||||
|
||||
// add rows to A and corresponding entries to b:
|
||||
int nr_of_rows_added = 0;
|
||||
for (unsigned int i=0; i<n; ++i) {
|
||||
if (*(qp.fl()+i)) { // x >= l
|
||||
if (*(qp.get_fl()+i)) { // x >= l
|
||||
// add a row to A:
|
||||
for (unsigned int j=0; j<n; ++j)
|
||||
qp.add_entry_in_A (j, b.size(),(i==j? 1 : 0));
|
||||
//A[j].push_back(i==j? 1 : 0);
|
||||
qp.set_a (j, m, (i==j? 1 : 0));
|
||||
|
||||
// add corresponding entry to b:
|
||||
b.push_back(qp.l()[i]);
|
||||
qp.set_b(m, qp.get_l()[i]);
|
||||
|
||||
// add corresponding row type:
|
||||
row_types.push_back(CGAL::LARGER);
|
||||
|
||||
++nr_of_rows_added;
|
||||
qp.set_r(m, CGAL::LARGER);
|
||||
++m;
|
||||
}
|
||||
if (*(qp.fu()+i)) { // x <= u
|
||||
qp.set_l(i, false); // variable becomes free
|
||||
if (*(qp.get_fu()+i)) { // x <= u
|
||||
// add a row to A:
|
||||
for (unsigned int j=0; j<n; ++j)
|
||||
qp.add_entry_in_A (j, b.size(),(i==j? 1 : 0));
|
||||
//A[j].push_back(i==j? 1 : 0);
|
||||
qp.set_a (j, m ,(i==j? 1 : 0));
|
||||
|
||||
// add corresponding entry to b:
|
||||
b.push_back(qp.u()[i]);
|
||||
qp.set_b(m, qp.get_u()[i]);
|
||||
|
||||
// add corresponding row type:
|
||||
row_types.push_back(CGAL::SMALLER);
|
||||
|
||||
++nr_of_rows_added;
|
||||
qp.set_r(m, CGAL::SMALLER);
|
||||
++m;
|
||||
}
|
||||
qp.set_u(i, false); // variable becomes free
|
||||
}
|
||||
|
||||
// output:
|
||||
std::auto_ptr<std::ofstream> out = create_output_file(file, dir, "free");
|
||||
write_MPS(*out,
|
||||
"", // deduce number-type
|
||||
"Freed instance of original file",
|
||||
"master_mps_to_derivatives-create_free_instance",
|
||||
qp.problem_name(),
|
||||
CGAL::make_quadratic_program_from_iterators (
|
||||
n, m+nr_of_rows_added,
|
||||
A_iterator(qp.A_matrix().begin(),A_Beginner()),
|
||||
b.begin(),
|
||||
row_types.begin(),
|
||||
CGAL::Const_oneset_iterator<bool>(false), // fl
|
||||
qp.l(), // dummy
|
||||
CGAL::Const_oneset_iterator<bool>(false), // fu
|
||||
qp.u(), // dummy
|
||||
qp.d(),
|
||||
qp.c(), qp.c0()));
|
||||
qp.get_problem_name(),
|
||||
qp);
|
||||
out->close();
|
||||
}
|
||||
|
||||
|
|
@ -364,20 +308,19 @@ bool create_derivatives(const char *path,
|
|||
}
|
||||
|
||||
// load QP instance:
|
||||
const int verbosity = 5;
|
||||
typedef typename QP_from_mps_detail::IT_to_ET<IT>::ET ET;
|
||||
typedef CGAL::QP_from_mps<IT, Is_linear, Sparse_D, Sparse_A> QP;
|
||||
QP qp(f,true,verbosity);
|
||||
typedef CGAL::Quadratic_program_from_mps<IT> QP;
|
||||
QP qp(f);
|
||||
|
||||
// check for format errors in MPS file:
|
||||
if (!qp.is_valid()) {
|
||||
msg = "Input is not a valid MPS file: " + qp.error();
|
||||
msg = "Input is not a valid MPS file: " + qp.get_error();
|
||||
return false;
|
||||
}
|
||||
cerr << " MPS-file successfully input.\n";
|
||||
|
||||
// no derivatives if comment says so
|
||||
if (qp.comment().find(std::string("Derivatives: none"))!=std::string::npos)
|
||||
if (qp.get_comment().find(std::string("Derivatives: none"))!=std::string::npos)
|
||||
cerr << " No derivatives made.\n";
|
||||
else {
|
||||
// derivates:
|
||||
|
|
|
|||
|
|
@ -55,13 +55,13 @@ int main(const int argNr,const char **args) {
|
|||
#else
|
||||
typedef CGAL::Gmpz ET;
|
||||
#endif
|
||||
typedef CGAL::QP_from_mps<IT, CGAL::Tag_false, CGAL::Tag_true> QP;
|
||||
QP qp(std::cin,true,verbosity);
|
||||
typedef CGAL::Quadratic_program_from_mps<IT> QP;
|
||||
QP qp(std::cin);
|
||||
|
||||
// check for format errors in MPS f\ile:
|
||||
if (!qp.is_valid()) {
|
||||
cout << "Input is not a valid MPS file." << endl
|
||||
<< "Error: " << qp.error() << endl;
|
||||
<< "Error: " << qp.get_error() << endl;
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
|
|
@ -84,8 +84,8 @@ int main(const int argNr,const char **args) {
|
|||
cout << "Variable values:" << endl;
|
||||
Solver::Variable_value_iterator it
|
||||
= s.original_variable_values_begin() ;
|
||||
for (int i=0; i < qp.n(); ++it, ++i)
|
||||
cout << " " << qp.name_of_variable(i) << " = "
|
||||
for (int i=0; i < qp.get_n(); ++it, ++i)
|
||||
cout << " " << qp.get_name_of_variable(i) << " = "
|
||||
<< CGAL::to_double(*it) << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/QP_models.h>
|
||||
#include <CGAL/QP_functions.h>
|
||||
|
||||
// choose exact integral type
|
||||
#ifndef CGAL_USE_GMP
|
||||
#include <CGAL/MP_Float.h>
|
||||
typedef CGAL::MP_Float ET;
|
||||
#else
|
||||
#include <CGAL/Gmpz.h>
|
||||
typedef CGAL::Gmpz ET;
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
CGAL::Quadratic_program<int> qp; // no variables, no constraints
|
||||
assert (qp.is_valid());
|
||||
|
||||
CGAL::Quadratic_program_solution<ET> s =
|
||||
CGAL::solve_quadratic_program (qp, ET());
|
||||
|
||||
std::cout << "Solution = " << s.solution() << std::endl;
|
||||
std::cout << "Status = " << s.status() << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -337,23 +337,15 @@ bool process(const std::string& filename,
|
|||
// extract verbosity:
|
||||
const int verbosity = options.find("Verbosity")->second;
|
||||
|
||||
// read QP instance, first using dense representation:
|
||||
// read QP instance
|
||||
std::ifstream in(filename.c_str());
|
||||
if (!in)
|
||||
bailout1("could not open file '%'",filename);
|
||||
typedef CGAL::Quadratic_program_from_mps <IT> QP_instance;
|
||||
QP_instance qp(in,true,verbosity);
|
||||
QP_instance qp(in);
|
||||
in.close();
|
||||
|
||||
// then read it again, using sparse representation
|
||||
std::ifstream in2(filename.c_str());
|
||||
if (!in2)
|
||||
bailout1("could not open file '%'",filename);
|
||||
typedef CGAL::Sparse_quadratic_program_from_mps <IT> Sparse_QP_instance;
|
||||
Sparse_QP_instance qp2(in2,true,verbosity);
|
||||
in2.close();
|
||||
|
||||
std::string comment = qp.comment();
|
||||
std::string comment = qp.get_comment();
|
||||
|
||||
// check for the number-type:
|
||||
Input_type type;
|
||||
|
|
@ -402,26 +394,13 @@ bool process(const std::string& filename,
|
|||
(is_rational(ET())? "Gmpq" : "Double"))
|
||||
<< endl;
|
||||
|
||||
// check for format errors in MPS file (dense):
|
||||
// check for format errors in MPS file:
|
||||
if (!qp.is_valid()) {
|
||||
cout << "Input is not a valid MPS file." << endl
|
||||
<< "Error: " << qp.error() << endl;
|
||||
<< "Error: " << qp.get_error() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for format errors in MPS file (sparse):
|
||||
if (!qp2.is_valid()) {
|
||||
cout << "Input is not a valid MPS file." << endl
|
||||
<< "Error: " << qp2.error() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare qp1, qp2
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
|
||||
cout << "Dense/Sparse readers disagree.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// print program (using QMATRIX format), read it back in and check
|
||||
// whether it still agrees with the original program
|
||||
std::stringstream inout;
|
||||
|
|
@ -430,100 +409,58 @@ bool process(const std::string& filename,
|
|||
CGAL::QP_functions_detail::print_program
|
||||
(inout, qp, std::string("test_io_mps"),
|
||||
Is_linear(),Is_nonnegative());
|
||||
QP_instance qp3(inout, true, verbosity);
|
||||
CGAL_qpe_assertion (qp3.is_valid());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp3)) {
|
||||
cout << "Warning: MPS reader and MPS writer disagree.\n" << endl;
|
||||
}
|
||||
|
||||
// copy program and check whether it is still the same
|
||||
if (!qp.is_linear() && !qp.is_nonnegative()) {
|
||||
CGAL::Quadratic_program<IT> qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
|
||||
qp.fl(), qp.l(), qp.fu(), qp.u(),
|
||||
qp.d(), qp.c(), qp.c0());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
|
||||
cout << "Program not correctly copied.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
// test default/copy constructor, assignment
|
||||
CGAL::Quadratic_program<IT> qp5;
|
||||
qp5 = qp4;
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
|
||||
cout << "Program not correctly assigned.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
CGAL::Quadratic_program<IT> qp6 (qp4);
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
|
||||
cout << "Program not correctly copy-constructed.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (qp.is_linear() && !qp.is_nonnegative()) {
|
||||
CGAL::Linear_program<IT> qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
|
||||
qp.fl(), qp.l(), qp.fu(), qp.u(),
|
||||
qp.c(), qp.c0());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
|
||||
cout << "Program not correctly copied.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
// test default/copy constructor, assignment
|
||||
CGAL::Linear_program<IT> qp5;
|
||||
qp5 = qp4;
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
|
||||
cout << "Program not correctly assigned.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
CGAL::Linear_program<IT> qp6 (qp4);
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
|
||||
cout << "Program not correctly copy-constructed.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!qp.is_linear() && qp.is_nonnegative()) {
|
||||
CGAL::Nonnegative_quadratic_program<IT>
|
||||
qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
|
||||
qp.d(), qp.c(), qp.c0());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
|
||||
cout << "Program not correctly copied.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
// test default/copy constructor, assignment
|
||||
CGAL::Nonnegative_quadratic_program<IT> qp5;
|
||||
qp5 = qp4;
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
|
||||
cout << "Program not correctly assigned.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
CGAL::Nonnegative_quadratic_program<IT> qp6 (qp4);
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
|
||||
cout << "Program not correctly copy-constructed.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// test all four readers
|
||||
if (qp.is_linear() && qp.is_nonnegative()) {
|
||||
CGAL::Nonnegative_linear_program<IT>
|
||||
qp4 (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
|
||||
qp.c(), qp.c0());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
|
||||
cout << "Program not correctly copied.\n" << endl;
|
||||
return false;
|
||||
CGAL::Nonnegative_linear_program_from_mps<IT> qp2(inout);
|
||||
CGAL_qpe_assertion (qp2.is_valid());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
|
||||
cout << "Warning: MPS reader (NLP) and MPS writer disagree.\n" << endl;
|
||||
}
|
||||
// test default/copy constructor, assignment
|
||||
CGAL::Nonnegative_linear_program<IT> qp5;
|
||||
qp5 = qp4;
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp5, qp4)) {
|
||||
cout << "Program not correctly assigned.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
if (qp.is_linear() && !qp.is_nonnegative()) {
|
||||
CGAL::Linear_program_from_mps<IT> qp2(inout);
|
||||
CGAL_qpe_assertion (qp2.is_valid());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
|
||||
cout << "Warning: MPS reader (LP) and MPS writer disagree.\n" << endl;
|
||||
}
|
||||
CGAL::Nonnegative_linear_program<IT> qp6 (qp4);
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp6, qp4)) {
|
||||
cout << "Program not correctly copy-constructed.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
if (!qp.is_linear() && !qp.is_nonnegative()) {
|
||||
CGAL::Quadratic_program_from_mps<IT> qp2(inout);
|
||||
CGAL_qpe_assertion (qp2.is_valid());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
|
||||
cout << "Warning: MPS reader (QP) and MPS writer disagree.\n" << endl;
|
||||
}
|
||||
}
|
||||
if (!qp.is_linear() && qp.is_nonnegative()) {
|
||||
CGAL::Nonnegative_quadratic_program_from_mps<IT> qp2(inout);
|
||||
CGAL_qpe_assertion (qp2.is_valid());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp2)) {
|
||||
cout << "Warning: MPS reader (NQP) and MPS writer disagree.\n" << endl;
|
||||
}
|
||||
}
|
||||
// now copy from the iterators, check for equality
|
||||
CGAL::Quadratic_program_base<IT>
|
||||
qp4 (qp.get_n(), qp.get_m(), qp.get_a(), qp.get_b(), qp.get_r(),
|
||||
qp.get_fl(), qp.get_l(), qp.get_fu(), qp.get_u(),
|
||||
qp.get_d(), qp.get_c(), qp.get_c0());
|
||||
if (!CGAL::QP_functions_detail::are_equal_qp (qp, qp4)) {
|
||||
cout << "Program not correctly copied.\n" << endl;
|
||||
return false;
|
||||
}
|
||||
// test consistency of types
|
||||
if (qp.is_linear() != qp4.is_linear()) {
|
||||
cout << "Program types inconsistent (linearity): "
|
||||
<< qp.is_linear() << " vs. " << qp4.is_linear()
|
||||
<< "\n"<< endl;
|
||||
return false;
|
||||
}
|
||||
if (qp.is_nonnegative() != qp4.is_nonnegative()) {
|
||||
cout << "Program types inconsistent (nonnegativity): "
|
||||
<< qp.is_nonnegative() << " vs. " << qp4.is_nonnegative()
|
||||
<< "\n"<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef CGAL::QP_solver_impl::QP_tags<Is_linear,Is_nonnegative> Tags;
|
||||
|
||||
|
|
@ -548,14 +485,15 @@ bool process(const std::string& filename,
|
|||
// general form
|
||||
typedef CGAL::QP_solver_impl::QP_tags<CGAL::Tag_false,CGAL::Tag_false>
|
||||
LocalTags;
|
||||
typedef CGAL::Quadratic_program<IT>
|
||||
typedef CGAL::Quadratic_program_base<IT>
|
||||
LocalQP;
|
||||
CGAL::QP_pricing_strategy<LocalQP, ET, LocalTags> *slocal = new
|
||||
CGAL::QP_full_exact_pricing <LocalQP, ET, LocalTags>();
|
||||
|
||||
LocalQP qplocal (qp.n(), qp.m(), qp.a(), qp.b(), qp.r(),
|
||||
qp.fl(), qp.l(), qp.fu(), qp.u(),
|
||||
qp.d(), qp.c(), qp.c0());
|
||||
LocalQP qplocal (qp.get_n(), qp.get_m(), qp.get_a(), qp.get_b(),
|
||||
qp.get_r(),
|
||||
qp.get_fl(), qp.get_l(), qp.get_fu(), qp.get_u(),
|
||||
qp.get_d(), qp.get_c(), qp.get_c0());
|
||||
CGAL::QP_solver<LocalQP, ET, LocalTags> solverlocal (qplocal, slocal, 0);
|
||||
std::cout << "(c) ";
|
||||
delete slocal;
|
||||
|
|
|
|||
Loading…
Reference in New Issue