Skip to content

Commit

Permalink
Add measurement script and update algorithm
Browse files Browse the repository at this point in the history
functions
  • Loading branch information
adiletbaimyrza committed Nov 19, 2023
2 parents 62463fa + 81b1a23 commit 41895e0
Show file tree
Hide file tree
Showing 8 changed files with 438 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { createGraph, buildAdjacencyList } from "./graph.js";
import {
buildAdjacencyList,
buildAdjacencyListFromComponent,
} from "./graph.js";
import createMinHeap from "./minHeap.js";

const dijkstra = (graph) => {
const adjacencyList = buildAdjacencyList(graph);
const dijkstra = (adjacencyList, createFringe) => {
const nodesCount = adjacencyList.length;

const startNode = 0;
const finishNode = nodesCount - 1;

const fringe = new createMinHeap(nodesCount);
const fringe = new createFringe(nodesCount);
const keys = new Array(nodesCount);
const parents = new Array(nodesCount);

Expand All @@ -24,7 +26,7 @@ const dijkstra = (graph) => {
const node = fringe.extractMin();
const neighbours = adjacencyList[node.key];

if (node == finishNode) {
if (node.key == finishNode) {
break;
}

Expand All @@ -38,11 +40,11 @@ const dijkstra = (graph) => {
});
}

const sp = new Array();
const steps = new Array();
let node = finishNode;

while (node != startNode) {
sp.push({
steps.push({
from: parents[node].key,
to: node,
weight: parents[node].weight,
Expand All @@ -51,11 +53,24 @@ const dijkstra = (graph) => {
}

return {
steps: sp.reverse(),
spTotalWeight: keys[finishNode],
steps: steps,
total: keys[finishNode],
};
};

const transformResult = (result) => {
return {
steps: result.steps.reverse(),
total: result.total,
};
};

const dijkstraWrapper = (nodes, edges) => {
const adjacencyList = buildAdjacencyListFromComponent(nodes, edges);
const result = dijkstra(adjacencyList, createMinHeap);
return transformResult(result);
};

const displayDijkstraResult = (result) => {
console.log("SP steps:");

Expand Down Expand Up @@ -86,11 +101,14 @@ const computeSp = () => {
],
);

const result = dijkstra(graph, 0, 5);
const adjacencyList = buildAdjacencyList(graph);

const result = dijkstra(adjacencyList, createMinHeap);
const transformedResult = transformResult(result);

displayDijkstraResult(result);
displayDijkstraResult(transformedResult);

console.log("------- SP DIJKSTRA END -------");
};

export default dijkstra;
export { dijkstra, dijkstraWrapper };
63 changes: 47 additions & 16 deletions dijkstra-prim-visualization/src/algorithms/graph.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
const createGraphFromComponent = function (nodes, edges) {
const mappedNodes = nodes.map((node) => node.id);
const mappedEdges = edges.map((edge) => {
return [edge.firstNode.id, edge.secondNode.id, edge.weight];
});
// const createGraphFromComponent = function (nodes, edges) {
// const mappedNodes = nodes.map((node) => node.id);
// const mappedEdges = edges.map((edge) => {
// return [edge.firstNode.id, edge.secondNode.id, edge.weight];
// });

// return new createGraph(mappedNodes, mappedEdges);
// };

return new createGraph(mappedNodes, mappedEdges);
const createAdjacencyListEntry = (node, weight) => {
const entry = {
node: node,
weight: weight,
};
return entry;
};

const createGraph = function (nodes, edges) {
const createGraph = (nodes, edges) => {
this.nodes = nodes;
this.edges = new Array(edges.length);

Expand All @@ -24,14 +32,6 @@ const createGraph = function (nodes, edges) {
const buildAdjacencyList = (graph) => {
const adjacencyList = new Array(graph.nodes.length).fill(null);

const createAdjacencyListEntry = (node, weight) => {
const entry = {
node: node,
weight: weight,
};
return entry;
};

graph.edges.forEach((e) => {
if (!Array.isArray(adjacencyList[e.from])) {
adjacencyList[e.from] = new Array();
Expand All @@ -47,4 +47,35 @@ const buildAdjacencyList = (graph) => {
return adjacencyList;
};

export { createGraph, createGraphFromComponent, buildAdjacencyList };
const buildAdjacencyListFromComponent = (nodes, edges) => {
const adjacencyList = new Array(nodes.length).fill(null);

edges
.map((e) => {
return {
from: e.firstNode.id,
to: e.secondNode.id,
weight: e.weight,
};
})
.forEach((e) => {
if (!Array.isArray(adjacencyList[e.from])) {
adjacencyList[e.from] = new Array();
}
adjacencyList[e.from].push(createAdjacencyListEntry(e.to, e.weight));

if (!Array.isArray(adjacencyList[e.to])) {
adjacencyList[e.to] = new Array();
}
adjacencyList[e.to].push(createAdjacencyListEntry(e.from, e.weight));
});

return adjacencyList;
};

export {
createAdjacencyListEntry,
createGraph,
buildAdjacencyList,
buildAdjacencyListFromComponent,
};
72 changes: 72 additions & 0 deletions dijkstra-prim-visualization/src/algorithms/linkedList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const createLinkedList = function (capacity) {
const createNode = (key, value, next = null) => {
const node = {
key: key,
value: value,
next: next,
};

return node;
};

let head = null;
let currentSize = 0;

this.isEmpty = () => currentSize == 0;

this.insert = (key, value) => {
currentSize++;
const newNode = createNode(key, value);

if (head == null) {
head = newNode;
} else {
let tmp = head;

while (tmp.next != null) {
tmp = tmp.next;
}

tmp.next = newNode;
}
};

this.extractMin = () => {
let minValue = Infinity;
let minNode = null;
let tmp = createNode(-1, -1, head);

//find the min node
while (tmp.next) {
if (tmp.next.value < minValue) {
minValue = tmp.next.value;
minNode = tmp;
}

tmp = tmp.next;
}
tmp = minNode.next;

//delete the min node
if (minNode.next == head) {
head = head.next;
} else {
minNode.next = minNode.next.next;
}
--currentSize;

return tmp;
};

this.decreaseKey = (key, newValue) => {
let tmp = createNode(-1, -1, head);

while (tmp.next.key != key) {
tmp = tmp.next;
}

tmp.next.value = newValue;
};
};

export default createLinkedList;
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
import { createGraph, buildAdjacencyList } from "./graph";
import createMinHeap from "./minHeap";

const prim = (graph) => {
const adjacencyList = buildAdjacencyList(graph);
import {
buildAdjacencyList,
buildAdjacencyListFromComponent,
} from "./graph.js";
import createMinHeap from "./minHeap.js";

const prim = (adjacencyList, createFringe) => {
const nodesCount = adjacencyList.length;

const fringe = new createMinHeap(nodesCount);
const isInHeap = new Array(nodesCount);
const results = new Array(nodesCount);
const fringe = new createFringe(nodesCount);
const isInFringe = new Array(nodesCount);
const steps = new Array(nodesCount);
const keys = new Array(nodesCount);

// Insert node 0 with value 0
fringe.insert(0, 0);
isInHeap[0] = true;
isInFringe[0] = true;
keys[0] = Infinity;
results[0] = {
steps[0] = {
parent: -1,
weight: null,
};

for (let index = 1; index < nodesCount; index++) {
isInHeap[index] = true;
isInFringe[index] = true;
keys[index] = Infinity;
fringe.insert(index, Infinity);
}

while (!fringe.isEmpty()) {
const extractedNode = fringe.extractMin();
isInHeap[extractedNode.key] = false;
isInFringe[extractedNode.key] = false;

const neightbours = adjacencyList[extractedNode.key];
neightbours.forEach((n) => {
if (isInHeap[n.node]) {
if (isInFringe[n.node]) {
if (keys[n.node] > n.weight) {
fringe.decreaseKey(n.node, n.weight);
keys[n.node] = n.weight;
results[n.node] = {
steps[n.node] = {
from: extractedNode.key,
to: n.node,
weight: n.weight,
Expand All @@ -46,24 +47,35 @@ const prim = (graph) => {
});
}

results.sort((a, b) => a.weight - b.weight);
return steps;
};

let mstTotal = 0;
const transformSteps = (steps) => {
steps.shift(1);
steps.sort((a, b) => a.weight - b.weight);

for (let index = 1; index < nodesCount; index++) {
mstTotal += results[index].weight;
let total = 0;
for (let i = 0; i < steps.length; i++) {
total += steps[i].weight;
}

return {
steps: results,
mstTotalWeight: mstTotal,
steps: steps,
total: total,
};
};

const primWrapper = (nodes, edges) => {
const adjacencyList = buildAdjacencyListFromComponent(nodes, edges);
const steps = prim(adjacencyList, createMinHeap);

return transformSteps(steps);
};

const displayPrimResult = (result) => {
console.log("MST steps:");

for (let index = 1; index < result.steps.length; index++) {
for (let index = 0; index < result.steps.length; index++) {
console.log(
`From ${result.steps[index].from} to ${result.steps[index].to} with weight ${result.steps[index].weight}`,
);
Expand All @@ -88,11 +100,14 @@ const computeMst = () => {
],
);

const result = prim(graph);
const adjacencyList = buildAdjacencyList(graph);

const steps = prim(adjacencyList);
const transformedSteps = transformSteps(steps);

displayPrimResult(result);
displayPrimResult(transformedSteps);

console.log("------- MST PRIM END -------");
};

export default prim;
export { prim, primWrapper };
12 changes: 4 additions & 8 deletions dijkstra-prim-visualization/src/components/Navbar/NavbarUtils.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { createGraphFromComponent } from "../../algorithms/graph";
import prim from "../../algorithms/mstPrim";
import dijkstra from "../../algorithms/spDijkstra";
import { primWrapper } from "../../algorithms/prim";
import { dijkstraWrapper } from "../../algorithms/dijkstra";

const runPrim = (nodes, edges) => {
const graph = createGraphFromComponent(nodes, edges);
const result = prim(graph);
const result = primWrapper(nodes, edges);
console.log(result);
result.steps.shift(); // TODO: fix it
const edgeIds = getEdgeIDs(result.steps);

return edgeIds;
};

const runDijkstra = (nodes, edges) => {
const graph = createGraphFromComponent(nodes, edges);
const result = dijkstra(graph);
const result = dijkstraWrapper(nodes, edges);
console.log(result);
const edgeIds = getEdgeIDs(result.steps);

Expand Down
Loading

0 comments on commit 41895e0

Please sign in to comment.