Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fractional Chromatic Index test fails with GLPK #23798

Open
jdemeyer opened this issue Sep 7, 2017 · 47 comments
Open

Fractional Chromatic Index test fails with GLPK #23798

jdemeyer opened this issue Sep 7, 2017 · 47 comments

Comments

@jdemeyer
Copy link

jdemeyer commented Sep 7, 2017

The test

            sage: g = graphs.PetersenGraph()
            sage: g.fractional_chromatic_index(solver='GLPK')
            3.0

added in src/sage/graphs/graph.py by #23658 fails with GLPK-4.63 on 32-bit.

As a workaround, we use PPL by default in #24099.

CC: @dcoudert

Component: graph theory

Author: David Coudert

Branch/Commit: public/graphs/23798_fractional_chromatic_index @ 43e8873

Reviewer: Dima Pasechnik

Issue created by migration from https://trac.sagemath.org/ticket/23798

@jdemeyer jdemeyer added this to the sage-8.1 milestone Sep 7, 2017
@jdemeyer

This comment has been minimized.

@jdemeyer

This comment has been minimized.

@jdemeyer jdemeyer changed the title Fractional Chromatic Index Infinite Loop fails with GLPK Fractional Chromatic Index test fails with GLPK Sep 7, 2017
@dcoudert
Copy link
Contributor

dcoudert commented Sep 7, 2017

comment:3

I suspect that we need to change if M.solve(log = verbose) <= 1: to if M.solve(log = verbose) <= 1 + tol:, where tol = 0 if solver=='PPL' else 1e-6. I don't like this solution, but I don't know what else we can do.

I don't have access to a 32-bit machine and so cannot test.

@jdemeyer
Copy link
Author

jdemeyer commented Sep 7, 2017

comment:4

You could also forbid using a non-exact solver for this problem.

@dcoudert
Copy link
Contributor

dcoudert commented Sep 7, 2017

comment:5

Sure, we can force PPL, but it is way slower (can sometimes be faster on small graphs).

sage: G = graphs.Grid2dGraph(6,6)
sage: %time G.fractional_chromatic_index(solver='GLPK')
CPU times: user 43.4 ms, sys: 4.9 ms, total: 48.3 ms
Wall time: 52.1 ms
4.0
sage: %time G.fractional_chromatic_index(solver='PPL')
CPU times: user 1min 11s, sys: 256 ms, total: 1min 11s
Wall time: 1min 12s
4

I agree that using a tolerance gap is not a nice solution either.

@dcoudert
Copy link
Contributor

comment:6

I don't see better solution than making PPL the default solver here.


New commits:

7485007trac #23798: set PPL has default solver

@dcoudert
Copy link
Contributor

Commit: 7485007

@dcoudert
Copy link
Contributor

Author: David Coudert

@dcoudert
Copy link
Contributor

Branch: u/dcoudert/23798

@jdemeyer
Copy link
Author

comment:7

"Be aware that this method may loop endlessly when using some non exact solvers on 32-bits". I doubt that this is problem specific to 32 bits. The wording seems to imply that it's safe to use non-exact solvers on 64-bit machines.

@jdemeyer
Copy link
Author

comment:8

Also, this isn't quite correct:

Tickets :trac:`23658` and :trac:`23798` are fixed::

followed by a test with GLPK.

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 22, 2017

Changed commit from 7485007 to 910fb83

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Oct 22, 2017

Branch pushed to git repo; I updated commit sha1. New commits:

910fb83trac #23798: reviewers comments

@dcoudert
Copy link
Contributor

comment:10

Is this more appropriate ?

@jdemeyer
Copy link
Author

comment:11

Well, it depends. Do you consider the code here to be a fix or a workaround? I am asking because you need to decide what to do with

sage: g.fractional_chromatic_index(solver='GLPK') # known bug (#23798)

You cannot say that this ticket is a known bug while at the same time fixing this ticket.

@dcoudert
Copy link
Contributor

comment:13

The problem is not fixed. That's why I changed the text to Issue reported in :trac:`23658` and :trac:`23798` with non exact solvers::. What else can I write to be more correct/specific?

@jdemeyer
Copy link
Author

Changed commit from 910fb83 to none

@jdemeyer

This comment has been minimized.

@dcoudert
Copy link
Contributor

comment:27

Following above discussion, I added a tolerance gap for numerical LP solvers.

Note that we can use the networkx implementation of the blossom algorithm via the matching method, but it does not solve the issue. Actually, it's slower and worse for the rounding as I observe the issue on a 64 bits machine...


