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:
parent
4d4ecd67d0
commit
353f461f4b
13 changed files with 220 additions and 59 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue