I apologize in advance for how likely stupid this is going to come off, but I have a few questions and was hoping someone might be kind enough to offer some insight.
I became interested in Logic/Constraints programming some months ago, and have since spent time looking at tooling in the area. I don’t have any education or math background, so I found that a majority of the libraries were unapproachable because of how math-driven the API’s were.
JuMP is different, the DSL for expressing constraints and objectives feels much more logic-oriented than math-oriented.
I don’t have any background in Julia, so I tried to start with a simple problem:
"Given a list of food items, and a desired calorie + protein goal, return all possible combinations of food items you could eat to meet that goal"
I went through a number of the JuMP examples to get a feel for it, but then realized I wasn’t sure how to model the problem.
The questions I have are:
- Why are variables represented as single-input arrays in JuMP models? For example, a Food struct has calories, protein, carbs, fat, but in the examples, each of these values seem like they get pulled apart into individual arrays .
function example_cannery(; verbose = true) plants = ["Seattle", "San-Diego"] markets = ["New-York", "Chicago", "Topeka"] # Capacity and demand in cases. capacity = [350, 600] demand = [300, 300, 300] # Distance in thousand miles. distance = [2.5 1.7 1.8; 2.5 1.8 1.4]
Instead of the format that makes more sense, which is something like:
food = [ Food(name = "Pizza", cals = 300, protein = 12), Food(name = "Chicken", cals = 100, protein = 40), ]
This way you can do
food.calories, etc, instead of
food_names[i], food_cals[i] which is harder to follow.
What if you don’t have an
@objective, and you just want any values that meet your constraints? Would you just create an artificial/fake objective and example the constraint values after the solve?
How do solvers differ from combinatorial approaches, like the one below? I assume they have some advanced logic in them that makes them more effect at searching for values, and this approach breaks down at larger data sizes?
This was how I was able to do it naively:
Is this better representable/more scalable with constraints? If so, what might the right approach look like?