Deterministic algorithm

In computer science, a deterministic algorithm is an algorithm which, in informal terms, behaves predictably. If it runs on a particular input, it will always produce the same correct output, and the underlying machine will always pass through the same sequence of states. Deterministic algorithms are by far the most studied and familiar kind of algorithm, as well as one of the most practical, since they can be run on real machines efficiently.
One simple model for deterministic algorithms is the mathematical function; just as a function always produces the same output given a certain input, so do deterministic algorithms. The difference is that algorithms describe precisely how the output is obtained from the input, whereas abstract functions may be defined implicitly.
Formal definition
Formally, deterministic algorithms can be defined in terms of a state machine: a state describes what a machine is doing at a particular instant in time. State machines pass in a discrete manner from one state to another. Just after we enter the input, the machine is in its initial state or start state. If the machine is deterministic, this means that from this point onwards, its current state determines what its next state will be; its course through the set of states is predetermined. Note that a machine can be deterministic and still never stop or finish, as long as we can predict with certainty what states it will pass through.
Examples of particular abstract machines which are deterministic include the deterministic Turing machine and deterministic finite automaton.
What makes algorithms nondeterministic?
A variety of factors can cause an algorithm to behave in a way which is not deterministic, or nondeterministic:
 If it uses external state other than the input, such as user input, a global variable, a hardware timer value, a random value, or stored disk data.
 If it operates in a way that is timingsensitive, for example if it has multiple processors writing to the same data at the same time. In this case, the precise order in which each processor writes its data will affect the result.
 If a hardware error causes its state to change in an unexpected way.
Although real programs are rarely purely deterministic, it is easier for humans as well as other programs to reason about programs that are. For this reason, most programming languages and especially functional programming languages make an effort to prevent the above events from happening except under controlled conditions. Because of the way such restrictions enforce determinism, deterministic algorithms are sometimes called purely functional.
Problems with deterministic algorithms
Unfortunately, for some problems deterministic algorithms are also hard to find. For example, there are simple and efficient probabilistic algorithms that determine whether a given number is prime but have a very small chance of being wrong. These have been known since the 1970s (see for example Fermat primality test); only after another 30 years of focused research was a deterministic algorithm found, and it remains considerably slower in practice.
As another example, NP complete problems, which include many of the most important practical problems, can be quickly solved using an imaginary massively parallel machine called a nondeterministic Turing machine, but efficient practical algorithms have never been found for any of them. At best, we can currently only find approximate solutions or solutions in special cases.
Another major problem with deterministic algorithms is that sometimes, we don't want the results to be predictable. For example, if you are playing an online game of blackjack that shuffles its deck using a pseudorandom number generator, a clever gambler might guess precisely the numbers the generator will choose and so determine the entire contents of the deck ahead of time, allowing them to cheat (this has actually happened!) Similar problems arise in cryptography, where private keys are often generated using such a generator. This sort of problem is generally avoided using a cryptographically secure pseudorandom number generator.