New commits:

ebcde7ctrac #23798: add tolerance gap for numerical LP solvers

@dimpase
Copy link
Member

dimpase commented Jul 13, 2021

comment:28

I don’t like this approach. Without explicit guarantees that these tolerances are correct, it is replacing correct algorithms with heuristics.

@mkoeppe
Copy link
Member

mkoeppe commented Jul 13, 2021

comment:29
         matching = [fe for fe in frozen_edges if M.get_values(b[fe]) == 1]

This line also needs changing because the test "== 1" is not robust.

@dimpase
Copy link
Member

dimpase commented Jul 13, 2021

comment:30

I don’t see how one can make the oracle (the inner LP) inexact, without potentially returning a very wrong answer.

The oracle checks that there is no maximum weight matching of weight >1. Say, we let it error by epsilon, i.e we terminate with oracle returning 1+epsilon. Potentially, there could be K maximum matchings with this weight, if they are disjoint this means that the final error is K times epsilon, oops…

@dimpase
Copy link
Member

dimpase commented Jul 13, 2021

Reviewer: Dima Pasechnik

@dcoudert
Copy link
Contributor

comment:32

I don't like this solution either but I don't know what to do when a solver returns 0.99999... instead of 1 although we have set the variable type to binary. The solvers are aware of the type of the variable and so should return a value with the correct type and not a double. The solution might be in the backends.

@dimpase
Copy link
Member

dimpase commented Jul 14, 2021

comment:33

Replying to @dcoudert:

I don't like this solution either but I don't know what to do when a solver returns 0.99999... instead of 1 although we have set the variable type to binary. The solvers are aware of the type of the variable and so should return a value with the correct type and not a double. The solution might be in the backends.

No, my point is that without a special analysis it's not possible to argue that solving the oracle problem (with non-integer objective function) inexactly provides a correct result, even if you "correctly" round 0.9999... to 1. It's because a small oracle error may get amplified a lot in the main LP.
Welcome to floating point hell :-)|

@dimpase
Copy link
Member

dimpase commented Jul 15, 2021

comment:34

Replying to @dcoudert:

Following above discussion, I added a tolerance gap for numerical LP solvers.

Note that we can use the networkx implementation of the blossom algorithm via the matching method, but it does not solve the issue. Actually, it's slower and worse for the rounding as I observe the issue on a 64 bits machine...

The oracle implementation here is naive, and bound to get very slow; it's integer LP without Edmonds' constraints,
instead of a "normal" LP over the matching polytope with Edmonds' constraints (aka blossom inequalities).
So this would need yet another oracle (as there are too exponentially many inequalities there), but well, it's polynomial time then.
The generated constraints can stay, so this should be fast.


New commits:

ebcde7ctrac #23798: add tolerance gap for numerical LP solvers

@mkoeppe
Copy link
Member

mkoeppe commented Jul 19, 2021

comment:35

I took a quick look at the function now. I would suggest the following changes:

  1. Before adding a new constraint to the master problem, verify that matching is indeed a matching. In this way, the master problem will always be a correct relaxation, even if an inexact oracle is used.

  2. When the numerical solver that is used for solving the separation problem does not find a matching of value greater than 1 + epsilon, you can switch to PPL - then, with a bit of luck, it can prove the bound <= 1.

  3. It will make sense to have separate parameters for the solver used for the master problem and the one(s) used for the separation problem.

@dimpase
Copy link
Member

dimpase commented Jul 19, 2021

comment:36

Actually, it seems that even with PPL, the code is just wrong, as PPL does not do MILP, it only does LP, right?

@mkoeppe
Copy link
Member

mkoeppe commented Jul 19, 2021

comment:37

The PPL does have a (very limited) MIP solver.

@mkoeppe mkoeppe modified the milestones: sage-9.4, sage-9.5 Aug 9, 2021
@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 6, 2021

Branch pushed to git repo; I updated commit sha1. New commits:

1926be5trac #23798: merged with 9.5.beta5
43e8873trac #23798: ideas from comment 35

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Nov 6, 2021

Changed commit from ebcde7c to 43e8873

@dcoudert
Copy link
Contributor

dcoudert commented Nov 6, 2021

comment:40

I tried the ideas from #comment:35. I have let some code for debugging as the code may loop forever when using GLPK for both master and separation problems. The patchbot will complain...

We should search for another method not relying on LP solvers, if any...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants