Hi guys,

It's been a while since I raised this issue. I actually solved this and I
want to contribute it back.
I implemented a new public method in SimplexSolver called optimizeExtra,
that returns a SimplexSolution containing:

1) PointValuePair solution;
   The optimal solution.

2) HashMap<LinearConstraint, ExtraConstraintInfo> extraConstraintInfo;
   A mapping of the user created LinearConstraints to a class containing
the constraint's RHS sensitivity and shadow price.

3) CoefficientBounds[] coefficientSensitivity;
   The sensitivity of each coefficient in the objective function.

I believe that the code is good, mathematically speaking, because I checked
the results (both manually and automatically) against another library.
But, since this was done in a certain problem domain, there may still be
bugs in untested scenarios.
Unfortunately, I can't bring those automated tests without bringing a lot
of code related to that domain. We also checked the results after some
post-processing that could mask some very palpable errors, making those
tests unsuitable for general testing.
I'll implement new end-to-end tests.

I just created a fork at https://github.com/cherullo/commons-math. I'll
email you guys as soon as I finish merging my changes so we can discuss
this further.

I saw that the SolutionCallback was implemented. Since my approach also has
it's merits, I'll try my best to merge both.
Comments are welcome :-)

  []s Renato C.








On Tue, Sep 10, 2013 at 2:42 AM, Thomas Neidhart
<thomas.neidh...@gmail.com>wrote:

> On 09/09/2013 10:37 PM, Thomas Neidhart wrote:
> > On 09/09/2013 09:02 PM, Renato Cherullo wrote:
> >> Hi all,
> >>
> >> I need to implement a way to recover some important information from
> >> SimplexSolver's final tableau.
> >> I'll start by the shadow price, which seems very straight forward. If I
> >> understand it correctly, I must:
> >> 1- Store the original LinearConstraints in the same order as the
> normalized
> >> constraints.
> >>    The LinearConstraintSet stores the constraints in a HashSet, so care
> >> must be taken to ensure ordering.
> >> 2- After the optimization, given a constraint, I must determine the
> >> tableau's column relative to the constraint's slack variable and return
> the
> >> value on the objective function row.
> >>    The column index should be getSlackVariableOffset() plus the number
> of
> >> LEQ and GEQ constraints present in the original constraints list before
> the
> >> given constraint.
> >>
> >> I'm kinda new to the Simplex method, so this may be wrong too. Looking
> at
> >> the code, I think that the logic in (2) should be implemented in
> >> SimplexSolver, but I'm not sure about (1), since:
> >>
> >> A- SimplexSolver doesn't store the SimplexTableau instance used during
> >> optimization. Since SS is immutable, it really shouldn't. So I must
> return
> >> the shadow price of every constraint along the optimal PointValuePair,
> >> creating another overload of the doOptimize method (or some other new
> >> method).
> >
> > There are related requests from other users (see MATH-970), which want
> > to retrieve the best solution found so far in case the optimization
> > reaches the iteration limit. Right now it is not possible to retrieve
> > the last computed tableau but we will need to change that in some way.
> >
> > When we have this, adding a method to retrieve the index of the slack
> > variable should be trivial.
>
> One way to achieve this without breaking the current API would be to
> define a separate OptimizationData object that acts as a callback:
>
> e.g. SolutionCallback, with an interface like this:
>
> updateTableau(SimplexTableau t)
>
> this callback will be called every iteration step and can be provided in
> the call to optimize.
>
> The last solution can be retrieved from the tableau via getSolution().
>
> Thomas
>
> >> B- I'm not confident enough that iterating a HashSet is fully
> >> deterministic, nothing in the contracts says so. If it's really not
> >> deterministic, then I'd have to copy the original constraints in the
> same
> >> foreach-loop that builds the normalized constraints list inside
> >> SimplexTableau (from the HashSet in LinearConstraintSet). Normalization
> >> happens in the normalizeConstraints method, and it returns a List right
> >> into the final "constraints" field. To have both lists populated in the
> >> same loop and placed in final fields, the loop would have to be in the
> >> constructor. Kinda ugly...
> >
> > the iteration order for a HashSet is still deterministic (as long as you
> > do not modify the set itself of course), but only inside a running vm.
> > Running the same example might lead to different results for different
> > vms, thus I was proposing to change the LinearConstraintSet to use a
> > LinkedHashSet internally as it will simplify analyzing and debugging
> > problems reported by users.
> >
> > btw. the constraints were provided as a plain list prior to the
> > refactoring that resulted in the current API available in the optim
> package.
> >
> >> So, any comments about the Simplex method and coding will be greatly
> >> appreciated.
> >> I'm a mathematician and programmer (much more the later than the
> former),
> >> but I'm not well versed in Java's idiosyncrasies, and I'm new to
> >> participating in the FOSS community. I want to do this, and so any
> guidance
> >> will be appreciated :-)
> >
> > Welcome to the commons community!
> >
> > Before starting to create patches, you might want to read the developers
> > guide:
> >
> > http://commons.apache.org/proper/commons-math/developers.html
> >
> > If you other questions, do not hesitate to raise them on the mailinglist.
> >
> > Thomas
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> For additional commands, e-mail: dev-h...@commons.apache.org
>
>

Reply via email to