Code Monkey home page Code Monkey logo

Comments (11)

sccolbert avatar sccolbert commented on July 1, 2024 1

Kiwi is an LP solver, so if it's finding a solution that satisfies the constraints, then by definition it's not a bug. If there is more than one possible solution, then your system is under-constrained. When that happens, the only guarantee the solver makes is that it will find "a solution", which is not necessarily the optimal solution. Which solution you get in those cases will depend upon the nature of your constraints and the order in which you add them to the solver, but it's probably better to just assume the solution chosen will be "random". Kiwi is really designed to be used for LP problems where there is only one possible solution. As @MatthieuDartiailh mentioned, you can achieve this for ambiguous systems by setting some weights on various constraints to force the objective function to optimize for your desired semantics.

from kiwi.

MatthieuDartiailh avatar MatthieuDartiailh commented on July 1, 2024 1

@jklymak the segfault is resolved in 1.1.0

from kiwi.

MatthieuDartiailh avatar MatthieuDartiailh commented on July 1, 2024

Hi,
I never took the time to look at #15 because I am not comfortable with the solver internals, but since I am trying to improve the tests and document the project I hope to be able to look at it in the coming months.
You may try to add weak constraints or weak EditVariables to help the solver get a consistent solution. I hope to be able to give you a more complete answer soon.

from kiwi.

sccolbert avatar sccolbert commented on July 1, 2024

I'm going to close this as the solver is working as expected. If you find a reproducible problem where you are getting incorrect results, please do open a new issue.

from kiwi.

jklymak avatar jklymak commented on July 1, 2024

Thanks @sccolbert; I agree this is not a bug per-se...

I think the general issue is probably how I've implimented the constraints. I'm laying out boxes. For a horizontal layout I've done something like:

A.width = A.right - A.left
B.width = B.right - B.left

A.right < B.left - pad 

# make boxes same width
A.width == B.width

# make boxes be inside Parent
A.left >= Parent.left
A.right <= Parent.right

B.left >= Parent.left
B.right <= Parent.right

# define width of parent
Parent.left == 0
Parent.right == 1

Thats obviously under-constrained, so then I also add a weak constraint that A.width == 1 and B.width==1 in order to get them to be as big as possible. A better constraint would be that
A.width + B.width + pad = 1. but the real structure is heavily nested, so its not trivial to keep track of what should add up to 1 (though perhaps I should just go back and do that).

Any other hints on what we should be doing would be welcome. In general the solver works great, and the occasionally failing test is truly a peverse case, but I thought I'd ask about it here.

from kiwi.

sccolbert avatar sccolbert commented on July 1, 2024

Here's how we generate box constraints in Enaml. It's a bit abstract since it operates on both vertical/horizontal orientations, and has a couple levels of indirection, but I'm sure you can follow it after a bit of study. Let me know if you want me to explain any part of it:

https://github.com/nucleic/enaml/blob/master/enaml/layout/linear_box_helper.py#L120

That helper class is used internally by some convenience functions:

https://github.com/nucleic/enaml/blob/master/enaml/layout/layout_helpers.py#L49

Which allows you to specify constraints like this (in Enaml syntax):

enamldef Main(Window):
    Container:
        constraints = [
            hbox(pb1, pb2, pb3)
        ]
        PushButton: pb1:
            text = 'Spam'
        PushButton: pb2:
            text = 'Long Name Foo'
        PushButton: pb3:
            text = 'Bar'

from kiwi.

sccolbert avatar sccolbert commented on July 1, 2024

Enaml uses a nestable model as well, and constraints generation propagates by passing the parent "constrainable" component to the nested helpers, so that those helpers can use the parent as the bounding box. Since each leaf component has a "preferred size" the system is able to solve from the bottom-up and size the parents based on the required space of the children.

from kiwi.

sccolbert avatar sccolbert commented on July 1, 2024

For example:
https://github.com/nucleic/enaml/blob/master/examples/layout/advanced/nested_boxes.enaml

from kiwi.

jklymak avatar jklymak commented on July 1, 2024

Cool, thanks a lot! I should have read this sort of thing before looking at doing the matplotlib layout, but sometimes only fools rush in...

Our problem is the inverse, where the children don't have an a-priori prefered size, but we want to make them as big as possible, and still fit in the figure and not overlap with the other children.

But, not to give the wrong impression - what we have seems to work really well 99.9% of the time, and it totally would not have been possible without your great work here. But I just wanted to touch base on some best practices to see if we could improve what we are doing and make the solver a little happier, so thanks a lot for the links.

from kiwi.

jklymak avatar jklymak commented on July 1, 2024

https://matplotlib.org/tutorials/intermediate/constrainedlayout_guide.html if you want an overview...

from kiwi.

sccolbert avatar sccolbert commented on July 1, 2024

I would still use the "spacer" approach like we have in Enaml for your layouts. In this case, the spacers would each have a known size, and the various leaf components would have solved sizes and perhaps weak constraints to set their proportions relative to their siblings. The only other fixed sizes would be the root layout box. The solver would then spit out the solution for all of the children.

from kiwi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.