Brute Force and Ignorance

Computers generally don’t solve problems the same way humans do.

Take Sudoku, for instance. A human Sudoku player will usually look for patterns in the existing numbers, looking for possible spots to place a 1, 2, 3, etc. Or maybe they will notice that a particular square has everything but a 7 and 8, with one in line with another 8, and will deduce what goes where based on that. We look for what makes sense, and try to piece together a rational solution based on logic and observation.

Such relatively sophisticated, creative, intuitive heuristics don’t always represent the easiest way to solve a problem using a computer. Sometimes a simple exhaustive search (one that my former Calculus teacher called the “Brute Force and Ignorance” approach) is best. After all, modern computers have a lot of brute force to bring to bear!

How could one most simply describe how to solve a Sudoku puzzle, given that the solver could follow instructions exactly — and was really, really fast at carrying them out? One method would be to try every single possible combination until something works, backtracking when you come across a dead end. Try to place a “1” in the first blank square, and check to see if there are any conflicts. If not, good — write it down and solve the remaining puzzle. If no such solution exists, or the “1” doesn’t fit, erase it and try a “2” there — and so on. This is the algorithm presented in an excellent recent Computerphile video about how to solve Sudoku in Python.

For some problems, like Chess, this kind of approach is untenable, since it won’t finish before the expected heat death of the Universe. Chess, while nowhere near as complex as Go, still has something like 10^120 possible games.

For Sudoku, however, this works surprisingly well. Most numbers that are tried are dead ends — but if so, they are usually found out quickly. If the algorithm successfully placed a “1,” for instance, it will still blindly try to place a “1” right next to it, since that’s the next step. This will fail, but it will fail quickly, allowing the algorithm to advance and try a “2” and then “3” until it finds something that sticks. No human would check all of these clearly-wrong branches — but they also take much longer to check the plausible ones.

How long would such a dumb, brute-force algorithm take to solve a Sudoku? I wasn’t sure — maybe years? So I tried programming it in C. (Here is the source file.) The example puzzle from the video was solved in about 120 milliseconds on my (ten-year-old but still modern-ish) PC, after having searched 37,652 possible number placements. Not bad!

Next, I looked for a real challenge, and came across what is said to be the world’s hardest Sudoku puzzle…

The “World’s hardest Sudoku,” by Arlo Irkala of AISudoku.com.

This is a nasty one! Nothing obvious jumps out at you, although in a few cases, you can narrow down the choices a bit and start to make progress. I entered in the data and re-ran the program.

This puzzle put up a good fight — there was actually a noticeable pause before the solution displayed — but roughly 1.65 seconds (and maybe something like five billion clock cycles) later, the unique solution popped up:

Nasty, but still solvable!

Lots of progress has been made on many fascinating, important problems by coming up with new algorithms. QuickSort, hashes, distributed computing, heuristics, and similar advancements have made efficient search engines possible. Clever branch-and-bound approaches have enabled Chess (and probably Go) engines to outplay any human.

But sometimes, all you really need is a big hammer.

Posted in Algorithms, C, Coding, Math | Tagged , , , , , | Leave a comment

Back EMF

V = L*di/dt. It’s what inductors do.

While working on an electromagnetic project, I needed to control a series of solenoid coils. This sort of thing is usually handled by switching the low side — connect one terminal of each coil to a power rail, and use an NFET to connect the other side to ground when you want to fire it.

It’s great in theory — but the problem with inductive loads is that they react badly to having the current cut off, generating a potentially very large voltage across their terminals as the magnetic field collapses in response to a cutoff of the current to the coil. (Inductors are sometimes thought of as “mass” when comparing electronic oscillators to mechanical mass-and-spring systems. An inductor with current flowing through it is somewhat like a moving electrical mass. All that energy has to go somewhere!)

Many MOSFETs, including the IRF510s I was using, have a built-in flyback diode to address this problem. (You can see this on the datasheet as a diode with its anode connected to the source and its cathode connected to the drain.) This diode is reverse biased against the normal voltage present across the FET when it’s off, but allows current to continue flowing when the FET cuts off. Theoretically, roughly the same current should continue flowing in the coil since the diode would continue to conduct once the voltage became over 600mV or so.

An exploded IRF510 NMOSFET.
Inductors can store quite a bit of energy!

Or, rather, that’s what was supposed to happen. What actually happened was a 100ms coil firing, followed by the FET turning into a small firecracker.

It’s pretty clear what happened — when the current was interrupted, the flyback diode couldn’t handle the inrush current from the coil. The datasheet claimed a pulse current rating of 20A and each coil has a resistance of roughly 2 ohms. So at 30V (the setting which caused the explosion), it should have seen a current of about 15A, even assuming a zero-ohm on resistance.

This actually worked out fine for the pulse itself (the coil did fire), but was apparently too much for the flyback diode. The preliminary postmortem is that it seems to have been basically vaporized by the current pulse, blowing the encapsulation in half and somehow even managing to kill the controlling Arduino in the process. (I’ll reuse what I can from it — maybe I can just swap out the chip.) Note to self: FETs can send killer pulses up the gate lead when caused to explode.

Oh, well. Beefier transistors and some large Schottky diodes should hopefully fix the issue. And some protection for the Arduino. I suppose I could just lower the rail voltage — but where’s the fun in that?

