From the linked page (and the one linked beyond that), it's a breadth-first search actually. Keep a list of possible puzzle states at all times, pick a blank cell (theoretically arbitrary, but in practice intelligently for performance), add copies of the state with each possibility for that state added.
Looks nice. Since imports numpy can utilize (more of) numpy's operations to squeeze validation functions and nested fors to one. Should result in shorter code but readability will probably depend on reader's experience in array programming.