新浪新闻客户端

Lanchester战争模型:用可分离变量的微分方程占卜战事

Lanchester战争模型:用可分离变量的微分方程占卜战事
2021年01月23日 22:28 新浪网 作者 超级数学建模

  看过国产的战争题材电视剧《亮剑》的各位老铁一定熟悉李云龙集结重兵攻打县城的故事。在故事中,李云龙利用人数上的优势对平安县城进行了围点打援,最后用二营长的意大利炮消灭了城楼上的鬼子官。

  但是众所周知,抗日时期中国军队的单兵作战能力及武器配备均远不如日本鬼子。因此最终的胜利是取决于李云龙部队的数量优势。

  于是矛盾产生了:当我方在单兵作战效率上不如敌方时,我方需要获得怎样的数量优势已取得战斗的胜利呢?

  早在第一次世界大战期间,英国工程师F.W Lanchester就利用战斗中双方人数的变化率提出了Lanchester战争模型用于预测战争结果。我相信李云龙在打县城之前曾研究过这个模型。

  (图源:某贴吧)

//正经的部分来了

  模型建立:

  首先,我们假设A军在战斗开始后的t时刻有x(t)人,B军在战斗开始后的t时刻有y(t)人。设,且每支军队的减员均由敌方攻击造成,减员速率与敌方人数成正比。忽略增员部队与非战斗减员,我们可以根据双方的减员速率列出如下的微分方程组

  在上述微分方程组中,b与c分别代表B军与A军的单兵作战效率,即每个战士在单位时间内干掉的敌军数量。我们可以用这个量来代表士兵的“质量”或“效率”,显然这个量与军队的武器水平,指挥员的指挥水平与战士的单兵素质有关。

  解原微分方程组,

  由(2)/(1)得, bydy=cxdx//注意这一步,我将含y项与含x项分别移入等号两侧

  对两边同时求不定积分      

  两边同时求至t的定积分       

  稍作处理,             

  得到                          

  下面开始分类讨论:

  我们可以由b,c,与双方初始人数yx计算出K值

  情况1:

  当K=0时,有by²=cx²,即当y=0(B军全部阵亡)时,有x=0(A军全部阵亡)。故存在一个时刻T,双方战平。

  情况2:

  当K>0时,有by²-cx²=K,此时当x=0(A军全部阵亡)时,

  此时B军取得胜利。

  情况3:

  当K

  此时A军取得胜利。

  由以上的讨论我们可以发现,单兵质量上的优势对于整体作战能力的贡献是线性的,但是数量优势与对于整体作战能力的贡献是成平方关系的。这也就能解释为什么在二战中苏联红军在装备,指战员才能与单兵作战能力均不如德军的情况下能够以自身绝对的数量优势战胜敌军。

  (图源:百度图片)

  作为一个热爱计算机编程的高二狗,本能告诉我这种数学模型可以代入计算机由程序解决。于是我在学校上课期间(基本上是下课的时候),冒着被老班收掉MacBook Pro的风险写下了如下Java小程序(不要告诉老师O(∩_∩)O谢谢)

  public class Army {

     private String name;

     private double quantity;

     private double warIndex;

     public Army(){

         name="";

         quantity=0;

      }

     public Army(String n,double q,double i){

         name=n;

         quantity=q;

         warIndex=i;

      }

     public double getQuantity() {

         return quantity;

      }

     public double getWarIndex() {

         return warIndex;

      }

     public String getName() {

         return name;

      }

  }

  //以上我创建了一个“Army”类(请自动将所有的Index(指数)看成coefficient(系数))

  //下面我需要一个客户端,以进行相关运算

  import java.util.Scanner;

  public class Client{

     public static void main(String[] args){

         double K;

     Scanner sc=new Scanner(System.in);

         Scanner reader=new Scanner(System.in);

     System.out.println("Please input the name/quantity/warIndex of army1:");

     Army army1=new Army(sc.nextLine(),sc.nextDouble(),sc.nextDouble());

         System.out.println("Please input the name/quantity/warIndex of army2:");

         Army army2=newArmy(reader.nextLine(),reader.nextDouble(),reader.nextDouble());

         K=army2.getWarIndex()*Math.pow(army2.getQuantity(),2)-army1.getWarIndex()*Math.pow(army1.getQuantity(),2);

         if(K==0){

             System.out.println("It's a tie");

         }

         else if(K

             double rest=Math.sqrt((-K)/army1.getWarIndex());

             System.out.println(army1.getName()+" "+"wins");

             System.out.println("The rest quantity of "+""+army1.getName()+":"+rest);

         }

         else if(K>0){

             double rest=Math.sqrt((K)/army2.getWarIndex());

             System.out.println(army2.getName()+" "+"wins");

             System.out.println("The rest quantity of "+""+army2.getName()+":"+rest);

         }

      }

  }

  //(嘘!传说李云龙在战前用这个程序算了一卦)

