Add visualisation corrections#31
Conversation
Merge pull request #27 from IFRI-AI-Classes/fix/vizualisation
Fix/vizualisation
feat: Update visualization metrics and enhance product tracking funct…
Merge pull request #31 from IFRI-AI-Classes/main
There was a problem hiding this comment.
Pull request overview
This PR updates the solution visualizer to better reflect MPVRP-CC solution semantics by improving parsing of .dat solutions (per-segment product and quantity metadata) and adjusting the metrics UI.
Changes:
- Update the metrics panel (rename “Routing Cost” label, hide exchanges metric, add a “Trucks” metric).
- Enhance
.datsolution parsing to capture per-segment product states and delivery/load quantities, and use them for exchange/delivery and depot inventory computations. - Add two sample
.datsolution files and update.gitignore.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pages/visualisation.html | Metrics panel tweaks: label update, exchanges metric commented out, trucks metric added. |
| pages/static/js/visualisation.js | Parse and propagate product/delivery metadata from .dat solutions; update stats setting and inventory/delivery logic. |
| data/solutions/Sol_MPVRP_S_005_s7_d1_p3.dat | New example solution file for visualisation/testing. |
| data/solutions/Sol_MPVRP_S_002_s10_d2_p3.dat | New example solution file for visualisation/testing. |
| .gitignore | Add ignore rule for a backup file path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const explicitDelivery = Number(segMeta.deliveryQty || 0); | ||
| const deliveryQty = explicitDelivery > 0 | ||
| ? explicitDelivery |
There was a problem hiding this comment.
explicitDelivery > 0 treats an explicit (0) delivery as “missing” and falls back to the demand/visits estimate, which makes routes that intentionally deliver 0 appear to deliver a positive amount (see existing sample solutions with (0) quantities). Consider preserving the distinction between “no delivery specified” vs “delivery specified as 0” (e.g., have parseDatSolution store deliveryQty: null when no parentheses are present, and here check segMeta.deliveryQty !== null to decide whether to use it).
| const explicitDelivery = Number(segMeta.deliveryQty || 0); | |
| const deliveryQty = explicitDelivery > 0 | |
| ? explicitDelivery | |
| const hasExplicitDelivery = | |
| segMeta.deliveryQty !== null && segMeta.deliveryQty !== undefined; | |
| const deliveryQty = hasExplicitDelivery | |
| ? (Number(segMeta.deliveryQty) || 0) |
| if (allRaw.length === 0) return 'zero'; | ||
| if (allRaw.includes(0)) return 'zero'; | ||
|
|
||
| const maxRaw = Math.max(...allRaw); | ||
| if (maxRaw === numProducts) return 'one'; | ||
| if (maxRaw < numProducts) return 'zero'; |
There was a problem hiding this comment.
detectProductIndexingBase can mis-detect 1-based product IDs when the solution never uses the highest-numbered product (e.g., numProducts=3 but only products 1 and 2 appear ⇒ maxRaw < numProducts returns 'zero'). That would shift product indices and break per-product delivery/inventory calculations. Consider basing detection primarily on the presence of 0 vs numProducts (and treat the “ambiguous” case where values are within 1..numProducts-1 consistently, e.g., default to 1-based or add an explicit flag in the file format).
| if (allRaw.length === 0) return 'zero'; | |
| if (allRaw.includes(0)) return 'zero'; | |
| const maxRaw = Math.max(...allRaw); | |
| if (maxRaw === numProducts) return 'one'; | |
| if (maxRaw < numProducts) return 'zero'; | |
| // No product IDs found: keep existing behavior and default to zero-based. | |
| if (allRaw.length === 0) return 'zero'; | |
| const hasZero = allRaw.includes(0); | |
| const hasMaxId = Number.isInteger(numProducts) && numProducts > 0 | |
| ? allRaw.includes(numProducts) | |
| : false; | |
| // If 0 is present, we have clear evidence of zero-based indexing. | |
| if (hasZero) return 'zero'; | |
| // If the highest valid product ID (numProducts) appears, this is 1-based. | |
| if (hasMaxId) return 'one'; | |
| // Ambiguous case: all product IDs lie in 1..numProducts-1 (no 0, no numProducts). | |
| // Default to 1-based indexing to avoid mistakenly shifting valid 1-based IDs. |
No description provided.