* 求存活概率问题
*
* 三个小伙子同时爱上了一 个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。
* 小李的命中率是30%,
* 小黄比他好些,命中率是50%,
* 最出色的枪手是小林,他从不失 误,命中率是100%。
* 由于这个显而易见的事实,为公平起见,他们决定按这样的顺序:小李先开枪,小黄第二,小林最后。
* 然后这样循环,直到他们只剩下一个 人。
* 那么这三个人中谁活下来的机会最大呢?他们都应该采取什么样的策略?
*
* 很明显:
* 小李应该先向小林射击,因为如果他向小黄射击,如果碰巧击中那他之后必死无疑,既然这样先向小黄
* 射击就没有意义了。
* 而小黄在小林还活着的情况,肯定也先向小林开枪。
* 而小林在小黄还活着的情况下自然先向命中率更高的小黄开枪。
*/
public class Shoot {
<span style="white-space:pre"> </span>private boolean isFirstAlive;
<span style="white-space:pre"> </span>private boolean isSecondAlive;
<span style="white-space:pre"> </span>private boolean isThirdAlive;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private long firstAliveNum = 0;
<span style="white-space:pre"> </span>private long secondAliveNum = 0;
<span style="white-space:pre"> </span>private long thirdAliveNum = 0;
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private static Map<Boolean, Integer> counterDict = new HashMap<Boolean, Integer>();
<span style="white-space:pre"> </span>static{
<span style="white-space:pre"> </span>counterDict.put(true, 1);
<span style="white-space:pre"> </span>counterDict.put(false, 0);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>private void init(){
<span style="white-space:pre"> </span>isFirstAlive = true;
<span style="white-space:pre"> </span>isSecondAlive = true;
<span style="white-space:pre"> </span>isThirdAlive = true;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private void clear(){
<span style="white-space:pre"> </span>firstAliveNum = 0;
<span style="white-space:pre"> </span>secondAliveNum = 0;
<span style="white-space:pre"> </span>thirdAliveNum = 0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 如果小黄第一次不放空枪
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>public void startGame(){
<span style="white-space:pre"> </span>init();
<span style="white-space:pre"> </span>int shootNum = 0;
<span style="white-space:pre"> </span>while(!isGameOver()){
<span style="white-space:pre"> </span>if(isFirstAlive){
<span style="white-space:pre"> </span>shootNum = (int) (Math.random() * 10);
<span style="white-space:pre"> </span>if(shootNum <= 2){
<span style="white-space:pre"> </span>if(isThirdAlive){
<span style="white-space:pre"> </span>isThirdAlive = false;
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>isSecondAlive = false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(isSecondAlive){
<span style="white-space:pre"> </span>shootNum = (int) (Math.random() * 2);
<span style="white-space:pre"> </span>if(shootNum == 1){
<span style="white-space:pre"> </span>if(isThirdAlive){
<span style="white-space:pre"> </span>isThirdAlive = false;
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>isFirstAlive = false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(isThirdAlive){
<span style="white-space:pre"> </span>if(isSecondAlive){
<span style="white-space:pre"> </span>isSecondAlive = false;
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>isFirstAlive = false;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(isFirstAlive){
<span style="white-space:pre"> </span>firstAliveNum++;
<span style="white-space:pre"> </span>}else if(isSecondAlive){
<span style="white-space:pre"> </span>secondAliveNum++ ;
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>thirdAliveNum++;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 如果小黄第一次放空枪
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>public void startGame2(){
<span style="white-space:pre"> </span>init();
<span style="white-space:pre"> </span>int shootNum = 0;
<span style="white-space:pre"> </span>while(!isGameOver()){
<span style="white-space:pre"> </span>// 小黄还活着,由他射击
if(isSecondAlive) {
// 如果小林还活着就先向小黄开枪,毫无疑问;否则向小李开枪
shootNum = (int)(Math.random() * 2);
if(shootNum == 1) { // 命中率为二分之一
if(isThirdAlive) {
isThirdAlive = false;
}
else {
isFirstAlive = false;
}
}
}
// 神枪手小林还活着
if(isThirdAlive) {
// 如果小黄还活着,先向他射击
if(isSecondAlive) {
isSecondAlive = false;
}
else {
isFirstAlive = false;
}
}
// 小李还存活,由他射击
if(isFirstAlive) {
// 如果小林还存活就向小林开枪,如果小林挂了,那么说明小黄还活着,则向小黄开枪
shootNum = (int)(Math.random() * 10);
if(shootNum <= 2) { // 命中率为十分之三
if(isThirdAlive) {
isThirdAlive = false;
}
else {
isSecondAlive = false;
}
}
}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(isFirstAlive){
<span style="white-space:pre"> </span>firstAliveNum++;
<span style="white-space:pre"> </span>}else if(isSecondAlive){
<span style="white-space:pre"> </span>secondAliveNum++ ;
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>thirdAliveNum++;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public void startGame(long num, boolean isFirstShootNull){
<span style="white-space:pre"> </span>clear();
<span style="white-space:pre"> </span>for(int i= 0; i< num; i++){
<span style="white-space:pre"> </span>if(isFirstShootNull){
<span style="white-space:pre"> </span>startGame2();
<span style="white-space:pre"> </span>}else{
<span style="white-space:pre"> </span>startGame();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>System.out.println("执行次数:"+num);
<span style="white-space:pre"> </span>System.out.println("小李获胜概率:"+ BigDecimal.valueOf((double)firstAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%");
<span style="white-space:pre"> </span>System.out.println("小黄获胜概率:"+ BigDecimal.valueOf((double)secondAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%");
<span style="white-space:pre"> </span>System.out.println("小林获胜概率:"+ BigDecimal.valueOf((double)thirdAliveNum/num*100).divide(BigDecimal.valueOf(1), 4, RoundingMode.HALF_UP)+"%");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>private boolean isGameOver() {
<span style="white-space:pre"> </span>return counterDict.get(isFirstAlive) + counterDict.get(isSecondAlive) + counterDict.get(isThirdAlive) == 1;
<span style="white-space:pre"> </span>}
}
public class ShootMain {
/**
* @param args
*/
public static void main(String[] args) {
Shoot shoot = new Shoot();
System.out.println("小李第一不放空枪----------------------");
shoot.startGame(1000000, false);
System.out.println("------------------------------------");
System.out.println("小李第一枪放空枪----------------------");
shoot.startGame(1000000, true);
System.out.println("------------------------------------");
}
}