Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit a493426

Browse files
committed
Fix DAG partial credit distance algorithm
1 parent 0fcbebe commit a493426

1 file changed

Lines changed: 36 additions & 35 deletions

File tree

runestone/parsons/js/dagGrader.js

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import LineBasedGrader from "./lineGrader";
22
import { DiGraph } from "jsnetworkx/node/classes";
33
import { hasPath } from "jsnetworkx/node/algorithms/shortestPaths/generic";
4+
import { isDirectedAcyclicGraph } from "jsnetworkx/node/algorithms/dag";
45

56
function graphToNX(answerLines) {
67
var graph = new DiGraph();
7-
for (let line of answerLines) {
8-
graph.addNode(line.tag);
9-
for (let line2 of line.depends) {
8+
for (let line1 of answerLines) {
9+
graph.addNode(line1.tag);
10+
for (let line2tag of line1.depends) {
1011
// the depends graph lists the *incoming* edges of a node
11-
graph.addEdge(line2, line);
12+
graph.addEdge(line2tag, line1.tag);
1213
}
1314
}
1415
return graph;
@@ -46,63 +47,63 @@ function allSubsets(arr) {
4647

4748
export default class DAGGrader extends LineBasedGrader {
4849

49-
5050
inverseLISIndices(arr) {
5151
// For more details and a proof of the correctness of the algorithm, see the paper: https://arxiv.org/abs/2204.04196
5252

5353
var solution = this.problem.solution;
5454
var answerLines = this.problem.answerLines();
5555

56-
let graph = graphToNX(answerLines);
57-
console.log(allSubsets([1,2,3]))
56+
let graph = graphToNX(solution);
5857

5958
let seen = new Set();
6059
let problematicSubgraph = new DiGraph();
61-
let distractors = [];
62-
for (let block of solution) {
60+
let tagsToRemove = [];
61+
for (let line1 of answerLines) {
6362

64-
if (block.distractor) {
65-
distractors.push(block);
63+
if (line1.distractor) {
64+
tagsToRemove.push(line1.tag);
6665
continue;
6766
}
6867

69-
for (let block2 of seen) {
70-
let problematic = hasPath(graph, block, block2);
71-
if (hasPath(graph, block, block2)) {
72-
problematicSubgraph.addEdge(block, block2);
68+
for (let line2 of seen) {
69+
let problematic = hasPath(graph, {source: line1.tag, target: line2.tag});
70+
if (problematic) {
71+
problematicSubgraph.addEdge(line1.tag, line2.tag);
7372
}
7473
}
7574

76-
seen.add(block);
75+
seen.add(line1);
7776
}
7877

79-
console.log(problematicSubgraph);
80-
81-
if (problematicSubgraph.numberOfNodes() == 0) {
82-
// just return the indices of the distractors, I guess???
83-
} else {
84-
let mvc = null;
85-
let subsets = allSubsets(problematicSubgraph.nodes());
86-
for (let i = 0; i <= problematicSubgraph.numberOfNodes(); i++) {
87-
for (let subset of subsets[i]) {
88-
if (isVertexCover(problematicSubgraph, subset)) {
89-
mvc = subset;
90-
console.log(mvc)
91-
break;
92-
}
93-
}
94-
if (mvc != null) {
78+
let mvc = null;
79+
let subsets = allSubsets(problematicSubgraph.nodes());
80+
for (let i = 0; i <= problematicSubgraph.numberOfNodes(); i++) {
81+
for (let subset of subsets[i]) {
82+
if (isVertexCover(problematicSubgraph, subset)) {
83+
mvc = subset;
9584
break;
9685
}
9786
}
87+
if (mvc != null) {
88+
break;
89+
}
9890
}
9991

100-
// TODO implement the algorithm properly for the DAG grader so that it is the shortest edit distance
101-
// to ANY of the correct solutions instead of just to the model solution
102-
return super.inverseLISIndices(arr)
92+
tagsToRemove = tagsToRemove.concat([...mvc]);
93+
let indices = tagsToRemove.map(tag => {
94+
for (let i = 0; i < answerLines.length; i++) {
95+
if (answerLines[i].tag === tag) return i;
96+
}
97+
});
98+
99+
return indices;
103100
}
104101

105102
checkCorrectOrdering(solutionLines, answerLines) {
103+
if (!(isDirectedAcyclicGraph(graphToNX(solutionLines)))) {
104+
throw "Dependency between blocks does not form a Directed Acyclic Graph; Problem unsolvable."
105+
}
106+
106107
let seen = new Set();
107108
let isCorrectOrder = true;
108109
this.correctLines = 0;

0 commit comments

Comments
 (0)