Merged PR 175: Implement drag drop

- [x] Implement drag drop to create an element at a specific index
- Add Swap behavrior
- Implement max contraints with simplex
~~- [ ] Implement drag drop to swap two container that flex~~

- Fixes tries number for simplex it can now go up to 2 * number of containers
- Fixes flex calling another flex behavior when not needed (remember that flex behavior is the only behavior that needs to communicate with siblings)
- Fix max width being ignored in input group
This commit is contained in:
Eric Nguyen 2022-09-05 07:56:45 +00:00
parent 4d4ecd67d0
commit 353f461f4b
13 changed files with 220 additions and 59 deletions

View file

@ -17,20 +17,22 @@
* @param requiredMaxWidth
* @returns
*/
export function Simplex(minWidths: number[], requiredMaxWidth: number): number[] {
export function Simplex(minWidths: number[], maxWidths: number[], requiredMaxWidth: number): number[] {
/// 1) standardized the equations
// add the min widths constraints
const constraints = minWidths.map(minWidth => minWidth * -1);
// add the max widths constraint
constraints.push(requiredMaxWidth);
/// 2) Create the initial matrix
// get row length (nVariables + nConstraints + 1 (z) + 1 (b))
const nVariables = minWidths.length;
const nConstraints = constraints.length;
const rowlength = nVariables + nConstraints + 2;
const matrix = GetInitialMatrix(constraints, rowlength, nVariables);
const rowlength =
minWidths.length + // min constraints
maxWidths.length + // max constraints
nConstraints + 1 + // slack variables
1 + // z
1; // b
const matrix = GetInitialMatrix(constraints, maxWidths, requiredMaxWidth, rowlength);
/// Apply the algorithm
const finalMatrix = ApplyMainLoop(matrix, rowlength);
@ -40,32 +42,35 @@ export function Simplex(minWidths: number[], requiredMaxWidth: number): number[]
return solutions;
}
const MAX_TRIES = 10;
/**
* Specific to min widths algorithm
* Get the initial matrix from the maximum constraints
* and the number of variables
* @param maximumConstraints
* @param minConstraints
* @param rowlength
* @param nVariables
* @returns
*/
function GetInitialMatrix(
maximumConstraints: number[],
rowlength: number,
nVariables: number
minConstraints: number[],
maxConstraints: number[],
objectiveConstraint: number,
rowlength: number
): number[][] {
const nConstraints = maximumConstraints.length;
const matrix = maximumConstraints.map((maximumConstraint, index) => {
const nVariables = maxConstraints.length;
const constraints = minConstraints.concat(maxConstraints);
constraints.push(objectiveConstraint);
const matrix = constraints.map((constraint, index) => {
const row: number[] = Array(rowlength).fill(0);
// insert the variable coefficient a of a*x
if (index <= nConstraints - 2) {
// insert the the variable coefficient of the minimum widths constraints (negative identity matrix)
if (index < nVariables) {
// insert the the variable coefficient of the minimum/maximum widths constraints (negative identity matrix)
row[index] = -1;
} else if (index < (2 * nVariables)) {
row[index - (nVariables)] = 1;
} else {
// insert the the variable coefficient of the maximum width constraint
// insert the the variable coefficient of the maximum desired width constraint
row.fill(1, 0, nVariables);
}
@ -73,7 +78,7 @@ function GetInitialMatrix(
row[index + nVariables] = 1;
// insert the constraint coefficient (b)
row[rowlength - 1] = maximumConstraint;
row[rowlength - 1] = constraint;
return row;
});
@ -119,7 +124,8 @@ function GetAllIndexes(arr: number[], val: number): number[] {
*/
function ApplyMainLoop(oldMatrix: number[][], rowlength: number): number[][] {
let matrix = oldMatrix;
let tries = MAX_TRIES;
const maxTries = oldMatrix.length * 2;
let tries = maxTries;
const indexesTried: Record<number, number> = {};
while (matrix[matrix.length - 1].some((v: number) => v < 0) && tries > 0) {
// 1) find the index with smallest coefficient (O(n)+)
@ -183,9 +189,10 @@ function ApplyMainLoop(oldMatrix: number[][], rowlength: number): number[][] {
}
if (tries === 0) {
console.table(matrix);
throw new Error('[Flex] Simplexe: Could not find a solution');
}
console.debug(`Simplex was solved in ${maxTries - tries} tries`);
return matrix;
}