Imaginons un déconfinement où la liberté de déplacement ne soit pas restreinte.

Premier réflexe: aller rendre visite à tous ses amis à travers la France.
Deuxième réflexe: pensons économie et évitons tout de même les kilomètres en trop.

Voilà ce que ça peut donner pour un périple de 7 villes aller-retour.
(Oui, c'est un peu plus fun que d'imaginer un VRP.)

http://javatwist.imingo.net/voyageur.htm


Code html : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>La tournée des copains</title>
</head>
 
<body>
 
<div id="cadre">
	<div id="m">Soit une liste de villes à parcourir en un minimum de kilomètres, 
	avec retour au départ:
		<strong id="m2"></strong>
		<div id="first"></div>
	</div>
	<div id="second"></div>
</div>
 
</body>
</html>

Code css : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
#cadre{margin:50px;display:flex;}
#second{overflow:auto;height:300px;margin:50px;}
table{border-collapse:collapse;height:300px;}
caption, thead{background:lime;font-weight:bold;}
td, th{padding:5px;border:1px solid black;}
strong{display:block;margin:10px;font-weight:bold;}
tr td:first-child{background:lime;font-weight:bold;}


Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
window.addEventListener("DOMContentLoaded",()=>{
//*******************************************************************************
// tableau des distances entre villes
const t={
	"Marseille"	:{"Nantes":985,"Caen":1000,"Paris":780,"Lille":1000,"Lyon":315},
	"Lyon"		:{"Nantes":685,"Caen":700,"Paris":460,"Lille":700},
	"Lille"		:{"Nantes":600,"Caen":390,"Paris":225},
	"Paris"		:{"Nantes":385,"Caen":240},
	"Caen"		:{"Nantes":320},
	"Nantes"	:null}
//*******************************************************************************
// tableau des villes
let lg=[];
for (i in t) {lg.push(i)};
lg.reverse();
//*******************************************************************************
// variables pour affichage html du tableau des distances
const tab=document.createElement("table"),
cap=document.createElement("caption"),
head=document.createElement("thead"),
tb=document.createElement("tbody"),
tr=document.createElement("tr"),
td=document.createElement("td"),
th=document.createElement("th");
//*******************************************************************************
// affichage du tableau
cap.textContent="Voici le tableau des distances";
tab.appendChild(cap); 
tab.appendChild(head); 
head.appendChild(th);
tab.appendChild(tb); 
document.getElementById("first").appendChild(tab);
lg.forEach((v,i,t)=>{if(i<t.length-1){let it=th.cloneNode();it.textContent=v;head.appendChild(it)}})
// gestion du tableau "en triangle"
for (i in t){if(t[i]!=null){
	let l=tr.cloneNode();tb.appendChild(l);
	let cel=td.cloneNode();cel.textContent=i;l.appendChild(cel);
	for (j in t[i]){let cel=td.cloneNode();cel.textContent=t[i][j];l.appendChild(cel)}};
}
//*******************************************************************************
// génération des permutations
const run=((t,t2,n)=>{
	t.map(v=>t2.map(w=>{if(!v.includes(w))t.push([...v,w])}));
	t.splice(0,n);
	return t[0].join(",")!=t2 ? run(t,t2,t.length) : t
})
const tour=run([[]],lg,1)
//*******************************************************************************
// ajout de la ville de départ en fin de chaque parcours
tour.forEach(v=>v.push(v[0]));
//*******************************************************************************
// calcul des distances cumulées et insertion en début de tableau
tour.forEach(v=>{
	let tot=0;
	v.map((v2,i,ta)=>{
	if(i<ta.length-1){tot+= t[v2] && t[v2][ta[i+1]] ? t[v2][ta[i+1]] : t[ta[i+1]][v2]}
		else{ta.unshift(tot)}
	});
});
//*******************************************************************************
// tri croissant des kilométrages
tour.sort((a,b)=>a[0]-b[0])
//*******************************************************************************
// variables pour affichage html du tableau des parcours
const tab2=document.createElement("table"),
cap2=document.createElement("caption"),
tb2=document.createElement("tbody");
//*******************************************************************************
// affichage du tableau
cap2.textContent="Kilométrage selon les itinéraires possibles";
tab2.appendChild(cap2);
tab2.appendChild(tb2); 
document.getElementById("second").appendChild(tab2);
tour.forEach(v=>{
	let l=tr.cloneNode();tb2.appendChild(l);
	v.forEach(v2=>{
		let cel=td.cloneNode();cel.textContent=v2;l.appendChild(cel);
	})
})
//*******************************************************************************
// affichage de la liste de villes en haut du document
for(i in lg){
	document.getElementById("m2").textContent+=lg[i]+ " "
}
//*******************************************************************************
 
})