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

Refocus examples on OptaPlanner by bringing back the good old *App #239

Open
holgerbrandl opened this issue Dec 4, 2021 · 7 comments
Open
Assignees

Comments

@holgerbrandl
Copy link

The new examples put too much focus on system integration with quarkus. In fact, they hide the underlying optaplanner concepts to an extent that new users may not understand the API. Or are simply overwhelmed with quarkus complexity, and move on to OR tooling that has a lower entry barrier in its introductory examples.

Don't get me wrong, the demos and their great web interfaces are just awesome. However, they imho don't educate on how to use optaplanner in the same simplistic way the old demos did. They are more integration examples than quickstarts, which I'd expect to also quick to understand and not just quick to run.

Most importantly quarkus quickstarts lack a solverconfig, which accordingly to the docs (https://docs.optaplanner.org/8.14.0.Final/optaplanner-docs/html_single/index.html#solverConfigurationByJavaAPI) is the heart of an optaplanner solution. The config has somehow has been engineered away, which dramatically impedes the learning experience.

The demos should include an "App" as done in the non-quarkus demos. E.g. TimeTableApp is so much more instructive on how to use optaplanner: It shows how to bind all entity definitions, constraints and the solution classes into a solver-config, builds a solver, creates a dummy problem, and solves it. The code explains itself.

In contrast, the call-center demo does not even seem to have an application entrypoint. The quarkus examples are just providing loose uncoupled definitions which are magically bound behind the scenes into an actual application driven by annotations the reader may not be familiar with (or may not care about). And it seems that quarkus quickstarts are using methods beyond annotations to glue the applications together: org.acme.callcenter.solver.CallCenterConstraintsProvider is not annotated and is not referenced at all in the entire repo except in the tests, so it leaves the reader in the dark how it may be discovered to run the call center.

I hope was not too negative here. But I could imagine that other users may struggle as well.

@triceo
Copy link
Contributor

triceo commented Dec 4, 2021

@ge0ffrey FYI.

@ge0ffrey
Copy link
Contributor

ge0ffrey commented Dec 7, 2021

Hi @holgerbrandl
Thanks for your honest feedback. It's a fair point to make and something we do worry about.
These are our competing goals:

  • Getting started should be a simple as possible => getting started in plain java without Quarkus should be easy.
  • The use case demos should be attractive (= web technology), which is the reason the use case demos use quarkus...

Before I contaminate this discussion by answering, can I just ask:

  1. Have you seen the hello-world example in optaplanner-quickstarts?
  2. If not, what if we start linking that better? From the use-cases readme files maybe?

@ge0ffrey ge0ffrey self-assigned this Dec 7, 2021
@holgerbrandl
Copy link
Author

Thanks for your kind reply.

getting started in plain java without Quarkus should be easy.

+1. But with most of the quickstarts there is no way to run them without dependency injection and quarkus doing some behind the scenes magic. It's totally fine to use this fine engineering, but that's imho not something you may not want to confront a first-time OptaPlanner user with.

The use case demos should be attractive

I'd think that most users arriving at OptaPlanner project-page will be looking for an OR solver. Their background is likely also more in OR or industrial engineering, or process optimization, so too heavy quarkus tech might distract/confuse them. If I'm serious about OR, I will ask somebody else for the webinterface most likely anyway.

The quarkus quickstart examples are incredibly valuable for advanced users of Optaplanner who seek best practice guidance for system integration and interaction with a running solver.

  1. Sure. I know and love the simplistic examples, that introduce OptaPlanner without much clutter. NQueens is wonderfully introduced in https://docs.optaplanner.org/8.14.0.Final/optaplanner-docs/html_single/index.html#nQueens describing just how to model with OptaPlanner while still having some optional UI ready in case the users wants/needs it.

  2. I guess most readers start in the user guide because the repo is overwhelming. And there the order is IMHO not optimal: Simple examples without any avoidable technical clutter should maybe better come first. Simply to introduce the core-concepts of the API gently and very focussed. More complex integration studies (which you call quickstarts) could be better presented afterwards and named as such.

Regarding other links: In https://docs.optaplanner.org/8.14.0.Final/optaplanner-docs/html_single/index.html#useCasesAndExamples the examples could link into the respective https://github.com/kiegroup/optaplanner/tree/main/optaplanner-examples/src/main/java/org/optaplanner/examples. It took at least me a while to figure that all the documentation pointers were also available as fully worked-out examples.

@m-renken
Copy link

Maybe I can serve as an example here. I tried to understand the basics of optaplanner and was pointed here by the docs. I chose to look at the vehicle routing example since it is closest to my use case. I have never used quarkus before.

After two hours of browsing through this repository, the only things that seemed relevant to me are VehicleRoutingConstraintProvider and DepotAngleCustomerDifficultyWeightFactory.
I have no idea how either of these classes are instantiated, they are referenced nowhere outside of the unit tests.

I've now decided to read the python API quickstart instead which seems to have a much smaller complexity overhead.

@triceo
Copy link
Contributor

triceo commented Mar 31, 2023

Maybe I can serve as an example here.

Thank you for the feedback. To answer your concerns:

  • Both classes you mentioned are instantiated inside the solver and neither the quickstarts, nor the examples do it differently. There is no way how you can control that. (And in my opinion, nor should you.) This issue, if resolved, wouldn't do anything to improve the situation you point out.
  • The Python quickstart may seemingly be smaller in terms of complexity, but the Python-to-Java translation is in fact much more complex. You will notice that the Python quickstart is significantly slower than the Java quickstart.

To see the simplest possible example of using OptaPlanner, without Quarkus, Spring, Swing or literally anything extra, the plain "Hello World" example is here for you:

https://github.com/kiegroup/optaplanner-quickstarts/tree/stable/hello-world

@m-renken
Copy link

Thank you for the reply.

Both classes you mentioned are instantiated inside the solver [...]

I can't quite follow you. "The solver" refers to the optaplanner solver, I presume? How does it become aware of these two classes?

To see the simplest possible example of using OptaPlanner, without Quarkus, Spring, Swing or literally anything extra, the plain "Hello World" example is here for you:

https://github.com/kiegroup/optaplanner-quickstarts/tree/stable/hello-world

That looks a lot nicer at first glance. But ideally, I would hope for an even simpler "Hello World", there are still ~500 lines of code here. Compare for example the Gurobi docs.

Maybe something like the vehicle routing would more aptly be labeled "showcase" than "quickstart".

@triceo
Copy link
Contributor

triceo commented Mar 31, 2023

I can't quite follow you. "The solver" refers to the optaplanner solver, I presume?

The solver, in this case, is a simple name for an aggregation of APIs and algorithms found in the optaplanner-core-impl module. It is the code that instantiates the solution, fills it with data, and solves the problem according to the constraints.

How does it become aware of these two classes?

There is a solver config. In some cases, you can see it as XML. In Quarkus, much of it is auto-detected and therefore invisible. In the hello world quickstart, it is here.

That looks a lot nicer at first glance. But ideally, I would hope for an even simpler "Hello World", there are still ~500 lines of code here. Compare for example the Gurobi docs.

Whether this is simple or not is a matter of opinion. In our vision, optimization problems should be modeled using typical Java objects, contraints as plain and easily understandable Java code. We believe this has significant upsides, far outweighing any perceived increase in verbosity. We believe it brings normal everyday Java developers into the fold, making optimization more accessible.

Other people may prefer to define their problems as math equations, and perceive that as the simpler approach. That is their prerogative, and we are glad that there are other projects which cater to those preferences.

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

No branches or pull requests

4 participants