slightlyoff / cassowary.js

Cassowary/JS, better, faster, future-ready
Other
1.69k stars 107 forks source link

Changing a variable coefficient #71

Open bchevalier opened 9 years ago

bchevalier commented 9 years ago

Hello,

I found 2 methods to change a variable coefficient but both of them are problematic:

1- Using Expression.setVariable. The problem: the coefficient of the variable within the expression seems to be correctly updated but not within the tableau. Is it normal?

A simple example to illustrate the problem:

var solver = new SimplexSolver();
solver.autoSolve = false;

var x = new Variable({ name: 'x', value: 5 });

var myExpression = new Expression(x, 2);
var myConstraint1 = new Inequality(myExpression, GEQ, 5);
var myConstraint2 = new Inequality(myExpression, LEQ, 5);

solver.addConstraint(myConstraint1);
solver.addConstraint(myConstraint2);

console.log(myExpression.toString()); // 2*5
myExpression.setVariable(x, 1);
console.log(myExpression.toString()); // 1*5

solver.resolve();

// At this point x should be equal to 5 if the expression was correctly updated
console.log(x); // x = 2.5

2 - By removing and re-adding constraints. The problem: it gives really poor performance. e.g 2ms to remove and add back a single constraint on a 15 row by 10 columns tableau although it takes 0.05ms to solve it!.

Is there a more friendly and reliable way to cheaply do that coefficient change operation? (I tried to dive in the code but could not figure out what to do!)

Note: I am using cassowary to implement a complex responsive UI and I plan on implementing a branch and cut algorithm based on cassowary in order to solve problems that include integer variables. Therefore I am searching for an efficient way to dynamically change cut constraints.

mcanthony commented 8 years ago

Unless I am misunderstanding the correlation here, I think what you are trying to accomplish will be addressed when the feature described in https://github.com/slightlyoff/cassowary.js/issues/66 lands. @slightlyoff is this correct?

bchevalier commented 8 years ago

I think https://github.com/slightlyoff/cassowary.js/issues/66 is only about changing the right hand side of a constraint. What I want is more general: I want to be able to change any variable coefficient in the objective function and in the constraints and the right hand side values of any constraint.

I think I might know how to do it (general case for the dynamic changes I listed above): 1 - Take the variable implied (if any) out of the base (pivot if necessary) 2 - Put the slack variable corresponding to the constraint involved (if any) in the base (pivot if necessary) 3 - Update the cell of the matrix that correspond to the variable and the constraint involved: the new value should be the previous value minus the difference between the new and previous coefficients. 4 - Solve

I am just not sure I want to spend time making those changes if the repo is not maintained.