Initial commit: greedy nearest-neighbour and total
dkl9

dkl9 commited on 2025-184 18:43:57
Showing 1 changed files, with 30 additions and 0 deletions.

... ...
@@ -0,0 +1,30 @@
1
+import math
2
+import typing
3
+import collections.abc
4
+
5
+Func: typing.TypeAlias = collections.abc.Callable
6
+DistTable: typing.TypeAlias = list[list[float]]
7
+IndSeq: typing.TypeAlias = list[int]
8
+
9
+def distance_table[T](points: list[T], metric: Func[[T, T], float]) -> DistTable:
10
+    return [[metric(x, y) for y in points] for x in points]
11
+
12
+def score_nearest(distances: DistTable, sample: IndSeq) -> float:
13
+    return sum(min(distances[i][j] for j in sample) for i in range(len(distances)))
14
+
15
+def score_total(distances: DistTable, sample: IndSeq) -> float:
16
+    return sum(sum(
17
+        0 if i in sample else distances[i][j] for j in sample
18
+    ) for i in range(len(distances)))
19
+
20
+def greedy_min_seq(distances: DistTable, score_func: Func[[DistTable, IndSeq], float]) -> IndSeq:
21
+    seq = []
22
+    options = set(range(len(distances)))
23
+    while options:
24
+        best = min(options, key=lambda o: score_func(distances, seq + [o]))
25
+        seq.append(best)
26
+        options.remove(best)
27
+    return seq
28
+
29
+dt: DistTable = distance_table([(0, 2), (3, 2), (4, 2), (5, 0), (0, 0)], math.dist)
30
+print(greedy_min_seq(dt, score_total))
0 31