Posted in Analog, Arduino, Digital, Electronics, Fundamentals, Power, Toys | Tagged , , , , , | Leave a comment

Qu’est-ce que JeVois?*

One of the best things about embedded electronics is that it seems to always be Christmastime. Inventive engineers are constantly coming up with devices to make previously complex tasks routine and previously impossible tasks merely challenging. Problems that you thought were next to impossible are solved by a new magic component. Arduinos made programming a breeze. NeoPixels let us offload RGB LED duty cycle loops basically onto the LEDs themselves. Cheap optical TOF sensors made distance sensing into a science rather than an art.

One of the hardest problems to solve, traditionally, has been that of Computer Vision. Capturing good images has recently become easier, with decent CMOS sensors allowing image capture and playback. Analysis of these images, however, has generally required a powerful PC with GPU as well as specialized software.

The JeVois A33 computer vision camera (Image: JeVois.org)

The JeVois (French for “I see”) A33 computer vision camera changes that. It consists of a quad-core processor with GPU combined with an onboard camera, with console and video streaming access via a Mini USB connector.

The quad-core processor is the key. The JeVois, as small as it is, actually has enough processing speed to analyze and modify its video feed in real time. It can be programmed to identify objects, for example, or count the dots on dice, or read QR codes and barcodes, or serve as a lanekeeping device when driving.

A screenshot of the JeVois detecting multiple
QR codes (which it can do at ~60fps!)

The neat part is, there’s enough processing power onboard to analyze the images as they’re captured and distill out the important information. The contents of QR codes can be sent as plain, easy-to-parse text to a PC, Raspberry Pi, or even a simple 8-bit microcontroller via a 4-pin serial port. The JeVois does all the heavy lifting.

In other words, Arduinos just learned how to see the world — and understand much of what they see. (And it’s all open source!)

I love living in the future.

* French pun: “Qu’est-ce que je vois?” means “What do I see?,” whereas “Qu’est-ce que JeVois?” means “What is JeVois?” It’s a clever name for a clever device.

Posted in Arduino, Current Events, Digital, Tools, Toys | Tagged , , | Leave a comment

Darwin’s Polyhedra

Evolution by natural selection is a powerful algorithm that has come up with all of the variety of life we see on Earth. By keeping what works and discarding the ideas that don’t, populations can evolve over time to better fit their environment.

The same idea can be used to find solutions to given computational problems, as well. The field of Genetic Algorithms / Genetic Programming uses Darwinian evolution to search for solutions to various problems. Candidate solutions are encoded as gene sequences — perhaps a series of bytes, with each byte representing some parameter of the candidate solution. Each generation, the solutions are all tested and ranked, with better solutions having a higher chance to be selected to produce the next generation. Selected parent genomes are combined via crossover (with some mutation) to produce new genomes to be evaluated in the next generation.

One good way to test how well such an approach works is to try it out on problems for which you already know at least some solutions. For example, the Tammes Problem asks what is the greatest size disc for which you can fit N such discs on the surface of a sphere. Equivalently, what is the maximum, minimum distance possible between any two of N points on the surface of a sphere?

Solutions to such a problem can be expressed in genetic form, suitable for being acted upon by evolutionary forces. The position of each point is expressed in altitude and azimuth angles, sufficient to cover the surface of the unit sphere. (Note to self: explore using quaternions.) The simulation is then run, with the function that determines evolutionary fitness being the minimum distance between any two points. Solutions can then be visualized as polyhedra, where the unit sphere is cut by planes normal to the vector from the origin to each point. This results in an N-sided polyhedron — although sometimes a rather weird, lumpy one at first.

The best “cube” of generation 1.
Not very impressive at some 19.3% error — but that quickly improves!

For “easy” problems such as N=6, this approach quickly produces a nearly-optimal solution. Six equally-spaced points on the unit sphere will be farthest apart when they are in the form of a cube. For example, points at (1,0,0) and (0,1,0) could be two such points, 90 degrees apart. The optimal Tammes distance for N=6, then, is sqrt(2).

For N=6, the genetic approach described above very quickly converges to the expected cube solution, with point positions very nearly the expected distance apart. (A typical result differs from sqrt(2) by well under one part per million, if left to run for a while.)

The best cube of Generation 2941 (and the previous thousand or so) —
a cube with a measurement error of ~12.293 parts per million.)

Some values of N produce interesting results. For N=8, the most typical result is an anti-prism, similar to the platonic octohedron, but with four of the points rotated by 45 degrees. (When you think about it, it makes sense; the points are farther apart that way.)

An antiprism octahedron. It’s not the Platonic solid, but it would be a fair die.

Larger values seem to pose greater challenges to this approach; N=12 sometimes produces the expected Platonic regular dodecahedron, but more often will get stuck in a local minimum, producing a somewhat symmetrical shape. (Like in nature, Darwinian evolution doesn’t always produce a *perfect* solution — just whatever seems to get the job done best. )

Various somewhat-symmetric “grown” polyhedra.
All except for the 8-gon are irregular, but with striking symmetries.
From left to right: Irregular 10-sider; antiprism 8-sider; 7-hedron; 9-hedron.

The next goal: try to grow a regular icosahedron.

Posted in 3D Printing, Algorithms, Coding, Genetic Algorithms, Math, Science | Tagged , , , , , , , | Leave a comment