- commit
- ffb400a789b9abb5ba727e96ec4df66aa549eafe
- parent
- 555ff4935ee4dad738d61af2d25668e81f10e0fd
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2026-01-28 09:46
optimize permutations - faster because there is less allocations (?) - skip some permutations based on their lowest possible score
Diffstat
| M | xiwal/scheme.py | 49 | ++++++++++++++++++++++++++++++++++++------------- |
1 files changed, 36 insertions, 13 deletions
diff --git a/xiwal/scheme.py b/xiwal/scheme.py
@@ -1,5 +1,4 @@ 1 1 import functools2 -1 import itertools3 2 import math 4 3 5 4 from . import lch @@ -41,16 +40,40 @@ def distance(color, i): 41 40 return d ** 4 * c, c 42 41 43 4244 -1 def score(colors):45 -1 sum_score = 046 -1 sum_chroma = 047 -148 -1 for i, color in enumerate(colors):49 -1 score, chroma = distance(color, i)50 -1 sum_score += score51 -1 sum_chroma += chroma52 -153 -1 return sum_score / sum_chroma-1 43 def get_best_subset(colors, n): -1 44 # perf: skip some permutations based on their lowest possible score -1 45 pos = 0 -1 46 indices = [0] * n -1 47 dists = [0] * n -1 48 weights = [1] * n -1 49 best_score = math.inf -1 50 best_colors = None -1 51 while True: -1 52 dists[pos], weights[pos] = distance(colors[indices[pos]], pos) -1 53 score = sum(dists) / sum(weights) -1 54 -1 55 if score < best_score and pos + 1 == n: -1 56 best_score = score -1 57 best_colors = [colors[i] for i in indices] -1 58 -1 59 if score < best_score and pos + 1 < n: -1 60 pos += 1 -1 61 else: -1 62 indices[pos] += 1 -1 63 -1 64 while True: -1 65 if indices[pos] == len(colors): -1 66 if pos == 0: -1 67 return best_colors -1 68 indices[pos] = 0 -1 69 dists[pos] = 0 -1 70 weights[pos] = 1 -1 71 pos -= 1 -1 72 indices[pos] += 1 -1 73 elif indices[pos] in indices[:pos]: -1 74 indices[pos] += 1 -1 75 else: -1 76 break 54 77 55 78 56 79 def scheme(colors, dominant): @@ -76,6 +99,6 @@ def scheme(colors, dominant): 76 99 def colors2scheme(colors): 77 100 colors = [lch.from_hex(c) for c in colors] 78 101 dominant = colors[0]79 -1 colors = min(itertools.permutations(colors, 6), key=score)80 -1 s = scheme(colors, dominant)-1 102 subset = get_best_subset(colors, 6) -1 103 s = scheme(subset, dominant) 81 104 return [lch.to_hex(c) for c in s]