blackopsrepl/vehicle-routing-python
2
1function analyzeScore(solution, endpointPath) {2 new bootstrap.Modal("#scoreAnalysisModal").show()3 const scoreAnalysisModalContent = $("#scoreAnalysisModalContent");4 scoreAnalysisModalContent.children().remove();5 scoreAnalysisModalContent.text("");6 7 if (solution.score == null) {8 scoreAnalysisModalContent.text("Score not ready for analysis, try to run the solver first or wait until it advances.");9 } else {10 visualizeScoreAnalysis(scoreAnalysisModalContent, solution, endpointPath)11 }12}13 14function visualizeScoreAnalysis(scoreAnalysisModalContent, solution, endpointPath) {15 $('#scoreAnalysisScoreLabel').text(`(${solution.score})`);16 $.put(endpointPath, JSON.stringify(solution), function (scoreAnalysis) {17 let constraints = scoreAnalysis.constraints;18 constraints.sort(compareConstraintsBySeverity);19 constraints.map(addDerivedScoreAttributes);20 scoreAnalysis.constraints = constraints;21 22 const analysisTable = $(`<table class="table"/>`).css({textAlign: 'center'});23 const analysisTHead = $(`<thead/>`).append($(`<tr/>`)24 .append($(`<th></th>`))25 .append($(`<th>Constraint</th>`).css({textAlign: 'left'}))26 .append($(`<th>Type</th>`))27 .append($(`<th># Matches</th>`))28 .append($(`<th>Weight</th>`))29 .append($(`<th>Score</th>`))30 .append($(`<th></th>`)));31 analysisTable.append(analysisTHead);32 const analysisTBody = $(`<tbody/>`)33 $.each(scoreAnalysis.constraints, function (index, constraintAnalysis) {34 visualizeConstraintAnalysis(analysisTBody, index, constraintAnalysis)35 });36 analysisTable.append(analysisTBody);37 scoreAnalysisModalContent.append(analysisTable);38 }).fail(function (xhr, ajaxOptions, thrownError) {39 showError("Score analysis failed.", xhr);40 },41 "text");42}43 44function compareConstraintsBySeverity(a, b) {45 let aComponents = getScoreComponents(a.score), bComponents = getScoreComponents(b.score);46 if (aComponents.hard < 0 && bComponents.hard > 0) return -1;47 if (aComponents.hard > 0 && bComponents.soft < 0) return 1;48 if (Math.abs(aComponents.hard) > Math.abs(bComponents.hard)) {49 return -1;50 } else {51 if (aComponents.medium < 0 && bComponents.medium > 0) return -1;52 if (aComponents.medium > 0 && bComponents.medium < 0) return 1;53 if (Math.abs(aComponents.medium) > Math.abs(bComponents.medium)) {54 return -1;55 } else {56 if (aComponents.soft < 0 && bComponents.soft > 0) return -1;57 if (aComponents.soft > 0 && bComponents.soft < 0) return 1;58 59 return Math.abs(bComponents.soft) - Math.abs(aComponents.soft);60 }61 }62}63 64function addDerivedScoreAttributes(constraint) {65 let components = getScoreComponents(constraint.weight);66 constraint.type = components.hard != 0 ? 'hard' : (components.medium != 0 ? 'medium' : 'soft');67 constraint.weight = components[constraint.type];68 let scores = getScoreComponents(constraint.score);69 constraint.implicitScore = scores.hard != 0 ? scores.hard : (scores.medium != 0 ? scores.medium : scores.soft);70}71 72function getScoreComponents(score) {73 let components = {hard: 0, medium: 0, soft: 0};74 75 $.each([...score.matchAll(/(-?[0-9]+)(hard|medium|soft)/g)], function (i, parts) {76 components[parts[2]] = parseInt(parts[1], 10);77 });78 79 return components;80}81 82function visualizeConstraintAnalysis(analysisTBody, constraintIndex, constraintAnalysis, recommendation = false, recommendationIndex = null) {83 let icon = constraintAnalysis.type == "hard" && constraintAnalysis.implicitScore < 0 ? '<span class="fas fa-exclamation-triangle" style="color: red"></span>' : '';84 if (!icon) icon = constraintAnalysis.weight < 0 && constraintAnalysis.matches.length == 0 ? '<span class="fas fa-check-circle" style="color: green"></span>' : '';85 86 let row = $(`<tr/>`);87 row.append($(`<td/>`).html(icon))88 .append($(`<td/>`).text(constraintAnalysis.name).css({textAlign: 'left'}))89 .append($(`<td/>`).text(constraintAnalysis.type))90 .append($(`<td/>`).html(`<b>${constraintAnalysis.matches.length}</b>`))91 .append($(`<td/>`).text(constraintAnalysis.weight))92 .append($(`<td/>`).text(recommendation ? constraintAnalysis.score : constraintAnalysis.implicitScore));93 94 analysisTBody.append(row);95 row.append($(`<td/>`));96}