The Optimization Trap
About This Sketch
A generative visualization contrasting optimized efficiency with exploratory creativity. The left path shows a straight, optimized trajectory with predictable but limited progress. The right path wanders messily but achieves breakthrough insights through exploration. Watch as the exploratory path achieves greater depth over time despite appearing inefficient—illustrating how the most valuable creative work resists optimization and requires the freedom to explore, wander, and occasionally stumble into breakthroughs.
Algorithm
This sketch visualizes the optimization trap by showing two contrasting paths through a creative problem space. The left path represents the "optimized approach"—straight, efficient, and predictable, advancing upward with minimal variation. The right path represents the "exploratory approach"—wandering, seemingly inefficient, with occasional breakthrough moments that provide significant depth gains.
The visualization tracks "depth" for each path over time. The optimized path shows steady but slow growth, while the wandering path demonstrates the value of exploration: periods of seemingly inefficient meandering punctuated by breakthrough moments (shown as glowing points) that lead to deeper insights. Over time, the exploratory path achieves greater depth despite—or rather, because of—its apparent inefficiency.
This accompanies the blog post "The Optimization Trap" and explores how the things most worth doing often break when we try to optimize them.
Pseudocode
SETUP:
Initialize canvas (400x300)
Create starting points for both paths at bottom
Initialize empty path arrays
DRAW (every frame):
Get current theme colors
Clear background
Draw labels and dividers
Draw ground lines for both paths
Every 8 frames:
OPTIMIZED PATH:
Move upward with minimal horizontal variation
Add small, predictable depth increment (0.5)
Create straight, efficient trajectory
EXPLORATORY PATH:
Wander with significant horizontal variation (-8 to +8)
Random vertical progress
8% chance of breakthrough moment:
If breakthrough: large depth gain (3-6)
If not: modest depth gain (0.3-1.2)
Breakthroughs shown with glowing effect
Draw connecting lines for both paths
Display all path points with age-based fading
Show current depth values for comparison
Remove points older than 200 frames
After 150 frames:
Display key insight: "Valuable work requires inefficiency"
Source Code
let sketch = function(p) {
// Visualization: The Optimization Trap
// Two paths through a creative space
// Left: "Optimized path" - straight, efficient, but shallow and brittle
// Right: "Wandering path" - messy, inefficient, but discovers deeper insights
let optimizedPath = [];
let wanderingPath = [];
let insights = [];
let time = 0;
class PathPoint {
constructor(x, y, depth, isBreakthrough) {
this.x = x;
this.y = y;
this.depth = depth;
this.isBreakthrough = isBreakthrough || false;
this.age = 0;
}
update() {
this.age++;
}
display(colors, isOptimized) {
let alpha = p.map(this.age, 0, 200, 200, 50);
// Draw point
if (isOptimized) {
p.fill(...colors.accent2, alpha);
p.noStroke();
p.circle(this.x, this.y, 3);
} else {
if (this.isBreakthrough) {
// Breakthrough moments glow
p.fill(...colors.accent1, alpha * 0.3);
p.circle(this.x, this.y, 15);
p.fill(...colors.accent1, alpha);
p.circle(this.x, this.y, 8);
} else {
p.fill(...colors.accent3, alpha * 0.7);
p.circle(this.x, this.y, 4);
}
}
}
shouldRemove() {
return this.age > 200;
}
}
p.setup = function() {
p.createCanvas(400, 300);
// Starting points
optimizedPath.push(new PathPoint(90, 250, 0, false));
wanderingPath.push(new PathPoint(310, 250, 0, false));
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
time++;
// Labels
p.fill(...colors.accent3, 220);
p.noStroke();
p.textAlign(p.CENTER, p.TOP);
p.textSize(11);
p.textFont('Georgia');
p.text('Optimized Path', 90, 15);
p.text('Exploratory Path', 310, 15);
// Descriptions
p.textSize(8);
p.fill(...colors.accent3, 180);
p.text('Efficient but shallow', 90, 30);
p.text('Messy but deep', 310, 30);
// Ground line
p.stroke(...colors.accent3, 100);
p.strokeWeight(1);
p.line(20, 260, 180, 260);
p.line(220, 260, 380, 260);
// Dividing line
p.strokeWeight(1);
p.stroke(...colors.accent3, 60);
p.line(200, 45, 200, 260);
// Grow optimized path (straight, predictable, limited depth)
if (time % 8 === 0 && optimizedPath.length > 0) {
let last = optimizedPath[optimizedPath.length - 1];
if (last.y > 60) {
// Straight path up with minimal variation
let newY = last.y - 5;
let newX = last.x + p.random(-1, 1);
let newDepth = last.depth + 0.5; // Slow, predictable growth
optimizedPath.push(new PathPoint(newX, newY, newDepth, false));
}
}
// Grow wandering path (exploratory, unpredictable, breakthrough moments)
if (time % 8 === 0 && wanderingPath.length > 0) {
let last = wanderingPath[wanderingPath.length - 1];
if (last.y > 60) {
// Wandering exploration
let newX = last.x + p.random(-8, 8);
let newY = last.y + p.random(-7, -3);
// Constrain to right side
newX = p.constrain(newX, 240, 380);
// Occasional breakthroughs from wandering
let isBreakthrough = p.random() < 0.08;
let depthGain = isBreakthrough ? p.random(3, 6) : p.random(0.3, 1.2);
let newDepth = last.depth + depthGain;
wanderingPath.push(new PathPoint(newX, newY, newDepth, isBreakthrough));
}
}
// Draw connecting lines for optimized path
p.stroke(...colors.accent2, 100);
p.strokeWeight(2);
p.noFill();
p.beginShape();
for (let point of optimizedPath) {
p.vertex(point.x, point.y);
}
p.endShape();
// Draw connecting lines for wandering path
p.stroke(...colors.accent3, 120);
p.strokeWeight(1.5);
p.noFill();
p.beginShape();
for (let point of wanderingPath) {
p.vertex(point.x, point.y);
}
p.endShape();
// Update and display all points
for (let i = optimizedPath.length - 1; i >= 0; i--) {
optimizedPath[i].update();
optimizedPath[i].display(colors, true);
if (optimizedPath[i].shouldRemove()) {
optimizedPath.splice(i, 1);
}
}
for (let i = wanderingPath.length - 1; i >= 0; i--) {
wanderingPath[i].update();
wanderingPath[i].display(colors, false);
if (wanderingPath[i].shouldRemove()) {
wanderingPath.splice(i, 1);
}
}
// Depth indicators
p.textAlign(p.CENTER);
p.textSize(9);
p.fill(...colors.accent3, 200);
// Calculate depth for each path
if (optimizedPath.length > 0) {
let optDepth = optimizedPath[optimizedPath.length - 1].depth;
p.fill(...colors.accent2, 200);
p.text(`Depth: ${p.floor(optDepth)}`, 90, 270);
}
if (wanderingPath.length > 0) {
let wanderDepth = wanderingPath[wanderingPath.length - 1].depth;
p.fill(...colors.accent1, 200);
p.text(`Depth: ${p.floor(wanderDepth)}`, 310, 270);
}
// Key insight
if (time > 150) {
p.fill(...colors.accent2, 180);
p.textSize(8);
p.textAlign(p.CENTER);
p.text('Valuable work requires inefficiency', 200, 285);
}
// Start points
p.noStroke();
p.fill(...colors.accent2, 220);
p.circle(90, 250, 6);
p.fill(...colors.accent3, 220);
p.circle(310, 250, 6);
};
};