My boys and I enjoy playing a mobile version of the classic battleship game when we are waiting our turn at the barbershop. However, the artificial intelligence algorithm this specific game uses is so feeble that even my youngest son can consistently beat the computer player. So, I started thinking about improving the algorithm. I searched the web to see if there was already an established, dominant algorithm. Although I found several clever implementations, including one that used probabilities and another based upon a checkerboard pattern, I did not find one that I particularly enjoyed. After thinking about the problem further I came to the conclusion that this problem would be well suited for a dynamic programming algorithm.
From my perspective, the best approach to take when searching for the opponent’s ship is to target a square that is in the center of the longest line of unmarked squares. It would be even better to find a target which is at the intersection of two long lines of unchecked squares. To me, this is an effective divide and conquer approach similar in spirit to the concept of binary trees, the problem is finding an efficient algorithm. The problem seems to lend itself perfectly to the dynamic programming approach.
Despite its name, many programmers have never heard of dynamic programming. In all fairness, it is not really programming in that sense of the word, rather it is a mathematical method for dividing problems into smaller subproblems and then combing those parts to form an optimal solution. The “programming” portion of “dynamic programming” probably shares more in common with “television programming,” since they both involve using tables to organize data. The technique is taught in advanced computer science classes, so computer scientists and software engineers should be familiar with the technique.
Dynamic programming is a general technique which involves four basic steps: determine the structure of an optimal solution; recursively define values of the optimal solution; compute the optimal solution; and, if you need to know the optimal path in addition to the computed optimal solution value, construct the value formed by the path. The code on this page shows all of these parts, so it may help in understanding the technique.</div>
The world has recently experienced an economic depression the likes of which have not been seen since the Great Depression. World leaders have been struggling for over three years to keep this economic calamity from destroying social institutions and precipitating war as the last one did. Of the tools and techniques that were used in the 1930s to restore American economic prosperity there is one that has been neglected. Not only has this tool remained unused during the current depression, but it has been actively attacked. That tool is organized labor.
Like other labor movements, the American labor movement began to appear with the onset of industrialization. In its early years American labor was weak, decentralized, and probably not classifiable as a movement. It was not until the Great Depression that unionization gained the institutional acceptance that it needed to truly become a movement. However, as Americans learned with the “Nobel Experiment” of Prohibition, laws and institutional changes cannot alter society without the acceptance of the people. The 1936 Akron Rubber Strike marks the moment when the ideas of policy makers met the hands of labor and the American labor movement began its ascent.
It can be demonstrated that the 1936 Akron Rubber Strike was a pivotal event by examining the changed attitude of Goodyear’s management team. Prior to the rubber strike Goodyear felt that it had the upper hand, while afterwards management’s tone was much more conciliatory. The chronology of events will establish that this change in attitude was caused by the workers themselves and not simply foisted upon the company and its employees by “professional strike leaders” as Goodyear’s president at the time asserted.1