Skip to content

Commit

Permalink
Merge pull request #538 from MikePlekan/master
Browse files Browse the repository at this point in the history
A* creation and RCB rework
  • Loading branch information
jteresco authored Jun 7, 2023
2 parents c914496 + 803c629 commit 26ad6ab
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 12 deletions.
4 changes: 4 additions & 0 deletions HighwayDataExaminer/hdx.css
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,10 @@ h3


}
#copyURL:hover
{
border: 3px solid rgb(95, 55, 126);
}

#algorithmSelectionPanelTable td select#traversalDiscipline
{
Expand Down
33 changes: 21 additions & 12 deletions HighwayDataExaminer/hdxav-rcb.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const hdxPartitionerAV = {
partitionStart: [],
partitionEnd: [],
waypointParts: [],
callStack: [],
callStack: null,
numPartitions: 4,
curNumParts: 1,

Expand Down Expand Up @@ -70,7 +70,7 @@ const hdxPartitionerAV = {
for (let x = 0; x < waypoints.length; x++) {
thisAV.waypointParts[x] = x;
}

thisAV.partitionSection = thisAV.waypointParts;
thisAV.highlightBoundingBox();
thisAV.numPartitions =
Expand All @@ -82,7 +82,7 @@ const hdxPartitionerAV = {
thisAV.partitionEnd = Array(thisAV.numPartitions).fill(0);

// set up initial recursive step
thisAV.callStack.push({
thisAV.callStack.add({
currentPart: 0,
lowerBound: 0,
upperBound: waypoints.length-1,
Expand All @@ -93,7 +93,6 @@ const hdxPartitionerAV = {
minLon: thisAV.minlon
});
hdxAV.nextAction = "methodCall";
hdxAVCP.add("cut", visualSettings.pseudocodeDefault);
},
logMessage: function(thisAV) {
return "Doing some setup stuff";
Expand All @@ -116,7 +115,7 @@ const hdxPartitionerAV = {
}
// get the frame pointer for the recursive call we are
// starting
thisAV.fp = thisAV.callStack.pop();
thisAV.fp = thisAV.callStack.remove();

// removing old overlays
if (thisAV.coloring == "Overlays") {
Expand Down Expand Up @@ -416,7 +415,7 @@ const hdxPartitionerAV = {
// push our two recursive calls onto the stack according to
// the orientation of the next cut
if (thisAV.fp.cutLon) {
thisAV.callStack.push({
thisAV.callStack.add({
currentPart: (thisAV.fp.currentPart+thisAV.fp.partsLeft/2),
lowerBound: thisAV.partitionStart[(thisAV.fp.currentPart+thisAV.fp.partsLeft/2)],
upperBound: thisAV.partitionEnd[(thisAV.fp.currentPart+thisAV.fp.partsLeft/2)],
Expand All @@ -426,7 +425,7 @@ const hdxPartitionerAV = {
minLat: thisAV.fp.minLat,
minLon: thisAV.median
});
thisAV.callStack.push({
thisAV.callStack.add({
currentPart: thisAV.fp.currentPart,
lowerBound: thisAV.partitionStart[thisAV.fp.currentPart],
upperBound: thisAV.partitionEnd[thisAV.fp.currentPart],
Expand All @@ -438,7 +437,7 @@ const hdxPartitionerAV = {
});
}
else {
thisAV.callStack.push({
thisAV.callStack.add({
currentPart: (thisAV.fp.currentPart+thisAV.fp.partsLeft/2),
lowerBound: thisAV.partitionStart[(thisAV.fp.currentPart+thisAV.fp.partsLeft/2)],
upperBound: thisAV.partitionEnd[(thisAV.fp.currentPart+thisAV.fp.partsLeft/2)],
Expand All @@ -448,7 +447,7 @@ const hdxPartitionerAV = {
minLat: thisAV.median,
minLon: thisAV.fp.minLon
});
thisAV.callStack.push({
thisAV.callStack.add({
currentPart: thisAV.fp.currentPart,
lowerBound: thisAV.partitionStart[thisAV.fp.currentPart],
upperBound: thisAV.partitionEnd[thisAV.fp.currentPart],
Expand All @@ -473,7 +472,7 @@ const hdxPartitionerAV = {
highlightPseudocode(this.label, visualSettings.visiting);

//determine if call stack is empty
if (thisAV.callStack.length == 0) {
if (thisAV.callStack.items.length == 0) {
hdxAV.nextAction = "calculating";
}
else {
Expand Down Expand Up @@ -515,6 +514,8 @@ const hdxPartitionerAV = {
// adding data table
hdxPart.partitionAnalysis();
hdxAVCP.remove("cut");
hdxAVCP.update("stack", "");
hdxAVCP.remove("stack");
hdxAVCP.add("stats", visualSettings.pseudocodeDefault);
hdxAVCP.update("stats", hdxPart.styling());

Expand Down Expand Up @@ -560,6 +561,11 @@ const hdxPartitionerAV = {
this.code += '</td></tr>' + pcEntry(1,'if(number of Partitions > 2)','base');
this.code += '</td></tr>' + pcEntry(2,'Partition(newPartion)<br/>'+pcIndent(4)+'Partition(newPartion2)','recursiveCall');
this.code += '</td></tr>' + pcEntry(1,'else<br/>'+pcIndent(4)+'//do nothing','end');

this.callStack = new HDXLinear(hdxLinearTypes.CALL_STACK,
"Call Stack");
this.callStack.setDisplay(hdxAVCP.getDocumentElement("stack"),
displayCallStackItem);
},

setupUI() {
Expand All @@ -582,8 +588,8 @@ const hdxPartitionerAV = {
HDXQSRegisterAndSetCheckbox(this, "onfly", "calcOnFly");

// AVCP entries
hdxAVCP.add("undiscovered", visualSettings.undiscovered);
hdxAVCP.add("visiting", visualSettings.visiting);
hdxAVCP.add("cut", visualSettings.pseudocodeDefault);
hdxAVCP.add("stack", visualSettings.discovered);
},

// cleans up lines and overlays
Expand Down Expand Up @@ -658,3 +664,6 @@ const hdxPartitionerAV = {
}
}
}
function displayCallStackItem(item, Stack) {
return '<span custom-title="Partition #' + item.currentPart + ":" + '">' + "rcb (p = " + item.currentPart + ": " + item.partsLeft + ")" + "</span>";
};
87 changes: 87 additions & 0 deletions HighwayDataExaminer/hdxav-travspan.js
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,93 @@ hdxDijkstraAV.setupCode = function() {
this.code += "</table>";
};


/* Astar's algorithm based on hdxTraversalsSpanningAVCommon */

const hdxAstarAV = Object.create(hdxTraversalsSpanningAVCommon);

// entries for the list of AVs
hdxAstarAV.value = "astar";
hdxAstarAV.name = "A* Algorithm";
hdxAstarAV.description = "A* algorithm for single-source shortest paths.";
hdxAstarAV.foundTableHeader = "Paths Found So Far";
hdxAstarAV.distEntry = "Priority";

// required function to create an appropriate list of discovered vertices
hdxAstarAV.createLDV = function() {

return new HDXLinear(hdxLinearTypes.PRIORITY_QUEUE,
"Priority Queue");
};

// comparator for priority queue
hdxAstarAV.comparator = function(a, b) {
return a.val < b.val;
};

// function to determine the next "val" field for a new LDV entry
// in this case, the old cumulative distance plus the edge length
//
// first parameter is the LDV entry being visited at this point,
// second parameter is the destination vertex and edge traversed
// to get from the vertex being visited
hdxAstarAV.valForLDVEntry = function(oldEntry, nextNeighbor) {
let pathLength = oldEntry.val -
convertToCurrentUnits(
distanceInMiles(
waypoints[oldEntry.vIndex].lat, waypoints[oldEntry.vIndex].lon,
waypoints[this.endingVertex].lat, waypoints[this.endingVertex].lon));
pathLength = oldEntry.val != 0 ? pathLength : 0;//conditional is for starting node

let newpath = convertToCurrentUnits(
edgeLengthInMiles(graphEdges[nextNeighbor.via]));

let distance = convertToCurrentUnits(
distanceInMiles(
waypoints[nextNeighbor.to].lat, waypoints[nextNeighbor.to].lon,
waypoints[this.endingVertex].lat, waypoints[this.endingVertex].lon));
return pathLength + newpath + distance;
};

// helper function to help build pseudocode
hdxAstarAV.mainLoopBody = function(indent) {

return pcEntry(indent+1, "(to,via,d) &larr; pq." +
this.ldv.removeOperation() + "()", "getPlaceFromLDV") +
pcEntry(indent+1, "if tree.contains(to)", "checkAdded") +
pcEntry(indent+2, "discard (to,via) // on removal", "wasAdded") +
pcEntry(indent+1, "else", "") +
pcEntry(indent+2, "tree.add(to,via,d)", "wasNotAdded") +
pcEntry(indent+2, "for each e=(to,v) // neighbors",
"checkNeighborsLoopTop") +
pcEntry(indent+3, "if tree.contains(v)", "checkNeighborsLoopIf") +
pcEntry(indent+4, "discard (v,e) // on discovery",
"checkNeighborsLoopIfTrue") +
pcEntry(indent+3, "else", "") +
pcEntry(indent+4, "pq." + this.ldv.addOperation() + "(v,e,d+len(e)+distance(v,end))",
"checkNeighborsLoopIfFalse");

};

// Astar-specific psuedocode, note labels must match those
// expected by hdxTraversalsSpanningAVCommon avActions
hdxAstarAV.setupCode = function() {
this.code = '<table class="pseudocode">' +
pcEntry(0, ["pq &larr; new " + this.ldv.displayName,
"pq." + this.ldv.addOperation() + "(start,distance(start,end),0)" ],
"START");
if (this.stoppingCondition == "StopAtEnd") {
this.code +=
pcEntry(0, "while not tree.contains(end)", "checkEndAdded") +
pcEntry(1, "if pq.isEmpty", "checkLDVEmpty") +
pcEntry(2, "error: no path", "LDVEmpty") +
this.mainLoopBody(0);
}

this.code += "</table>";
};
hdxAstarAV.supportFindAllComponents = false;

/* Prim's algorithm based on hdxTraversalsSpanningAVCommon */

const hdxPrimAV = Object.create(hdxTraversalsSpanningAVCommon);
Expand Down
1 change: 1 addition & 0 deletions HighwayDataExaminer/hdxav.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ const hdxAV = {
this.avList.push(hdxDegreeAV);
this.avList.push(hdxGraphTraversalsAV);
this.avList.push(hdxDijkstraAV);
this.avList.push(hdxAstarAV);
this.avList.push(hdxPrimAV);
this.avList.push(hdxKruskalAV);
this.avList.push(hdxDFSRecAV);
Expand Down

0 comments on commit 26ad6ab

Please sign in to comment.