JWally / jsLPSolver

Simple OOP javaScript library to solve linear programs, and mixed integer linear programs
The Unlicense
420 stars 69 forks source link

Increase values evenly(ish) #94

Closed ojame closed 5 years ago

ojame commented 5 years ago

I'm incredibly new to linear programming - I'm sure what I'm requesting breaks the methodology, but I'm not sure what other tact to try. So perhaps this isn't solvable with this package, but i'm interested to know:

Input:

{
  optimize: "volume",
  opType: "max",
  constraints: {
    fat: { max: 20 },
    protein: { max: 50 },
    carb: { max: 100 }
  },
  variables: {
    broccoli: { fat: 2,  protein: 5, carb: 10, volume: 1 },
    steak: { fat: 2, protein: 5, carb: 10, volume: 1 }
  },
  ints: { broccoli: 1, steak: 1 }
}

Output:

{ feasible: true, result: 10, bounded: true, broccoli: 10 }

Which makes sense, as the shortest path is 10 x broccoli, and it's the first variable.

However, ideally i'd like a more even distribution - because the broccoli and steak have the same macros (to simplify this example), i'd prefer to see 5 x broccoli and 5 x steak.

Is there any way to achieve that? Ideally with many more variables and much more scattered macros.

JWally commented 5 years ago

Try setting your objective function up as something like this?:

    "optimize": {
        "bacon": "max",
        "cheddar cheese": "max",
        "french fries": "max"
    }
ojame commented 5 years ago

If i change my input to be

{
  optimize: {
    broccoli: "max",
    steak: "max"
  },
  opType: "max",
  constraints: {
    fat: { max: 20 },
    protein: { max: 50 },
    carb: { max: 100 }
  },
  variables: {
    broccoli: { fat: 2,  protein: 5, carb: 10, volume: 1 },
    steak: { fat: 2, protein: 5, carb: 10, volume: 1 }
  },
  ints: { broccoli: 1, steak: 1 }
}

the result is empty:

{ feasible: true, result: -0, bounded: true }

JWally commented 5 years ago

The attributes you're optimizing (broccoli and steak) don't exist as attributes of the variables themselves (If I said somewhere in documentation that happens, I need to change it).

The way you'd fix is to do something like this:

{
  "optimize": {
    "broccoli": "max",
    "steak": "max"
  },
  "constraints": {
    "fat": { "max": 20 },
    "protein": { "max": 50 },
    "carb": { "max": 100 }
  },
  "variables": {
    "broccoli": { "fat": 2,  "protein": 5, "carb": 10, "volume": 1 ,"broccoli": 1},
    "steak": { "fat": 2, "protein": 5, "carb": 10, "volume": 1 , "steak": 1}
  },
  "ints": { "broccoli": 1, "steak": 1 }
}

where the variable "broccoli" has an attribute of "broccoli" set to 1.

Out of curiosity, are you doing something with food, or are you using it in your examples because its easy to understand?

ojame commented 5 years ago

Awesome, sorry I missed that. I wasn't mislead by documentation anywhere, just a bit ignorant. I still couldn't get it to work until I realised passing an object to optimize was in a new version than what I had. It works well now though!

Yep, doing something with food. It's a fair bit more complex than the example I've displayed above, but adheres to the same structure. I'll send you a message when I've got something viewable online - jsLPSolver is a huge help.

Thanks Justin.

JWally commented 5 years ago

So for whatever its worth, a couple of years ago I built a proof of concept web-app that lets you set diet parameters, combine foods, and solve. There's a lot of functionality missing, but you get the point when you see it:

http://mathfood.com

The United States' USDA puts out a food database(sr17-sr28), that I converted to JSON format here:

http://mathfood.com/prod/names.json (name and id listing) http://mathfood.com/data/04609 (data about the food itself @ /data/{{id}})

Kind of scattered, but maybe it'll be useful for what you're working on.