下面我们来举一个栗子:假设李云龙的八路军有100人,鬼子有50人,设双方单兵作战效率均为1(客观地说,当时不太可能),两军交战.则经过程序处理后,运行得到下列结果:

  Please input the name/quantity/warIndex ofarmy 1:

  Balu

  100

  1

  Please input the name/quantity/warIndex ofarmy 2:

  Guizi

  50

  1

  Balu wins

  The rest quantity of  Balu:86.60254037844386

  Process finished with exit code 0

  即当鬼子被全歼时,八路军剩余约87人(阵亡13人)

  现在给太君们一个翻盘的机会:将每个鬼子的单兵作战效率提升至八路军的4倍(2的平方)

  运行客户端程序,得到下列结果:

  Please input the name/quantity/warIndex ofarmy 1:

  Balu

  100

  1

  Please input the name/quantity/warIndex ofarmy 2:

  Guizi

  50

  4

  It's a tie

  Process finished with exit code 0

  Oops!即使拥有了4倍于对方的效率,可怜的鬼子还是赢不了,只能与八路打成平手。(请各位老铁自己去看看《亮剑》,估计一下李云龙部队的数量是投入战斗的鬼子的几倍)

  这样一来,数量优势对于整体作战能力的贡献是成平方关系的规律得到了验证。这个规律也就是兰彻斯特平方定律。

  利用这个数学模型,我们不用再去庙里给菩萨上香或是夜观天象,而是可以理性地利用科学占卜战事走向,根据敌我双方实力做出合理的兵力分配,以获得最大程度的作战效益。

  这里还有2个问题有待解决:如何确定敌我双方的单兵作战效率(即系数b,c)?如何最佳地规定单位时间的设置?对于后者,我作为一个没有上过军校或战场的高中生并没有资格发言。但是对于前者,我写了一个程序,但是不确定正确与否,由于时间仓促加之老班太严,我并不能在交稿前对其进一步研究。

  这里仅附上其源代码,供评论区各位大佬批评指正。

  import java.util.Scanner;

  public class warIndex {

     public static void main(String[] args){

         int n,counter;

         double sum1,sum2;

         sum1=0;

         sum2=0;

         System.out.println("Please input the quantity (in groups) ofdata");

         Scanner reader=new Scanner(System.in);

         n=reader.nextInt();

         double[] warIndex1=new double[n+1];

         double[] warIndex2=new double[n+1];

         System.out.println("Please input the casualty of army1(group bygroup):");

         Scanner rd=new Scanner(System.in);

         double[] cas1=new double[n+1];

         for (counter=0;counter

             cas1[counter]=rd.nextDouble();

         }

         System.out.println("Please input the total quantity of army1(groupby group):");

         Scanner rdd=new Scanner(System.in);

          double[] quantity1=new double[n+1];

         for (counter=0;counter

             quantity1[counter]=rdd.nextDouble();

         }

         System.out.println("Please input the casualty of army2(group bygroup):");

         Scanner scc=new Scanner(System.in);

         double[] cas2=new double[n+1];

         for (counter=0;counter

             cas2[counter]=scc.nextDouble();

         }

         System.out.println("Please input the total quantity of army2(groupby group):");

          Scanner rddd=new Scanner(System.in);

         double[] quantity2=new double[n+1];

         for (counter=0;counter

             quantity2[counter]=rddd.nextDouble();

         }

         System.out.println("Please input the time consumed forbattles(group by group):");

         double[] time=new double[n+1];

         Scanner scanner=new Scanner(System.in);

         for (counter=0;counter

             time[counter]=scanner.nextDouble();

         }

         for (counter=0;counter

             warIndex1[counter]=cas2[counter]/(quantity1[counter]*time[counter]);

         }

         for (counter=0;counter

             sum1=sum1+warIndex1[counter];

         }

         for (counter=0;counter

             warIndex2[counter]=cas1[counter]/(quantity2[counter]*time[counter]);

         }

         for (counter=0;counter

             sum2=sum2+warIndex2[counter];

         }

         System.out.println("The warIndex of army1="+sum1/n);

         System.out.println("The warIndex of army2="+sum2/n);

      }

  }

  //在上述程序中,用户需要输入所需数据的数量,A军在每场试验性战斗中的阵亡人数,A军在每场试验性战斗中的总人数;B军在每场试验性战斗中的阵亡人数,B军在每场试验性战斗中的总人数及每场战斗的持续时间。最后程序会计算出双方单兵作战效率的平均值供指战员决策时作参考

  最后,我们应该珍爱和平,决不首先发动战争。但是,当祖国受到侵略,人民的生命财产安全受到威胁之时,我们要全方位的武装自己,保家卫国,维护世界和平。

  Dove of peace (图源:百度图片)

特别声明:以上文章内容仅代表作者本人观点,不代表新浪网观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与新浪网联系。
李云龙
权利保护声明页/Notice to Right Holders

举报邮箱:jubao@vip.sina.com

Copyright © 1996-2024 SINA Corporation

All Rights Reserved 新浪公司 版权所有