精华内容
下载资源
问答
  • 2021-04-07 10:14:26

    数据类型、变量、控制结构及数组综合实验


    一、实验目的
    综合运用所学数据类型、常量、变量、运算符、控制结构及数组等知识,以达到以下要求:

    1. 掌握数据类型变量、常量的声明和初始化
    2. 能够灵活的使用流程控制解决问题。
    3. 能够熟练的完成数组的的定义与初始化、数组的遍历和排序算法。
      二、实验类型及课时
      验证/设计/综合:综合性试验;课时:2。
      三、实验环境
      装有JAVA语言工具软件 (Eclipse或Eclipse)的微机若干
      四、实验内容
      1、 通过多项式的分析,利用流程控制结构及嵌套,实现下面的求和。
      在键盘上输入n , 编程计算,:
      sum=

    2、 通过分析平面图形,使用嵌套循环,正确输出以下内容:
    1 3 6 10 15
    2 5 9 14
    4 8 13
    7 12
    11

    3、请使用数组存储该数列:8,4,2,1,23,344,12,并结合数组的遍历、以及Arrays类的sort()方法和binarySearch()方法完成下面的要求:
    1)循环输出数列的值
    2)求数列中所有数值的和
    3)猜数游戏:从键盘中任意输入一个数据,判断数列中是否包含此数。

    4、练习数组的排序算法:
    产生0~100的8个随机整数,并利用冒泡排序法将其升序排序后输出(冒泡排序算法:每次进行相邻两数的比较,若次序不对,则交换两数的次序)。
    package array_3;

    import java.util.Arrays;
    import java.util.Random;
    import java.util.Scanner;
    public class for_arrry {
    public static void main(String[] args) {
    Scanner scanf = new Scanner(System.in);
    int n = scanf.nextInt();
    int sum=0;
    for (int i = n; i >0; i–) {
    double num1 = Math.pow(-1, i- 1);
    for (int j=0; j<=n;j++){
    double num2 = 1;
    num2*=1.0/j;
    sum+= num1*num2;
    }
    }
    System.out.print(“和为”+sum);
    }

    public static void question_2(){
        int row = 1;
        for (int i = 1;i<=5;i++){
            int start = row;
            for (int j=i;j<=5;j++){
                System.out.print(row+"\t");
                row+=(j+1);
            }
            row = start+i;
            System.out.println();
        }
    
    }
    public static void question_3(){
        int [] a= {8,4,2,1,23,344,12};
        for (int num : a) {
            System.out.println("成绩为" + num);
        }
        int sum=0;
        for (int j : a) {
            sum += j;
        }
        System.out.print("和为"+sum);
        Scanner scanf = new Scanner(System.in);
        int num_1 = scanf.nextInt();
        int num2=1;
        for (int i=0;i<=a.length;i++){
            if(num_1==a[i]){
                num2=0;
                break;
            }
        }
        if (num2==1){
            System.out.println("该数不在数组中");
        }else {
            System.out.println("该数在数组中");
        }
    }
    public static void question_4(){
        int [] a= new int[8];
        for (int i=0;i<8;i++){
            double random_num= Math.random();
            random_num*=100;
            a[i]= (int) random_num;
        }
        for (int i : a )
            System.out.println(i);
        for (int i = a.length-1; i>0; i--){
            int temp;
            if (a[i]<a[i-1]){
                temp = a[i-1];
                a[i-1]=a[i];
                a[i]=temp;
            }
        }
        System.out.println("输出(冒泡排序)结果为");
        for (int i :a){
            System.out.println(i);
        }
    }
    

    }
    五、实验报告要求
    1. 整理实验结果。
    2. 小结实验心得体会。

    更多相关内容
  • 控制变量方法的一个问题是估计的质量在很大程度上取决于控制变量的选择。 为了解决这个问题并从对数减少的对立变量方法中得到启发,我们建议将对立变量方法与传统的策略梯度相结合,解决多臂匪徒问题。 此外,我们...
  • 产生随机变量 X X X的 N N N个独立同分布随机数 X i , i = 1 , 2 , ⋯   , N X_i,i=1,2,\cdots,N Xi​,i=1,2,⋯,N,用样本均值 X N ‾ = 1 N ∑ i = 1 N X i \overline{X_N}=\frac{1}{N}\sum\limits_{i=1}^{N}X_i ...

    蒙特卡罗求积分

    @author--HCF

    背景概述

    为了解决某问题,首先需要把它变成一个概率模型的求解问题,然后产生符合模型的大量随机数,最后对产生的随机数进行分析从而求解问题,这种方法叫做Monte Carlo(蒙特卡罗)方法。

    比如为了计算圆周率 π \pi π的近似值可以使用随机模拟的方法。如果正方形 D = { ( x , y ) : x ∈ [ − 1 , 1 ] , y ∈ [ − 1 , 1 ] } D=\{(x,y):x\in [-1,1],y\in[-1,1]\} D={(x,y):x[1,1],y[1,1]}内随机等可能投点,落入单位圆 C = { ( x , y ) : x 2 + y 2 ≤ 1 } C=\{(x,y):x^2+y^2\le 1\} C={(x,y):x2+y21}的概率为面积之比 p = π 4 p=\frac{\pi}{4} p=4π。如果独立重复地投了 N N N个点,落入 C C C中的点的个数 ξ \xi ξ的平均值为 E ξ = p N E\xi=pN Eξ=pN,由概率的频率解释可以得到 ξ N ≈ π 4 ,   π ≈ π ^ = 4 ξ N \frac{\xi}{N}\approx\frac{\pi}{4},~\pi\approx\hat{\pi}=\frac{4\xi}{N} Nξ4π, ππ^=N4ξ,从而可以求出 π \pi π

    上例中估计的 π ^ \hat{\pi} π^实际上是随机的,如果再次独立重复投 N N N个点,得到的 π ^ \hat{\pi} π^和上一次结果会有不同,也即结果具有随机性。一般地,假设随机变量 X X X的期望为 θ \theta θ,方差为 σ 2 \sigma^2 σ2。产生随机变量 X X X N N N个独立同分布随机数 X i , i = 1 , 2 , ⋯   , N X_i,i=1,2,\cdots,N Xi,i=1,2,,N,用样本均值 X N ‾ = 1 N ∑ i = 1 N X i \overline{X_N}=\frac{1}{N}\sum\limits_{i=1}^{N}X_i XN=N1i=1NXi估计 θ \theta θ,由中心极限定理可知 X N ‾ \overline{X_N} XN近似服从 N ( θ , σ 2 N ) N(\theta,\frac{\sigma^2}{N}) N(θ,Nσ2),于是随机模拟误差幅度约为 O ( 1 N ) ( N → ∞ ) O(\frac{1}{\sqrt{N}})(N\to\infty) O(N 1)(N),因此为了增加一位小数的精度,即误差减小到原来的 1 10 \frac{1}{10} 101,重复试验次数需要增加都爱原来的 100 100 100倍。

    但是由于随机模拟方法对维数增加不敏感,因此维数的增加造成的影响很小(在计算定积分时,如果使用传统数值算法,维数增加会造成计算时间呈指数增加),因此蒙特卡罗方法被广泛应用到各个领域。本文将探讨其用于求解积分(主要是一维积分,二维或者更高维的积分可以类比推广)的用途,以及各种减小其方差的方法,并使用MATLAB进行模拟计算。

    首先给出基本代码

    clear, clc, tic
    f1 = @(x) sqrt(1-x.^2);
    f2 = @(x) sin(x) ./ x;
    f3 = @(x) exp(x);
    func = f3;
    blk = [0, 1];
    testTimes = 1000000;
    realRes = integral(func, blk(1), blk(2));
    calcRes = zeros(1, 100);
    error = zeros(1, 100);
    
    %=====================================%
    % 此处为各个方法对应的代码
    %=====================================%
    
    fprintf("估算值:%.16f\n", mean(calcRes));
    fprintf("误差:  %.16f\n", mean(error));
    fprintf("方差:  %.16f\n", var(error));
    toc
    

    随机投点法

    在这里插入图片描述

    设被积函数在积分区间 [ a , b ] [a,b] [a,b]上有界,不妨设为 [ 0 , M ] [0,M] [0,M],则求积分 I = ∫ a b h ( x ) d x I=\int_a^b h(x)\mathrm{d}x I=abh(x)dx相当于计算曲线 h ( x ) h(x) h(x)下的区域 D = { ( x , y ) : a ≤ x ≤ b ,   0 ≤ y ≤ h ( x ) } D=\{(x,y):a\le x\le b,~0\le y \le h(x)\} D={(x,y):axb, 0yh(x)}的面积,在此区域 G = [ a , b ] × [ 0 , M ] G=[a,b]\times[0,M] G=[a,b]×[0,M]上做均匀抽样 N N N次,得到随机样本点 D 1 , D 2 , ⋯   , D N = ( X i , Y i ) ,   i = 1 , 2 , ⋯   , N . D_1,D_2,\cdots,D_N=(X_i,Y_i),~i=1,2,\cdots,N. D1,D2,,DN=(Xi,Yi), i=1,2,,N.
    η i = { 1 , D i ∈ D 0 , D i ∉ D , i = 1 , 2 , ⋯   , N \eta_i=\left\{ \begin{array}{rcl} 1 &,& D_i\in D \\ 0 &,& D_i\notin D \end{array}\right., i=1,2,\cdots,N ηi={10,,DiDDi/D,i=1,2,,N
    η i \eta_i ηi独立同分布于 B ( 1 , p ) B(1,p) B(1,p),其中
    p = P ( D i ∈ D ) = S D S G = I M ( b − a ) p=P(D_i\in D)=\frac{S_D}{S_G}=\frac{I}{M(b-a)} p=P(DiD)=SGSD=M(ba)I
    得到随机的投点 D 1 , D 2 , ⋯   , D N D_1,D_2,\cdots,D_N D1,D2,,DN后,由强大数定律可知,当 N → ∞ N\to\infty N时,其落入曲线下方区域 D D D的概率 p ^ \hat{p} p^趋近于 p p p,因此当 N N N足够大的时候,可以通过 N N N个样本点出现在曲线下方的频率来求得积分
    I ≈ I ^ = p ^ M ( b − a ) I\approx\hat{I}=\hat{p}M(b-a) II^=p^M(ba)
    同时可以论证 I ^ \hat{I} I^的误差为 O p ( 1 N ) O_p(\frac{1}{\sqrt{N}}) Op(N 1),也就是说,若采取随机投点法,要提高一位精度,则需要100倍的样本数量。

    根据上面论证编写程序:

    result = zeros(1, testTimes);
    for k = 1:100
        x = unifrnd(blk(1), blk(2), 1, testTimes);
        y = unifrnd(1, 3, 1, testTimes);
        result = y < func(x);
        calcRes(k) = sum(result) / testTimes * 2 + 1;
        error(k) = abs(calcRes(k)-realRes);
    end
    

    期望积分法

    可以看到,随机投点法能够大致估计出积分取值,但是其精度很低,并且需要增加100倍才能提高一位的精度。另一种效率更高的求定积分的方法是利用期望值的估计。设 U ∼ U ( a , b ) U\sim U(a,b) UU(a,b),则
    E [ h ( U ) ] = ∫ a b h ( u ) 1 b − a d u = I b − a , ⇒ I = ( b − a ) ⋅ E h ( U ) E[h(U)]=\int_a^b h(u)\frac{1}{b-a}\mathrm{d}u=\frac{I}{b-a},\Rightarrow I=(b-a)\cdot Eh(U) E[h(U)]=abh(u)ba1du=baI,I=(ba)Eh(U)
    N N N个样本 U 1 , U 2 , ⋯   , U N U_1,U_2,\cdots,U_N U1,U2,,UN独立同分布于 U ( a , b ) U(a,b) U(a,b)分布,则由强大数定律,当 N → ∞ N\to \infty N
    E [ h ( U ) ] = 1 N ∑ i = 1 N h ( U i ) = I ^ b − a E[h(U)]=\frac{1}{N}\sum\limits_{i=1}^N h(U_i)=\frac{\hat{I}}{b-a} E[h(U)]=N1i=1Nh(Ui)=baI^
    因此 I I I的估计值为
    I ^ = b − a N ∑ i = 1 N h ( U i ) \hat{I}=\frac{b-a}{N}\sum\limits_{i=1}^N h(U_i) I^=Nbai=1Nh(Ui)
    可以证明,此方法的误差仍然为 O p ( 1 N ) O_p(\frac{1}{\sqrt{N}}) Op(N 1),但是方差比随机投点法小。

    据此编写程序:

    result = zeros(1, testTimes);
    for k = 1:100
        x = unifrnd(blk(1), blk(2), 1, testTimes);
        result = func(x) / testTimes;
        calcRes(k) = sum(result);
        error(k) = abs(calcRes(k)-realRes);
    end
    

    重要抽样法

    被积函数 h ( x ) h(x) h(x)可能在各处的取值差异很大,如果直接使用平均值估计积分,即均匀采样,很多样本值较小的地方,尤其是接近 0 0 0的地方会浪费较多的点,这样会导致方差比较大,因此考虑非均匀抽样,在 ∣ h ( x ) ∣ |h(x)| h(x)大的地方采集更多的点, ∣ h ( x ) ∣ |h(x)| h(x)小的地方采集更少的点,这样可以更有效地利用样本。

    设非均匀采样密度函数为 g ( x ) g(x) g(x),即在相应 x x x处以 g ( x ) g(x) g(x)的概率密度进行采样,这里 g ( x ) g(x) g(x)的形状与 h ( x ) h(x) h(x)类似。现有 N N N个数据点 X 1 ,   X 2 , ⋯   , X N X_1,~X_2,\cdots,X_N X1, X2,,XN独立同分布于 g ( x ) g(x) g(x),令
    η i = h ( X i ) g ( X i ) ,   i = 1 , 2 , ⋯   , N . \eta_i=\frac{h(X_i)}{g(X_i)},~i=1,2,\cdots,N. ηi=g(Xi)h(Xi), i=1,2,,N.

    E η = ∫ C h ( x ) g ( x ) g ( x ) d x = ∫ C h ( x ) d x = I E\eta=\int_C\frac{h(x)}{g(x)}g(x)\mathrm{d}x=\int_C h(x)\mathrm{d}x=I Eη=Cg(x)h(x)g(x)dx=Ch(x)dx=I
    因此可以用 { η i ,   i = 1 , 2 , ⋯   , N } \{\eta_i,~i=1,2,\cdots,N\} {ηi, i=1,2,,N}的样本均值来估计 I I I,即
    I = E η = 1 N ∑ i = 1 N h ( X i ) g ( X i ) I=E\eta=\frac{1}{N}\sum\limits_{i=1}^N \frac{h(X_i)}{g(X_i)} I=Eη=N1i=1Ng(Xi)h(Xi)
    h ( x ) = e x h(x)=e^x h(x)=ex为例,对被积函数 h ( x ) = e x h(x)=e^x h(x)=ex做泰勒展开得
    h ( x ) = e x = 1 + x + x 2 2 + ⋯   . h(x)=e^x=1+x+\frac{x^2}{2}+\cdots. h(x)=ex=1+x+2x2+.

    g ( x ) = c ( 1 + x ) = 2 3 ( 1 + x ) . g(x)=c(1+x)=\frac{2}{3}(1+x). g(x)=c(1+x)=32(1+x).
    使用逆变换法产生满足 g ( x ) g(x) g(x)密度函数的随机数, g ( x ) g(x) g(x)的分布函数 G ( x ) G(x) G(x)的反函数为
    G − 1 ( y ) = 1 + 3 y − 1 ,   0 < y < 1. G^{-1}(y)=\sqrt{1+3y}-1,~0<y<1. G1(y)=1+3y 1, 0<y<1.
    因此,取 U i U_i Ui独立同分布于 U ( 0 , 1 ) ,   i = 1 , 2 , ⋯   , N U(0,1),~i=1,2,\cdots,N U(0,1), i=1,2,,N,则 X i = 1 + 3 U i − 1 X_i=\sqrt{1+3U_i}-1 Xi=1+3Ui 1服从概率密度 g ( x ) g(x) g(x)的分布

    因此根据重要抽样法,求积分的式子为
    I ^ = 1 N ∑ i = 1 N e X i 2 3 ( 1 + X i ) \hat{I}=\frac{1}{N}\sum\limits_{i=1}^N\frac{e^{X_i}}{\frac{2}{3}(1+X_i)} I^=N1i=1N32(1+Xi)eXi
    据此编写程序如下

    result = zeros(1, testTimes);
    for k = 1:100
        u = unifrnd(blk(1), blk(2), 1, testTimes);
        x = sqrt(1+3*u) - 1;
        result = exp(x) ./ (1 + x) * 1.5 / testTimes;
        calcRes(k) = sum(result);
        error(k) = abs(calcRes(k)-realRes);
    end
    

    控制变量法

    已知两个随机变量 X X X Y Y Y。其中要求的是 X X X的期望,若不通过 Y Y Y来求 X X X的期望,则可以从 X X X中抽取 N N N个独立样本值 X 1 , X 2 , ⋯   , X N X_1,X_2,\cdots,X_N X1,X2,,XN,然后计算 X ‾ = 1 N ∑ i = 1 N X i \overline{X}=\frac{1}{N}\sum\limits_{i=1}^N X_i X=N1i=1NXi来估计 E X .   EX.~ EX.  若通过 Y Y Y来求 X X X的期望,且满足
    E Y = 0 ,   C o v ( X , Y ) < 0 EY=0,~Cov(X,Y)<0 EY=0, Cov(X,Y)<0
    Z ( b ) = X + b Y Z(b)=X+bY Z(b)=X+bY,则
    E Z ( b ) = E X V a r ( Z ( b ) ) = V a r ( X ) + 2 b C o v ( X , Y ) + b 2 V a r ( Y ) EZ(b)=EX\\ Var(Z(b))=Var(X)+2bCov(X,Y)+b^2Var(Y) EZ(b)=EXVar(Z(b))=Var(X)+2bCov(X,Y)+b2Var(Y)
    不难得到,当
    b = − C o v ( X , Y ) V a r ( Y ) = − ρ X , Y V a r ( X ) V a r ( Y ) b=-\frac{Cov(X,Y)}{Var(Y)}=-\rho_{X,Y}\sqrt{\frac{Var(X)}{Var(Y)}} b=Var(Y)Cov(X,Y)=ρX,YVar(Y)Var(X)
    时, Z ( b ) Z(b) Z(b)有最小方差
    V a r ( Z ( b ) ) = ( 1 − ρ X , Y 2 ) V a r ( X ) ≤ V a r ( X ) Var(Z(b))=(1-\rho_{X,Y}^2)Var(X)\le Var(X) Var(Z(b))=(1ρX,Y2)Var(X)Var(X)
    因此,只要 X X X Y Y Y的相关系数不等于 0 0 0,则可以减小方差,。

    h ( x ) = e x h(x)=e^x h(x)=ex为例,先求积分 I = ∫ 0 1 e x d x I=\int_0^1 e^x\mathrm{d}x I=01exdx,理论值为 e − 1 e-1 e1,若使用控制变量法,设 U ∼ U ( 0 , 1 ) U\sim U(0,1) UU(0,1),且 X = e U ,   Y = U − 1 2 X=e^U,~Y=U-\frac{1}{2} X=eU, Y=U21,则可以求得
    E Y = 0 ,   C o v ( X , Y ) ≈ 0.14086 ,   V a r ( Y ) = 1 12 b = − C o v ( X , Y ) V a r ( Y ) ≈ − 1.690 EY=0,~Cov(X,Y)\approx 0.14086,~Var(Y)=\frac{1}{12}\\ b=-\frac{Cov(X,Y)}{Var(Y)}\approx -1.690 EY=0, Cov(X,Y)0.14086, Var(Y)=121b=Var(Y)Cov(X,Y)1.690
    于是抽取 N N N个均匀分布值 U 1 , U 2 , ⋯   , U N U_1, U_2, \cdots,U_N U1,U2,,UN并根据大数定律对 Z i = e U i − 1.690 ( U i − 1 12 ) Z_i=e^{U_i}-1.690(U_i-\frac{1}{12}) Zi=eUi1.690(Ui121)求期望可以得到
    I ^ = 1 N ∑ i = 1 N [ e U i − 1.690 ( U i − 1 12 ) ] . \hat{I}=\frac{1}{N}\sum\limits_{i=1}^N\left[e^{U_i}-1.690(U_i-\frac{1}{12})\right]. I^=N1i=1N[eUi1.690(Ui121)].
    根据上述分析编写代码如下

    func_new = @(x) func(x) - 1.690309 * (x - 0.5);
    result = zeros(1, testTimes);
    for k = 1:100
        x = unifrnd(blk(1), blk(2), 1, testTimes);
        result = func_new(x) / testTimes;
        calcRes(k) = sum(result);
        error(k) = abs(calcRes(k)-realRes);
    end
    

    对偶变量法

    F ( x ) F(x) F(x)为连续分布函数, U ∼ U ( 0 , 1 ) ,   X = F − 1 ( U ) ,   Y = F − 1 ( 1 − U ) ,   Z = X + Y 2 U\sim U(0,1),~X=F^{-1}(U),~Y=F^{-1}(1-U),~Z=\frac{X+Y}{2} UU(0,1), X=F1(U), Y=F1(1U), Z=2X+Y,则显然 X X X Y Y Y同分布,并且可以得到 C o v ( X , Y ) ≤ 0 Cov(X,Y)\le 0 Cov(X,Y)0,因此
    V a r ( Z ) = 1 4 [ V a r ( X ) + V a r ( Y ) + 2 C o v ( X , Y ) ] = 1 2 [ V a r ( X ) + C o v ( X , Y ) ] ≤ 1 2 V a r ( X ) . \begin{array}{rcl} Var(Z) &=& \frac{1}{4}\left[Var(X)+Var(Y)+2Cov(X,Y)\right]\\ &=& \frac{1}{2}\left[Var(X)+Cov(X,Y)\right]\\ &\le& \frac{1}{2}Var(X). \end{array} Var(Z)==41[Var(X)+Var(Y)+2Cov(X,Y)]21[Var(X)+Cov(X,Y)]21Var(X).
    因此,抽取 N N N个样本点 U 1 , U 2 , ⋯   , U N U_1,U_2,\cdots,U_N U1,U2,,UN,则可以令
    Z i = 1 2 ( F − 1 ( U i ) + F − 1 ( 1 − U i ) ) Z_i=\frac{1}{2}\left(F^{-1}(U_i)+F^{-1}(1-U_i)\right) Zi=21(F1(Ui)+F1(1Ui))
    从而求得积分值。以 h ( x ) = e x h(x)=e^x h(x)=ex为例,设 U ∼ U ( 0 , 1 ) ,   X = e U ,   Y = e 1 − U U\sim U(0,1),~X=e^{U},~Y=e^{1-U} UU(0,1), X=eU, Y=e1U,使用对偶变量法可得积分估计值为
    I ^ = 1 N ∑ i = 0 N e U i + e 1 − U i 2 \hat{I}=\frac{1}{N}\sum\limits_{i=0}^N \frac{e^{U_i}+e^{1-U_i}}{2} I^=N1i=0N2eUi+e1Ui
    据此编写程序如下:

    func_new = @(x) (func(x) + func(1 - x)) / 2;
    result = zeros(1, testTimes);
    for k = 1:100
        x = unifrnd(blk(1), blk(2), 1, testTimes);
        result = func_new(x) / testTimes;
        calcRes(k) = sum(result);
        error(k) = abs(calcRes(k)-realRes);
    end
    

    分层抽样法

    分层抽样法将积分区域 C C C分为若干个子集上的积分,使得在每个子集上的变化不大,分别计算各个子集上的积分再求和,从而提高精确度。

    设积分 I = ∫ C h ( x ) d x I=\int_Ch(x)\mathrm{d}x I=Ch(x)dx可以分解为 m m m个不相交的子集 C j C_j Cj上的积分,即
    I = ∫ C h ( x ) d x = ∫ C 1 h ( x ) d x + ∫ C 2 h ( x ) d x + ⋯ + ∫ C m h ( x ) d x I=\int_Ch(x)\mathrm{d}x=\int_{C_1}h(x)\mathrm{d}x+\int_{C_2}h(x)\mathrm{d}x+\cdots+\int_{C_m}h(x)\mathrm{d}x I=Ch(x)dx=C1h(x)dx+C2h(x)dx++Cmh(x)dx
    C j C_j Cj上投 n j n_j nj个随机点 X j i ∼ U ( a j , b j ) ,   i = 1 , 2 , ⋯   , n j X_{ji}\sim U(a_j,b_j),~i=1,2,\cdots,n_j XjiU(aj,bj), i=1,2,,nj,则 I I I m m m个部分可以分别用期望积分求得,因此可以得到最终积分式子为
    I ^ = ∑ j = 1 m b j − a j n j ∑ i = 1 n j h ( X j i ) \hat{I}=\sum\limits_{j=1}^m\frac{b_j-a_j}{n_j}\sum\limits_{i=1}^{n_j}h(X_{ji}) I^=j=1mnjbjaji=1njh(Xji)
    h ( x ) = e x ,   I = ∫ 0 1 h ( x ) d x h(x)=e^x,~I=\int_0^1 h(x)\mathrm{d}x h(x)=ex, I=01h(x)dx为例,若分层数为 2 2 2,则积分式子可以写成
    I = ∫ 0 0.5 e x d x + ∫ 0.5 1 e x d x I=\int_{0}^{0.5}e^x\mathrm{d}x+\int_{0.5}^{1}e^x\mathrm{d}x I=00.5exdx+0.51exdx
    从而根据期望积分法对每一部分进行积分,总共取 N N N个点,可以得到
    I ^ = 0.5 − 0 N / 2 ∑ i = 1 N / 2 e U 1 i + 1 − 0.5 N / 2 ∑ i = ( N / 2 ) + 1 N e U 2 i \hat{I}=\frac{0.5-0}{N/2}\sum\limits_{i=1}^{N/2}e^{U_{1i}}+\frac{1-0.5}{N/2}\sum\limits_{i=(N/2)+1}^{N}e^{U_{2i}} I^=N/20.50i=1N/2eU1i+N/210.5i=(N/2)+1NeU2i
    其中 U 1 i ∼ U ( 0 , 0.5 ) ,   U 2 i ∼ U ( 0.5 , 1 ) U_{1i}\sim U(0,0.5),~U_{2i}\sim U(0.5,1) U1iU(0,0.5), U2iU(0.5,1),根据此方法得到的结果方差可以得到大幅度的减小。

    据分析编写代码如下

    layer = 10000;
    layerStep = 1 / layer;
    N = floor(testTimes/layer);
    result = zeros(1, layer);
    for k = 1:100
        x=unifrnd(blk(1), blk(2),1,testTimes);
        for i = 1:layer
            a = (i - 1) * layerStep;
            b = i * layerStep;
            x = unifrnd(a, b, 1, N);
            result(i) = mean(func(x)) * layerStep;
        end
        calcRes(k) = sum(result);
        error(k) = abs(calcRes(k)-realRes);
    end
    

    Metropolis Hasting算法

    此算法是一个基本的MCMC(马氏链蒙特卡罗)算法。一般地,对于高维或者取值空间 χ \chi χ结构复杂的随机变量 X X X,MCMC方法构造取值于 χ \chi χ的马氏链,使其平稳分布为 X X X的目标分布。模拟此马氏链,抛弃开始的部分抽样值,把剩余部分作为 X X X的非独立抽样。非独立抽样的估计效率比独立抽样低。

    Metropolis Hasting算法在每一步试探地进行转移(如随机游动),如果转移后能提高状态 x t x_t xt在目标分布 π \pi π中的密度值则接受转移结果,否则以一定的概率决定是转移还是停留不动。具体算法如下:
    在这里插入图片描述

    抽样完成之后,根据获得的状态集合进行求积分。首先将得到的状态集合按照固定的间隔进行统计,统计出现在每个段里面的状态的个数并记录下来。如图所示
    在这里插入图片描述

    不妨设目标函数为 π ( x ) = x \pi(x)=x π(x)=x,经过Metropolis Hasting算法将状态集合根分成 m m m段,每段的中点为 x i ,   i = 1 , 2 , ⋯   , m x_i,~i=1,2,\cdots,m xi, i=1,2,,m,并设每段中出现状态的数目占比(即对出现的次数求概率密度)为 n 1 ^ , n 2 ^ , ⋯   , n m ^ \hat{n_1},\hat{n_2},\cdots,\hat{n_m} n1^,n2^,,nm^,并且满足
    ∑ i = 1 m n i ^ = 1 \sum\limits_{i=1}^{m}\hat{n_i}=1 i=1mni^=1
    显然归一化之后的理想状态分布与目标函数只相差整数倍 k k k,当总试验次数 N → ∞ N\to\infty N时,有
    n i ^ → 1 k π ( x i ) ,   i = 1 , 2 , ⋯   , m \hat{n_i}\to \frac{1}{k}\pi(x_i),~i=1,2,\cdots,m ni^k1π(xi), i=1,2,,m
    当区间划分得足够细的时候,可以使用矩形法求得目标函数的积分,如
    I ≈ ∑ i = 1 m π ( x i ) × 1 − 0 m ≈ ∑ i = 1 m k n i ^ m = k m ∑ i = 1 m n i ^ = k m I \approx\sum\limits_{i=1}^{m}\pi(x_i)\times \frac{1-0}{m} \approx\sum\limits_{i=1}^{m}\frac{k\hat{n_i}}{m} =\frac{k}{m}\sum\limits_{i=1}^{m}\hat{n_i} =\frac{k}{m} Ii=1mπ(xi)×m10i=1mmkni^=mki=1mni^=mk
    而对于 k k k,则在每一段的目标函数值与状态归一化值的比例都近似等于 k k k,因此对每一段的比值求平均得到 k k k从而减小误差
    k ≈ 1 m ( ∑ i = 1 m π ( x i ) x i ^ ) k\approx \frac{1}{m}\left(\sum\limits_{i=1}^m \frac{\pi(x_i)}{\hat{x_i}}\right) km1(i=1mxi^π(xi))
    从而得到最终的积分值为
    I ≈ 1 − 0 m 1 m ( ∑ i = 1 m π ( x i ) x i ^ ) I\approx\frac{1-0}{m}\frac{1}{m}\left(\sum\limits_{i=1}^m \frac{\pi(x_i)}{\hat{x_i}}\right) Im10m1(i=1mxi^π(xi))

    算法过程如下:
    在这里插入图片描述

    clear, clc, clf, tic
    mu = 2; sigma = 3;      % 用于正态函数的模拟
    f1 = @(x) sqrt(1-x.^2);
    f2 = @(x) sin(x) ./ x;
    f3 = @(x) exp(x);
    f4 = @(x) 0.3 * exp(-0.2*x.^2) + 0.7 * exp(-0.2*(x - 10).^2);
    f5 = @(x) 1 / (sigma * sqrt(2 * pi)) * exp(-(x - mu).^2/(2 * sigma^2));
    func = f5;
    uniform_sample = @(a, b) a + rand() * (b - a);
    num_sample = 1000000;   % 总共需要步的步数(个状态)
    num_skip = 10000;       % 经过该步数之后才算做有效数据
    
    X = zeros(1, num_sample + num_skip);% 初始状态设置为0
    for i = 2:(num_sample + num_skip)   % 需要num_sample步+num_skip步
        xnow = X(i-1);                  
        xnext = uniform_sample(0, 1);   % 随机采样的结果,采用(0,1)上的均匀采样
        r = min(1, func(xnext)/func(xnow)); % 用于与接收
        u = rand();
        if (u <= r)         % 接收新采样得到的数据作为下一个状态值
            X(i) = xnext;
        else                % 拒绝,并保持当前值
            X(i) = xnow;
        end
    end
    plot(1:num_sample, X(num_skip + (1:num_sample)));
    % mean(X(num_skip +(1 :num_sample)));
    % std(X(num_skip +(1 :num_sample)));
    
    % 将区间分为num_seg个区段,统计落到每个区段上值的个数(histcounts)
    num_seg = 50;         
    [counts, interval] = histcounts(X(num_skip + (1:num_sample)), num_seg);
    % 每个区段的中点值
    points = (interval(1:end - 1) + interval(2:end)) / 2;
    figure(1);clf;
    bar(points, counts/num_sample);     % 将每个区段的数量绘制出来
    
    x = linspace(0, 1, num_seg); y = func(x);
    hold on; plot(x, func(x) / sum(func(x)));   % 理论的分布
    % 计算模拟积分值与真实积分值并对比
    rand_calc = (num_sample ./ counts) * func(points)' / num_seg^2;  
    real_calc = integral(func, 0, 1);
    delta1 = abs(rand_calc - real_calc);
    fprintf("rand_calc = %.16f\n", rand_calc);
    fprintf("real_calc = %.16f\n", real_calc);
    fprintf("积分误差 = %.16f\n", delta1);
    toc
    
    % 随机模拟出的分布函数与真实分布函数的比较
    F1(1) = 0; F2(1) = 0;   % 初始化分布函数的值
    for i = 2:num_seg
        F1(i) = F1(i-1) + counts(i) / num_sample;
        F2(i) = F2(i-1) + y(i) / sum(y);
    end
    figure(2); clf; 
    plot(x, [F1', F2']);    % 绘制两个分布函数
    delta2 = max(F1-F2);    % 随机模拟准确度的度量方法之一
    fprintf("分布误差 = %.16f\n", delta2);
    
    求积分方法结果误差方差
    随机投点法1.71819374000000050.00064312970754270.0000002829013013
    期望积分法1.71829371384874260.00037367254833370.0000000688076089
    重要抽样法1.71830526399081230.00013322921994150.0000000079561180
    控制变量法1.71828224545014960.00004846954189920.0000000015568030
    对偶变量法1.71828924457666890.00004864687091960.0000000013180232
    分层抽样法1.71828182899932760.00000004278151560.0000000000000012
    MH算法1.71794939748356270.0003324309754824

    可见,在这几种方法中,对于求解 h ( x ) = e x h(x)=e^x h(x)=ex ( 0 , 1 ) (0,1) (0,1)上的定积分,当实验次数为 1000000 1000000 1000000次时,分层抽样法的效率是最高的,误差及其方差都是最小的。当然,也可以尝试使用不同的重点抽样函数以减小方差,使用分层抽样法和控制变量法或者对偶变量法结合,重点抽样法和MH算法结合等等。

    Gibbs抽样

    最后再讨论一下Gibbs抽样算法,因为此算法一般用于二维或者更高维分布的模拟,所以不在上面一维积分处列出,但是Gibbs算法理论上也可以用于求一维积分,不过这样的效率就会非常低。

    一般的MCMC抽样每一步先尝试移动,然后根据新状态是否看尽目标分布来决定是接受还是拒绝该状态的值,因此会出现多次尝试仍然未移动的情况,这样会降低抽样效率。而Gibbs抽样则使用条件分布的抽样来代替这种全概率式的抽样,对于多维Gibbs抽样,其基本思路如下
    在这里插入图片描述

    现有条件概率分布为两个正态分布,它们分别服从 N ( 5 , 1 ) ,   N ( − 1 , 4 ) N(5,1),~N(-1,4) N(5,1), N(1,4),相关系数为 ρ \rho ρ,根据Gibbs算法进行抽样,最终得到模拟出来的边缘分布,联合分布以及真实分布如图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    现在考虑将相关系数设置成 0 0 0,则两个边缘分布是相互独立的。根据Gibbs算法可以产生服从一维正态分布的状态集合,而根据此状态集合可以使用和前面Metropolis Hasting求积分时同样的算法,从而求得正态分布的积分。经MATLAB验证,当试验次数为 100000 100000 100000次时,模拟一次计算得到 0.993198818520657 0.993198818520657 0.993198818520657(理论值为 1 1 1)的积分值,可见效率显然比不上其他算法。

    代码如下:

    clear,clc,clf
    
    pyx=@(x,m1,m2,s1,s2,rho) normrnd(m2+rho*s2/s1*(x-m1),sqrt((1-rho^2)*s2^2));
    pxy=@(y,m1,m2,s1,s2,rho) normrnd(m1+rho*s1/s2*(y-m2),sqrt((1-rho^2)*s1^2));
    bixy=@(x,y,m1,m2,s1,s2,rho) 1/(2*pi*s1*s2*sqrt(1-rho^2)).*exp(-1/(2*(1-rho^2)).*((x-m1).*(x-m1)/s1^2-2*rho*(x-m1).*(y-m2)/s1/s2+(y-m2).*(y-m2)/s2^2));
    
    N=10000;
    
    m1=5;
    m2=-1;
    s1=1;
    s2=2;
    rho=0;
    mu=[m1, m2];
    Sigma=[s1^2,rho*s1*s2;rho*s1*s2,s2^2];	% 协方差矩阵
    x_res=zeros(1,N);	% 初始化
    y_res=zeros(1,N);
    z_res=zeros(1,N);
    
    y=m2;				% 初始值
    for i=1:N
        x=pxy(y,m1,m2,s1,s2,rho);
        y=pyx(x,m1,m2,s1,s2,rho);
        z=mvnpdf([x,y],mu,Sigma);			% 根据采得数据计算联合分布值
        x_res(i)=x;
        y_res(i)=y;
        z_res(i)=z;
    end
    
    num_bins=100;		% 将状态集合分成多少段进行统计
    
    func=@(x) 1/sqrt(2*pi)/s1*exp(-(x-m1).^2/2/s1^2);
    [x_counts,x_interval]=histcounts(x_res,num_bins);	% 统计每一段状态出现次数
    x_points = (x_interval(1:end - 1) + x_interval(2:end)) / 2;
    tmp=find(x_counts~=0);		% 有些状态出现次数为0,避免其出现在分母上
    rand_calc = (N ./ x_counts(tmp)) * func(x_points(tmp))' / length(tmp)...
        * (x_interval(2)-x_interval(1))
    
    figure(1); clf; bar(x_points, x_counts/N);
    % histogram(x_res,num_bins,'normalization','pdf');	% 绘制概率密度
    % histogram(y_res,num_bins,'normalization','pdf');
    
    figure(2); clf; scatter3(x_res,y_res,z_res)	% 绘制联合分布图
    
    figure(3); clf; p(m1,m2,s1,s2,rho,0,10,-10,20);	% 真实分布
    
    function p(m1,m2,s1,s2,rho,xmin,a,ymin,b )%真实分布
    bixy=@(x,y,m1,m2,s1,s2,rho) 1/(2*pi*s1*s2*sqrt(1-rho^2)).*exp(-1/(2*(1-rho^2)).*((x-m1).*(x-m1)/s1^2-2*rho*(x-m1).*(y-m2)/s1/s2+(y-m2).*(y-m2)/s2^2));
    x=xmin:0.1:xmin+a;
    y=ymin:0.1:ymin+b;
    [X,Y]=meshgrid(x,y); % 产生网格数据并处理
    p = bixy(X, Y, m1, m2, s1, s2, rho);
    figure(3); clf; mesh(X,Y,p)
    end
    

    参考文献

    • 李东风. 统计计算[M]. 高等教育出版社, 2017.
    • 洪志敏,白如玉,闫在在,陈君洋.二重积分的蒙特卡罗数值算法[J].数学的实践与认识,2015,45(20):266-271.
    • MCMC(四)Gibbs采样
    展开全文
  • lecture 11:内生性与工具变量法

    千次阅读 2021-04-30 12:38:00
    内生性的解决方法: 1 工具变量法 2 自然实验法 3 处理效应模型 4 Heckman 模型 5 引入固定效应 6 广义矩估计 7 断点回归 8 倾向得分匹配模型 更新 对文章的一些修正及补充。如果确定有内生性问题,打算用IV法。...

    内生性问题

    1. “内生性”名称的由来

    现在人们说某个模型有内生性问题(endogeneity issue),是指模型中的一个或多个解释变量与误差项存在相关关系。

    显然,这个解释和内生性这个名字有点不搭。其实内生性问题字面含义是指模型中的解释变量有内生性(endogeneity)。

    在一个模型中,有些变量的值是在模型内部决定的,是内生的(endogenous);有些变量的值是被模型外界决定的,是外生的(exogenous)。在一般模型中,被解释变量应该是内生的,解释变量应该是外生的,解释变量的取值是不能被我们的模型所决定的。内生性问题字面意思指的是解释变量不是完全外生了,有了内生性了。

    此种内生性问题的一个常见症状就是解释变量和误差项存在相关关系。但不知从什么时候起,人们开始把一切“解释变量和误差项存在相关关系”的情况都叫做内生性问题了,也不管它是什么原因导致的。(关于这一点,可以参考Dougherty《introduction to econometrics》第十章和Wooldridge《Introductory Econometrics》第三章)

    所以就这么叫吧,没什么好纠结的了。

    1. 存在内生性问题的后果

    内生性会破坏参数估计的“一致性”。

    参数估计的“一致性”就是指当样本量很大时,用样本估计出的参数会无限趋近于总体的真实参数。当我们用样本估计出的参数没有了一致性,那它也就没什么参考价值了。

    1. 内生性问题的产生原因

    主要有以下几种,当然也不完全,我用简单的单方程线性模型举例:

    1)测量误差(measurement error)

    测量误差指的是模型使用的解释变量的数值和真实数据有误差。

    2)选择偏差

    3)遗漏解释变量(explanatory variable omitted)

    现实问题总是复杂的,一般情况下,谁也没办法找到所有能影响被解释变量的变量,遗漏解释变量几乎是不可避免的。

    4)互为因果(simultaneity)

    被解释变量能够反过来影响解释变量的情况被称为互为因果,有时也被称为反向因果(reverse causality)。

    在这里插入图片描述4. 内生性问题的解决方法

    内生性的解决方法有很多,IV、Heckman两步法、matching类、DID…从IV到2SLS, 到GMM,到系统GMM,应用范围越来越宽。但我有一个忠诚的建议,就是在选择方法之前梳理一下自己的处理逻辑,弄清楚到底内生性问题是由什么引起的。计量经济学的迷人(或者说迷我)之处就在于故事的完整性、逻辑的严密性,如果机械地套用方法,文章就失去了灵魂。

    内生性的解决方法:

    1 工具变量法
    2 自然实验法
    3 处理效应模型
    4 Heckman 模型
    5 引入固定效应
    6 广义矩估计
    7 断点回归
    8 倾向得分匹配模型

    更新

    对文章的一些修正及补充。如果确定有内生性问题,打算用IV法。一般来说,经济学top期刊对IV要求较高,要完全外生的IV。2020年Economic Journal一篇研究古代科举对现代人力资本影响的文章用一个地区到最近的竹林和松林分布地带的河流距离作为科举考试制度的成功程度。更经典的还有Acemoglu 2001的例子。这是完全外生的,很难想到。对于一些管理学文章,非完全外生的IV也是可行的,例如对于企业层面的研究,用滞后项,行业均值,行业除自身外的均值作为IV都是常用的办法。如果IV的个数与内生解释变量个数一致,则需要从理论上说明该IV的外生性和相关性,其中相关性可以通过2SLS第一阶段的F值或者相关系数做个大概判断。如果IV个数大于内生解释变量个数,则要用Hansen J test检验其外生性。

    对于控制变量是否需要外生,控制变量可以内生。

    总之,在同方差或者恰好识别情况下,2SLS与GMM等价,没有必要使用GMM。但是同方差很少见,多数都是异方差。文章里所说的2SLS指的是GMM,不过因为我个人把用于解决内生性的GMM叫做2SLS,把sys-GMM和diff-GMM叫做GMM。所以在异方差时,我说的2SLS指的是GMM。2SLS和GMM的命令高度相似。如果恰好识别,就用2SLS。

    工具变量和2SLS之间的关系:
    其实两者的本质都是一样的,IV可以视为2SLS的一个特例:当内生变量个数与工具变量个数相等时,称之为IV法;而当工具变量个数大于内生变量个数时,称为2SLS。

    参考文献:
    IV2SLS-python使用

    内生性问题及其产生原因

    内生性问题:起因,类型和解决办法

    工具变量相关性与外生性

    08 - Instrumental Variables

    内生性问题刍议:

    为什么学者都逮着“内生性问题”不放?

    作为一个学术后辈,我个人认为学术交流和研究具有复杂性和开放性,没有一个学术问题探讨是自我封闭的,尤其是社会科学中因果关系的分析,需要不断的努力探索和发展。

    大家都知道,社会科学领域研究中的“因果关系”分析,在实证研究范畴中经常会遇到所谓的“内生性问题”。众所周知,内生性问题的产生,是有多重因素影响引起的,从而产生了不同类型的处理方案,比如工具变量法、Heckman二阶段法、安慰剂分析法、倾向得分匹配法等一系列五花八门的分析方法,而且这类内生性问题处理方法也在进一步完善和发展中,这也是为什么近些年来又有很多统计方法不断出现,如DID方法、断点回归分析法等。当然,这些方法的使用都要各自安好应用环境和条件,需要区别对待和运用。

    其中,工具变量法是最为重要的一种内生性处理方法,也是大家常用且易懂的方法。但是,在运用该方法的时候,我们经常会遇到一个非常重要的问题:如何去寻找一个合适且有效的工具变量呢?的确,这是个学术难题,它难处不仅仅在于我们个人能力的有限性,而且还在于客观世界的复杂性带来的学术偏好,以致影响学术审稿的客观性。

    众所周知的是,在社会科学领域,进行实证研究难以避开所考察因素之间的双向因果,即内生性问题。对此,在实际研究操作过程中,工具变量法(instrumental variable method)依然是解决内生性问题的最为有效方法之一,而且相比较而言,对基于调查数据的定量分析,工具变量方法具有独特优势,已构成解决内生性问题的常见方法(陈强,2013;陈云松,2012; Krueger,1991)。但是,如何寻找可靠合适的工具变量,增加了解决内生性问题的难度。

    从因果关系的分析来看,社会科学中因果关系的分析经常被因果关系中的“反向因果”所困扰,这是为什么呢?因为社会科学中很多社会经济现象的发生都是多重因素交织在一起的影响结果,以我们目前的个人主观臆断和能力,显然是我们无法剥离谁是因、谁是果?或许,这也是为什么很多学术同仁在中国知网搜索文献时,经常会遇到似“鸳鸯”类的文献,如:一篇文章主题是“A对B的影响研究”,一篇文章主题是“B对A的影响研究”。那么,我们就产生一种疑虑:到底是谁影响谁呢?相信这类奇怪的选题,你也遇到过不少好!

    也正因为有这种风气或计量潮流的影响,现在学界有关工具变量的探讨,尤其是在学术论文审稿中或者学术会议中,很多审稿人或点评人似乎存在明显的偏好性和误导性,喜欢“乱点谱”,逮着“内生性问题”不放,比如:1、一提意见就指点他人文章因果关系中的内生性问题。2、随意批评别人工具变量的合理性但又不提啥建设性意见。3、过于重视因果关系中内生性问题,由此拒稿。4、追求吸引眼球的工具变量。……

    需要说明的是,在学术规范上,本人是不反对去重视实证分析中的内生性问题,反而为了应对审稿人的要求,每次做了不少内生性问题的处理方案。但是,在这个内生性问题的讨论方面,每个学术人都应该有个节制的程度,针对内生性问题分析的问题上,我们应该做到“有理有据、合情合理”,而不是随意就来“内生性问题”,我们主要从以下几个方面去把关内生性问题:内生性问题你处理重视与否、计量方法的准确性、工具变量度量的合理性、工具变量的外生性,以及内生性问题理论分析阐述等方面。

    实际上,由于经济活动的影响因素繁多复杂,以及经济数据的噪音影响,去寻找一个完全独立于因变量、且仅对自变量产生影响的外生变量是一项艰巨的任务,找到好的工具变量是非常之艰难(陈云松,2012),但康奈尔大学知名计量社会学家Morgan(2002)认为,由于社会科学问题的影响因素较为复杂,只要能和其他方法进行比较和相互补充,就可以更大胆、更冒险地发现和使用工具变量,哪怕工具变量具有明显瑕疵的外生性或无法完全消除质疑,也是值得提倡的。

    为此,我们尽心去努力的是:根据所考察的主题来为寻找合适的工具变量把关,不仅从理论分析上认为所选取的工具变量的适宜性,而且还应通过统计分析来检验工具变量的外生性(即弱工具变量检验),以尽可能地寻找一个恰当的工具变量,运用工具变量法来减轻内生性问题对结论所产生的影响偏误。

    所以,在学术探讨上,大家要保持一种开放的思维来分析学术问题,内生性问题是一个极为复杂的统计问题和社会现象,更需要我们的深思熟虑去看待问题的解决方案和态度。而且,内生性问题的解决,也并不会因为你寻找了一个工具变量、进行了一个内生性处理命令,就可以得到很好或者完全解决的。

    当然,也许你认为我的观点不对,但你想想:你认为你文章的内生性问题,真的处理好了吗?你找的工具变量真的完全“外生”吗?不好意思,也许主效应他们两者之间根本没有什么关系……

    举例:电子资料在群里。
    https://economics.mit.edu/faculty/acemoglu/ Daron Acemoglu
    https://www.sohu.com/a/159507737_728084
    https://blog.csdn.net/weixin_27787297/article/details/113965735
    Sargent数量经济:回归分析与Python
    二阶段最小二乘

    作为示例,我们会重复Acemoglu,Johnson and Robinson(2001,AER)的经典文章的结果

    该论文可以从这里下载(https://economics.mit.edu/files/4123)

    (1)在这篇文章中,作者强调制度对经济发展对的影响

    (2)主要的贡献是利用殖民死亡率作为制度差异的外生变化的来源

    (3)这种变化决定制度是否引起了更多的经济增长,而不是别的方式

    展开全文
  • 针对双足机器人被动步行中... 进一步地,利用OGY 对机器人支撑腿处的变量施加微扰,把机器人混沌状态稳定在自身的不动点上,实现了对混沌步态的快速控制。仿真实验和机器人行走实验结果表明了所提控制方法的有效性。
  • 通过对多种控制算法进行仿真研究后,利用控制变量法以及定性分析相结合对以下五种控制算法进行性能比较:常规PID控制算法、Smith控制算法、带死区修正后的Smith控制算法、模糊控制算法和模糊PID控制控制算法,我们...
  • 利用子集构造DFA 一、实验目的二、实验要求、内容三、实验设备四、实验原理(或程序框图)及步骤五、程序源代码六、实验数据、结果分析七、存在的问题与体会附录 一、实验目的 掌握将非确定有限自动机确定化的方法...

    一、实验目的

    掌握将非确定有限自动机确定化的方法和过程。

    二、实验要求、内容

    1.输入一个NFA,输出一个接受同一正规集的DFA;
    2.采用任意语言,实现该算法;
    3编制测试程序;
    4.调试程序。

    三、实验设备

    计算机、Windows 7操作系统、Eclipse Luna程序集成环境、JDK 12。

    四、实验原理(或程序框图)及步骤

    对给定的NFA状态,程序在利用子集构造法将其转换为对应的DFA状态时,首先需要获取NFA状态转换图中的对应信息,包括字母表、状态集以及初始状态。为方便程序处理,可将每个状态实例化为一个类State,其类图如图4-1所示,函数详细定义及功能见附录。状态转换图中,某状态经过字母表中某字符串可达某状态集,构成了当前状态、某个字符串和某个状态集三者的映射关系,则可对特定状态用字符串与状态集间的映射关系准确描述三者的关系,即构建键值对<字符串,可达状态集>(变量path)描述特定状态。此外,程序中还涉及某状态处理时的标记与否(变量flag)和状态名(变量name)。

    图4-1 状态类类图
    如果将初始状态规定为状态输入的状态0(记为S0),则只需前二者。获取相应信息后,首先对S0构造其ε闭包集合A作为DFA的开始状态。随后对字母表中的每一个字母,依次在原NFA状态集中对其做A中包含所有状态的闭包运算,获得A在经过该字母的转换后得到的下一状态集。对获取的每一个状态,如果其不在状态集合中,则将其作为一个新状态。对于获取的每一个新状态,重复在A状态上执行的动作,直到没有任何状态产生为止。在执行闭包运算时,对集合中的每一个状态,将该状态能经过当前字符串转换得到的所有状态加入当前集合的闭包集中。主程序流程图和闭包算法流程图流程图如图4-2所示。
    图4-2 主程序流程图(左)和闭包算法流程图(右)

    五、程序源代码

    计算DFA的while循环如下所示,此时已经完成了所有状态信息的输入、初始化并且计算出了DFA的首个状态加入transState列表中,此列表即为最终所求的DFA的状态集,其中每个状态的状态名均此状态包含的NFA状态集。tState被用于标记当前状态,是自定义的状态类State的实例,其中包含状态姓名、是否被标记以及此状态和所有字母上的转换关系,其类图见图4-1,详细定义见附录。flag为其是否被标记的布尔类型变量,transTable中包含所有找到的构造DFA的状态集合(原NFA的子集),在循环中通过path标记当前找到的可以构造DFA的状态。包含文件处理和输入输出的完整主程序以及类State的定义见附录。

    while (!flag) 
    {
    	tState.markFlag(true);
    	List<String> state = new LinkedList<String>();
    	for (int i = 0; i < transTable.size(); i++) 
    	{
    		state = transTable.get(i);
    		if (state.toString().equals(tState.name()))		break;
    	}
    	// 找到当前状态的原始转换列表
    	String[] path = new String[state.size()];
    	k = 0;	
    	for (String m : state)	path[k++] = m;
    	// 取到当前状态
    	for (String s : sigma) 
    	{
    		// 按字母表填转换表
    		if (s.equals("$"))		break;
    		String[] move = new String[state.size()];
    		move = move(states, totalStates, path, s);
    		// 第一次move
    		// 如果这个状态得到这个字符串,执行e-closure运算
    		if (!move[0].equals("#"))		
    			 move = move(states, totalStates, move, "$");
    		stateList = new LinkedList<>();
    		for (String q : move)	stateList.add(q);
    		tState.put(s, stateList);// 将得到的状态填入对应的状态
    		System.out.println(tState);
    		if (!transTable.contains(stateList) && !stateList.contains("#")) 
    		{
    			transTable.add(stateList);//扩充状态转换列表
    			State sa = new State(stateList.toString(), sigma,	totalSignals);
    			sa.put("$", "#");
    			transState.add(sa);	
    		}
    		// 找下一个状态,改变对应flag的值用以控制循环
    		for (State s : transState) 
    		{
    			if (!s.isFlag()) 
    			{
    				tState = s;flag = tState.isFlag();
    				break;
    			} else	flag = true;	
    		}
    	}	
    }
    

    计算闭包的函数如下所示,相关描述见注释。

    	/**算法描述:(1)将T中所有状态压入栈stack; 将closure (T) 初始化为T; 
    	 * (2)若stack不空 将栈顶元素t弹出栈; 
    	 * (3)对每个从t到u有一条标记为 ε的边的状态u:
     如果 u 不在ε-closure ( T ) do 将u 添加到closure ( T );
    	 * (4)将u压入栈stack中 closure算法
    	 * @param states 状态列表
    	 * @param totalStates,所有状态数
    	 * @param location,待转换状态在原始状态列表中的位置
    	 * @param str,将要执行对该字符串的闭包运算
    	 * @return 转换后的字符串集合 */
    public static String[] closure(State[] states, int totalStates,			int location, String str)
    {
    	LinkedList<String> list = (LinkedList<String>) states[location].get(str);
    	LinkedList<String> current = new LinkedList<String>();
    	Stack<String> stack = new Stack<>();
    	if (list.contains("#"))
    	{
    		if (str.equals("$")) 	current.add(states[location].name());
    	}  
    	else 
    	{
    		stack.push(states[location].name());
    		for (String i : list)	stack.push(i);
    		while (!stack.empty()) 
    		{
    			String temp = stack.pop();
    			for (int n = 0; n < totalStates; n++) 
    			{
    				if (stack.empty())		break;
    				if ((states[n].name()).equals(temp)) 
    				for (String j : (LinkedList<String>) states[n].get(str)) 
    				if (!(j.equals("#")) && !(stack.contains(j))&& !stack.empty())	stack.push(j);	
    			}
    				if (!current.contains(temp))	current.add(temp);	
    		}
    	}
    	if (current.isEmpty())	current.add("#");
    	String[] res = new String[current.size()];
    	int t = 0; for (String i : current) 	res[t++] = i;
    	return res;	
    }
    

    六、实验数据、结果分析

    实验中用到的NFA状态转换图如图6-1所示,为方便处理,将空串同样视为待处理的字符串,在程序中用“$”表示。

    图6-1 NFA状态转换图

    在处理时首先构建其状态转换表如表6-1所示。
    表6-1 NFA状态转换表
    状态\字符串letterdigit$
    01##
    1##2
    2##3 9
    3##4 6
    45##
    5##8
    6#7#
    7##8
    8##3 9
    9###

    将其按照图4-1中的流程处理后得到的新状态转换图如图6-2所示。

    图6-2 转换后的DFA状态转换图

    新状态转换表如表6-2所示。
    表6-2 转换后的NFA状态转换表
    状态\字符串letterdigit$
    AB##
    BCD#
    CCD#
    DCD#

    其中,新状态转换表中状态分别为原状态转换表中某些状态的集合,如表6-3所示。

    表6-3 NFA和DFA中状态的对应
    新状态原状态集合
    A{0}
    B{2,9,3,6,4,1,0}
    C{8,9,3,6,4,5,2,1,0}
    D{8,9,3,6,4,7}

    根程序处理包结构如图6-3所示,其中Lex.java和State.java分别为处理程序和状态类的源程序文件,Test.java是进行函数功能测试的测试文件。data.txt和result.txt分别为原始数据文件和处理后的结果文件。

    图6-3 程序包结构目录

    根据表6-1构造程序原始数据文件文件data.txt,其内容如图6-2所示。其中,原始数据文件每行的内容依次为:包含空串的字符串总数、字母表中的所有字母、包含的状态总数以及每个状态在依次转换对应字母转换后的状态,相邻状态用空格分隔,没有该字符的转换用#标记。

    图6-4 原始数据记录文件

    程序处理结果依次如图6-3到图6-5所示,其中,图6-3是程序读取原始数据文件后,将原始数据显示在控制台上的结果。其内容与表6-1相同,分别为状态名,该状态的是否被标记,以及该状态经过每一字符转换后的对应状态。图6-4是程序处理原始数据的过程,将每次构造出的新状态包含的原始状态集合作为新状态的名字,在第一列显示,其余列与图6-4中内容顺序形同。图6-5表示经过转换后构成的新状态转换表。将该表内容存入结果集文件result.txt中,其文本内容如图6-6所示。

    图6-5 获取原始状态转换表并显示
    图6-6 状态转换过程
    图6-7 转换后新的状态转换表
    图6-8 存储结果的result.txt文件内容

    七、存在的问题与体会

    1.程序中NFA的原始状态表需要在程序开始之前手动写入文件,不能自动从状态转换图读取原始状态。且原始数据和结果都存在txt文件中,可读性较差。
    2.使用Java语言编写程序,代码的执行效率较低。尤其是因为没有对指针的操作,在代码中使用了大量链表和数组的转换,且使用较多的增强的for循环,占用了较多的额外空间和迭代器空间。这些转换也使用了大量额外空间,此外由于程序中使用String类型数据作为基础数据,在新建数据和使用临时变量制造了较多的碎片空间。如果使用含指针的语言如C++,可以有效避免上述问题,代码的时空性能和执行效率会更高。
    3.通过实验加深了对于子集构造法的理解,特别是对于NFA和DFA中各种数据间的映射关系以及NFA和DFA的映射关系有了进一步理解。通过相应映射关系,从NFA到DFA的转换会更容易。

    附录

    完整程序源代码如下所示,其中各部分功能均在代码中以注释形式(“/**/”包裹的文字段或者“//”开头的文字)标明。

    package lex;
    /**@author 1706020228张峰瑞2020/4/22*/
    import java.io.*;
    import java.util.*;
    /**用于将文件data.txt中的NFA状态转换表,转化成对应DFA的状态转化表,写入文件result.txt*/
    public class Lex {
    	public static void main(String[] args) throws FileNotFoundException {
    		/** -----------------初始化开始--------------- **/
    		List<String> stateList;//原始状态列表
    		List<State> transState;//转换后的状态列表
    		List<List<String>> transTable;//得到的新的状态集合
    		File file = new File("src/lex/data.txt");
    		Scanner reader = new Scanner(file);
    		int totalSignals = Integer.parseInt(reader.nextLine());// 获取字符总数(包含空串)
    		String[] sigma = new String[totalSignals];
    		String newLine = reader.nextLine();//获取所有字符串(空串以$表示),以空格划分
    		sigma = newLine.split(" ");
    		int totalStates = Integer.parseInt(reader.nextLine());// 获取状态总数
    		State[] states = new State[totalStates];
    		for (int i = 0; i < totalStates; i++) 
    			states[i] = new State("" + i, sigma, totalSignals);
    		for (int i = 0; i < totalStates; i++) {
    			// 获取每个状态在对应字母转换后的状态表,没有状态用#
    			for (int j = 0; j < totalSignals; j++) {
    				newLine = reader.nextLine();
    				String[] lines = newLine.split(" ");
    				stateList = new LinkedList<>();
    				for (int m = 0; m < lines.length; m++)	
    					stateList.add(lines[m]);
    				states[i].put(sigma[j], stateList);
    			}
    		}
    		System.out.println("\n原始状态转换表为:");
    		int k = states[0].toString().length();
    		while (k >= 15) {
    			System.out.print("_");	k--;
    		}
    		System.out.println();//控制输出
    		for (int i = 0; i < totalStates; i++) 
    			System.out.println(states[i]);
    		k = states[0].toString().length();
    		while (k >= 15) {
    			System.out.print("_");	k--;
    		}
    		System.out.println();
    		reader.close();
    		/** -----------------初始化结束-------------- **/
    		transState = new LinkedList<State>();
    		stateList = new LinkedList<String>();//
    		transTable = new LinkedList<List<String>>();
    		/** -------------------找开始状态T0-------------- **/
    		String[] temp = closure(states, totalStates, 0, "$");
    		for (String m : temp)   stateList.add(m);
    		State tState = new State(stateList.toString(), sigma, totalSignals);
    		tState.put("$", "#");
    		transState.add(tState);
    		transTable.add(stateList);
    		/** ------------------将T0加入状态转换列表-------------- **/
    		System.out.println("\n转换过程:");//输出格式控制
    		k = states[0].toString().length();
    		while (k >= -5) {
    			System.out.print("_");	k--;
    		}
    		boolean flag = tState.isFlag();//循环控制变量
    		/** ----------------------计算DFA--------------------- **/
    		System.out.println();
    		/*此处略去五中代码while片段*/
    		k = states[0].toString().length();
    		while (k >= -5) {
    			System.out.print("_");	k--;
    		}
    		/**----------------状态转换结束,将结果输出------------------**/
    		System.out.println("\n处理结束,新的状态转换表为:");
    		k = transState.get(0).toString().length();
    		while (k >= 15) {
    			System.out.print("_");	k--;
    		}
    		System.out.println();
    		for (int i = 0; i < transState.size(); i++) 
    			System.out.println(transState.get(i));
    		k = transState.get(0).toString().length();
    		while (k >= 15) {
    			System.out.print("_");	k--;
    		}
    		System.out.println();
    		/**------------将转换后的状态列表写入对应的文件result.txt------------**/
    		try {
    			file = new File("result.txt");
    			FileWriter newFile = new FileWriter(file, true);
    			BufferedWriter writer = new BufferedWriter(newFile);
    			for (int i = 0; i < transState.size(); i++) {
    				writer.write(transState.get(i).toString());
    				writer.newLine();
    				writer.flush();
    			}	writer.close();
    		} catch (IOException e) { System.out.println(e);	}
    	}
    /*此处略去五中closure函数*/
    	/**算法描述:实质是对传入集合中所有的元素做对相应字母的闭包运算
    	 * @see closure
    	 * @param states 状态列表
    	 * @param totalStates,所有状态数
    	 * @param tSet,待转换状态列表
    	 * @param str,将要执行对该字符串的闭包运算
    	 * @return 当前闭包黄钻换后的字符串集合* */
    	public static String[] move(State[] states, int totalStates, String[] tSet,
    			String str) {
    		LinkedList<String> list = new LinkedList<String>();
    		String[] temp = new String[tSet.length];
    		for (int i = 0; i < tSet.length; i++) {
    			if (tSet[i].equals("#"))				break;
    			int location = (Integer.parseInt(tSet[i]));
    			temp = closure(states, totalStates, location, str);
    			for (String m : temp) 
    				if (!list.contains(m))	list.add(m);
    		}
    		if (list.size() == 1 && list.contains("#")) {
    			tSet = new String[1];
    			tSet[0] = "#";
    			return tSet;
    		}
    		list.remove("#");
    		int k = 0;
    		if (list.size() != 0) {
    			tSet = new String[list.size()];
    			for (String m : list)
    				tSet[k++] = m;
    		} else {
    			tSet = new String[1];
    			tSet[0] = "#";
    		}
    		return tSet;
    	}
    }
    
    package lex;
    /**@author 1706020228张峰瑞2020/4/22*/
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    /**@param name,状态名称
     * @param paths,从状态到字符串的映射
     * @param flag,该状态是否被标记 * */
    public class State {
    	private String name;
    	private Map<String, List<String>> paths;
    	private boolean flag;
    	/**生成默认状态*/
    	State() {
    		this.setName("-1");
    		this.paths = new HashMap<String, List<String>>();
    		List<String> list = new LinkedList<>();
    		paths.put("a", list);
    		flag = false;
    	}
    	/**生成指定名称,包含特定数目字符串的状态
    	 * @param name,状态名称
    	 * @param sigma,字母表,用于构建映射
    	 * @param n,字母表中的字符串数目	 * */
    	State(String name, String[] sigma, int n) {
    		this.setName(name);
    		this.paths = new HashMap<String, List<String>>();
    		for (int i = 0; i < n; i++) {
    			List<String> list = new LinkedList<>();
    			paths.put(sigma[i], list);
    		}
    		flag = false;
    	}
    	/**@return name,返回当前状态名称* */
    	public String name() {	return name;	}
    	/**@param name,要设定的状态名称*/
    	public void setName(String name) {	this.name = name;	}
    	/**@return 当前状态是否被标记*/
    	public boolean isFlag() {	return flag;	}
    	/**@param flag,标记当前状态为指定状态*/
    	public void markFlag(boolean flag) {	this.flag = flag;	}
    	/**设置当前状态中指定字母和状态集合的映射
    	 * @param signal,指定的字母
    	 * @param list,要设置的对应映射的集合*/
    	void put(String signal, List<String> list) {	paths.put(signal, list);	}
    	/**设置当前状态中状态和指定字符串之间的映射
    	 * @param signal,被映射的指定字符串
    	 * @param string,映射后的字符串 * */
    	public void put(String signal, String string) {
    		List<String> list = new LinkedList<>();
    		list.add(string);
    		paths.put(signal, list);
    	}
    	/**获取当前状态的映射关系
    	 * @param key键值对中的键
    	 * @return 获取后的键值对 * */
    	Object get(String key) {	return paths.get(key);	}
    	/**判断两个状态是否相等
    	 * @param obj,要判断是否相等的状态
    	 * @return 是否相等 * */
    	@Override
    	public boolean equals(Object obj) {
    		return this.name.equals(((State) obj).name)
    				&& this.paths.equals(((State) obj).paths);
    	}
    	/**输出格式控制函数
    	 * @return 当前状态信息的字符串*/
    	@Override
    	public String toString() {
    		String path = paths.toString().replaceAll("=", "->");
    		path = path.replace(',', ' ');
    		path = path.replace('{', ' ');
    		path = path.replace('}', ' ');
    		path = path.replace('[', '{');
    		path = path.replaceAll("]", "} ");
    		String[] paths = path.toString().split("}");
    		int m = 0;
    		path = "";
    		for (int i = 0; i < paths.length; i++) {
    			if (i != paths.length - 1) 	paths[i] += "}";
    			paths[i] = "|" + paths[i];
    			m = 15 - paths[i].length();
    			if (m > 3) 
    				for (int k = 0; k < m; k++) 
    					paths[i] = paths[i] + " ";
    			else {
    				m = 40 - paths[i].length();
    				if (m > 0) 
    					for (int k = 0; k < m; k++) 
    						paths[i] = paths[i] + " ";
    			}
    			path = path + paths[i];
    		}
    		int j = name.length();
    		String name = this.name.toString();
    		if (j == 1) 			j = 10 - j;
    		else			j = 30 - j;
    		for (int k = 0; k < j; k++)		name = name + " ";
    		name = name.replace('[', '{');
    		name = name.replaceAll("]", "} ");
    		return "|" + name + "|" + flag + "       " + path;
    	}
    }
    
    展开全文
  • 异步电机矢量控制MATLAB仿真实验

    千次阅读 2021-04-23 16:59:22
    异步电机矢量控制MATLAB仿真实验Tag内容描述:1、异步电机矢量控制 VC 系统仿真实验 电气与信息工程学院 2019年6月 教学内容 1 矢量控制原理分析2 仿真实验模型的搭建3 仿真实验结果的分析 1 矢量控制原理分析 第一...
  • 《自动控制原理实验五-利用MATLAB绘制系统根轨迹》由会员分享,可在线阅读,更多相关《自动控制原理实验五-利用MATLAB绘制系统根轨迹(6页珍藏版)》请在人人文库网上搜索。1、实验利用MATLAB绘制系统根轨迹一、...
  • 基于得到的理想配光曲线,透镜采用分离变量法设计自由曲面,将光源和目标面进行网格划分,形成能量对映关系。同时对曲面构造误差进行控制,再利用反馈优化法对透镜进行优化,使透镜的配光曲线趋于理想。仿真实验表明...
  • 研究了一种新的隧道电缆巡检轨道机器人智能越障控制方法,探究了巡检机器人的工作环境,引用D-H参数建立巡检机器人越障模型,分析每个机器人的关节变量,得到机器人末端执行器的位置和姿态,使用求近似解值求出...
  • 实验为一个两输入,一输出的模糊控制实验 自定义使用场景:根据当前时间对灯光的需要以及当前物理上已经有的灯光(如自然光)的场景,来自动调节家庭使用吊灯的光亮 输入1:当前时间对对光的需要程度 输入2:...
  • 文章目录1 理论介绍1.1 Instrumental variable解释1.2 因果推断中:内生性的一个有意思的例子1.2 与代理变量(proxy variable)的对比1.3 连玉君老师的简易解读2 econML实现 DeepIV 同系列可参考: 因果推断笔记...
  • (一)项目任务ü 任务1:用定时方式控制LEDn 子任务1.1 两种定期器的认识n 子任务1.2 掌握定期器的定时原理和计算方法n 子任务1.3 采用定时器方法实现点亮LED功能ü 任务2:采用按键扫描控制LEDn 子任务2.1 C语言--...
  • 智能控制基础实验2:根轨迹分析

    千次阅读 2020-12-30 18:45:14
    一、实验目的 1.学习和掌握利用 MATLAB 绘制根轨迹图的方法 2.学习和掌握利用系统根轨迹图分析系统的性能 二、实验原理 1.根轨迹分析的 MATLAB 实现 (1)rlocus 函数 该函数的使用方法如下: rlocus(sys) 绘制单...
  • 测试方法-正交实验法/场景

    千次阅读 2020-04-08 22:37:56
    正交实验法如何查找正交表正交实验法例子2.场景法例1--微信红包例2--淘宝网买东西 1.正交实验法 正交试验设计(Orthogonal experimental design), 是从大量的试验点中挑选出适量的、有代表性的点,应用依据迦罗卡瓦...
  • 在双变量控制原理的基础上,对传统余弦交截进行线性化近似改造,以直线方程代替三角方程,不仅可以改善输出波形的对称度,减少输出电压的谐波,而且能够在线计算晶闸管触发时刻,同时能够实时连续改变参考电压的幅值和...
  • 实验过程中应用了"控制变量法"来设置实验条件,通过反复实验得出褐煤在超临界水中气化的影响因素与规律特征.结果表明,褐煤在超临界状态下比在亚临界状态下更能转化成可燃气体,且在超临界状态下,使用催化剂KOH可使褐...
  • 中國石油大学-单片机-实验三_LED指示灯循环控制中国石油大学(北京)实验报告实验课程: 单片机原理及应用实验名称: 实验三—— LED指示灯循环控制总学时: 48 教师: 林 立 成绩:实验日期: 2012 年 10 月 23 日...
  • 通过完成预测分析的语法分析程序,了解预测分析和递归子程序的区别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业...
  • 控制的方法是比较简单的六步换相利用电机内部的霍尔传感器,通过参考电机厂家给出的二二导通换相表,生成方波来控制电机。第一次实验为了简化需求,只考虑开环、定速、正转的情况: 开环:不考虑速度反馈,直接...
  • 正交实验法设计测试用例

    万次阅读 多人点赞 2018-11-13 15:31:10
    2 正交实验法3 利用正交实验设计测试用例的步骤:3.1 提取功能说明,构造因子--状态表3.2 加权筛选,生成因素分析表3.3 利用正交表构造测试数据集4 正交表的构成5 正交表的正交性5.1 整齐可比性5.2 均衡分散性二 用...
  • 在做随机实验或自然实验时,实验的效果往往需要一段时间才能显现出来,而我们关心的恰恰是被解释变量试验前后的变化。为此,考虑两期面板数据: (注:面板数据是一个m*n的数据矩阵,记录的是n个时间节点上m个对象的...
  • 键盘接口和七段数码管的控制实验

    千次阅读 2019-07-16 12:14:13
    一、实验目的 1. 学习4X4键盘的与CPU的接口原理 2. 掌握键盘芯片HD7279的使用,及8位数码管的显示方法; 二、实验内容 1. 通过4X4按键完成在数码管上的各种显示功能,以及LCD上显示。 三、实验设备 EL-ARM-830...
  • 在第一个离线计算阶段,利用对称多项式和Groebner基的理论将多元非线性方程等效地转换为一组单变量线性方程,然后将其存储到目标微控制器(MCU)中并在以下位置进行求解:线; 在第二个在线计算阶段,对线性方程组...
  • 一些变量筛选方法——1、综述

    万次阅读 多人点赞 2018-05-11 00:32:32
    由于《An Introduction to Statistical Learning with R》课程论文需要我们进行对一些变量筛选方法与降维的方法进行综述,所以这里将分几个部分,将学到的一些变量筛选方法写在博客之中。写成一篇长博客看得比较吃力...
  • 利用李亚普诺夫方法分析变量反馈控制混沌的机理,得到使混沌系统稳定的状态反馈控制律。仿真实验表明,适当选择反馈强度可将系统的混沌态引导到不动点,验证了理论的正确性。变量反馈可以很好地消除动力学系统的...
  • 编译原理 实验三 LR(1)分析 Java

    千次阅读 2020-02-15 15:51:49
    构造 LR(1)分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解 LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。 2.实验内容 对下列文法,用 LR(1)分析对任意输入...
  • 编译原理实验二 LL(1)分析

    千次阅读 2019-11-27 21:43:02
    实验二 LL(1)分析 通过完成预测分析的语法分析程序,了解预测分析和递归子程序的区 别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方 ,训练学生掌握开发应用程序的基本方法。...
  • 针对多变量、非线性和强耦合性的倒立摆系统,采用分析力学...研究结果表明,利用分析动力学方 来建立倒立摆系统的数学模型可以大大降低建模的复杂性,仿真研究和实际物理系统的实验结 果证明了所提出控制方法的有效性。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,631
精华内容 8,252
关键字:

利用控制变量法的实验

友情链接: ParkV9.03.zip