Optimal task allocation in distributed systems by graph matching and state space search