feat: Have mergeSort return a bottleneck comparison

if it can't go on due to not enough comparisons
This commit is contained in:
NunoSempere 2022-06-17 13:40:31 -04:00
parent c328ba5c25
commit b80199e940
2 changed files with 150 additions and 51 deletions

View File

@ -8,7 +8,11 @@ function isFirstElementGreater(links, element1, element2) {
);
if (relevantComparisons.length == 0) {
// console.log(element1, "vs", element2);
return errorMsg;
let answer = {
foundAnswer: false,
error: errorMsg,
};
return answer;
} else {
const firstLink = relevantComparisons[0];
// console.log(firstLink);
@ -17,10 +21,15 @@ function isFirstElementGreater(links, element1, element2) {
? true
: false;
const distanceIsGreaterThanOne = Number(firstLink.distance) > 1;
const answer =
const isFirstElementFirst =
(firstElementFirst && !distanceIsGreaterThanOne) ||
(!firstElementFirst && distanceIsGreaterThanOne);
return !answer;
let answer = {
foundAnswer: true,
isFirstElementFirst,
errorMsg,
};
return answer;
}
}
@ -29,54 +38,132 @@ function merge(links, left, right) {
while (left.length && right.length) {
// insert the biggest element to the sortedArr
let link = isFirstElementGreater(links, left[0], right[0]);
if (link == errorMsg) {
let getComparisonAnswer = isFirstElementGreater(links, left[0], right[0]);
if (getComparisonAnswer.foundAnswer == false) {
// console.log("Error@:");
// console.group();
// console.log({ left, right });
// console.groupEnd();
return errorMsg;
} else if (link) {
// left[0] > right[0]
sortedArr.push(left.shift());
} else {
sortedArr.push(right.shift());
let result = {
finishedMerge: false,
uncomparedElements: [left[0], right[0]],
errorMsg: errorMsg,
};
return result;
} else if (getComparisonAnswer.foundAnswer == true) {
if (getComparisonAnswer.isFirstElementFirst == true) {
// left[0] > right[0]
sortedArr.push(right.shift());
} else {
sortedArr.push(left.shift());
}
}
}
// use spread operator and create a new array, combining the three arrays
return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before
let result = {
finishedMerge: true,
orderedList: [...sortedArr, ...left, ...right],
// if they don't have the same size, the remaining ones will be greater than the ones before
};
return result;
}
export function mergeSortInner({ list, links }) {
export function mergeSortInner({ recursiveInput, links }) {
// console.log({ l: list.length });
if (list == errorMsg) {
return errorMsg;
if (recursiveInput.bottleneckedByComparison == true) {
let result = {
recursiveInput: {
list: recursiveInput.list,
bottleneckedByComparison: true,
uncomparedElements: recursiveInput.uncomparedElements,
},
links: links,
};
return result;
}
const half = list.length / 2;
const half = recursiveInput.list.length / 2;
// the base case is list length <=1
if (list.length <= 1) {
return list;
if (recursiveInput.list.length <= 1) {
let result = {
recursiveInput: {
bottleneckedByComparison: false,
list: recursiveInput.list,
},
links: links,
};
return result;
}
const left = list.slice(0, half); // the first half of the list
const right = list.slice(half, list.length); // Note that splice is destructive.
let orderedFirstHalf = mergeSortInner({ list: left, links });
let orderedSecondHalf = mergeSortInner({ list: right, links });
if (orderedFirstHalf != errorMsg && orderedSecondHalf != errorMsg) {
let result = merge(links, orderedFirstHalf, orderedSecondHalf);
return result;
const left = recursiveInput.list.slice(0, half); // the first half of the list
const right = recursiveInput.list.slice(half, recursiveInput.list.length); // Note that splice is destructive.
let orderedFirstHalfAnswer = mergeSortInner({
recursiveInput: { list: left, bottleneckedByComparison: false },
links,
});
let orderedSecondHalfAnswer = mergeSortInner({
recursiveInput: { list: right, bottleneckedByComparison: false },
links,
});
if (
orderedFirstHalfAnswer.recursiveInput.bottleneckedByComparison == false &&
orderedSecondHalfAnswer.recursiveInput.bottleneckedByComparison == false
) {
let mergeStepAnswer = merge(
links,
orderedFirstHalfAnswer.recursiveInput.list,
orderedSecondHalfAnswer.recursiveInput.list
);
if (mergeStepAnswer.finishedMerge == true) {
let result = {
recursiveInput: {
list: mergeStepAnswer.orderedList,
bottleneckedByComparison: false,
},
links,
};
return result;
} else {
let result = {
recursiveInput: {
list: recursiveInput.list,
bottleneckedByComparison: true,
uncomparedElements: mergeStepAnswer.uncomparedElements,
},
links,
};
return result;
}
} else if (
orderedFirstHalfAnswer.recursiveInput.bottleneckedByComparison == true
) {
return orderedFirstHalfAnswer;
} else {
return errorMsg;
return orderedSecondHalfAnswer;
}
}
export function mergeSort({ list, links }) {
// Try normally
let answer = mergeSortInner({ list, links });
if (answer != errorMsg) return answer;
let answer = mergeSortInner({
recursiveInput: { list, bottleneckedByComparison: false },
links,
});
if (answer.recursiveInput.bottleneckedByComparison == false) {
let result = {
finishedOrderingList: true,
orderedList: answer.recursiveInput.list,
};
return result;
} else {
let result = {
finishedOrderingList: false,
uncomparedElements: answer.recursiveInput.uncomparedElements,
};
return result;
}
/*
// otherwise
let permutation = list.slice();
var length = list.length;
@ -112,4 +199,5 @@ export function mergeSort({ list, links }) {
}
console.log("Error");
return "Error: The original list was wrongly ordered, and trying permutations didn't work";
*/
}

View File

@ -32,29 +32,40 @@ async function main() {
// Merge sort
let mergeSortOutput = mergeSort({ list, links });
// console.log("Output: ");
console.log("Sorted output: ");
console.group();
console.log(mergeSortOutput.map((x) => x.name));
console.groupEnd();
console.log("");
if (mergeSortOutput.finishedOrderingList == false) {
console.log("Merge could not proceed");
console.group();
console.log("Elements which need to be compared:");
console.log(mergeSortOutput.uncomparedElements);
console.groupEnd();
} else {
let orderedList = mergeSortOutput.orderedList;
// console.log(orderedList);
console.log("Sorted output: ");
console.group();
console.log(orderedList.map((x) => x.name));
console.groupEnd();
console.log("");
// find Paths
let nodes = mergeSortOutput.map((element, i) => ({
...element,
position: i,
}));
const linksWithPosition = links.map((link) => ({
...link,
sourceElementPosition: findElementPosition(link.source, nodes),
targetElementPosition: findElementPosition(link.target, nodes),
}));
let paths = await findDistancesFromAllElementsToAllReferencePoints({
nodes,
links: linksWithPosition,
});
// console.log(JSON.stringify(paths, null, 4));
// find Paths
let nodes = orderedList.map((element, i) => ({
...element,
position: i,
}));
const linksWithPosition = links.map((link) => ({
...link,
sourceElementPosition: findElementPosition(link.source, nodes),
targetElementPosition: findElementPosition(link.target, nodes),
}));
let paths = await findDistancesFromAllElementsToAllReferencePoints({
nodes,
links: linksWithPosition,
});
// console.log(JSON.stringify(paths, null, 4));
// Aggregate paths.
let aggregatedPaths = aggregatePaths(paths, nodes);
// Aggregate paths.
let aggregatedPaths = aggregatePaths(paths, nodes);
console.log(aggregatedPaths);
}
}
main();