若要计算「在第 n 抽时,才抽到所有要抽的六星角色」之机率分布 (n 为正整数,範围从 1 到无限大),这问题本身不容易直接处理,因此我决定先将此机率分布拆解成数个较容易计算出来的机率分布,再将其经由某些运算,叠加成欲求的机率分布
关于「在第 n 抽时,才抽到所有要抽的六星角色」之机率分布,事实上可以被看做 ∑「抽到第 i 个六星时,才抽到所有要抽的六星角色」的机率 *「抽第 n 抽时,才抽到第 i 个六星」之机率分布,其中 i 的範围是从 1 到无限大,n 的範围则随着 i 的不同而有不同,当 i = 1 时,n 的範围是从 1 到 99,当 i = 2 时,n 的範围是从 1 到 198,以此类推 (n 的範围之所以有上界,是因为方舟的卡池有六星保底机制)。根据上面的式子,若能求出 i 在各值时「抽到第 i 个六星时,才抽到所有要抽的六星角色」的机率与「抽第 n 抽时,才抽到第 i 个六星」的机率分布,即可计算出「在第 n 抽时,才抽到所有要抽的六星角色」之机率分布
然而在实际计算时,由于 i 的範围没有上界,因此需要计算出无限多个机率分布,才有办法计算出欲求的机率分布,但这是不可能的,所以需要设定一个 i 的计算上限来 计算量,使得计算变成可行。好消息是当 i 大于一定值后,其所生成之机率分布的面积将趋近于 0,也就是说在实际计算时,可以将 i 大于一定值的状况省略
接下来就是实作的部分了,这边以双 up 卡池两个 up 六星都要抽到的情况当作範例,下面是 MATLAB 程式码
close all; clear; clc;
p= #91;0.25 0.25 #93;; %目标机率占六星总机率的比例
n=length(p);
up_bound=1000; %作图时的上限
m=30; %六星的最大抽取数
k=1:m;
y0=zeros(1,m);
for i=1:n
x=sum(Combination(p,i),2);
y0=y0+(-1)^(i+1)*sum(x.*(1-x).^(k-1),1);
endfor
figure(1)
plot(k,y0, #039;ob #039;)
%print -dpng #039;01.png #039;
y1= #91; #93;;
for i=1:99
if i lt;=50
p=0.02*0.98^(i-1);
y1= #91;y1 p #93;;
else
p=0.02*(i-49);
for j=1:i-51
p=p*(0.98-0.02*j);
endfor
p=p*0.98^50;
y1= #91;y1 p #93;;
endif
endfor
figure(2)
plot(1:99,y1, #039;- #039;)
hold on
%print -dpng #039;02-1.png #039;
Y0=zeros(1,99*m);
Y0(1:99)=y1*y0(1);
y2=y1;
for i=2:m
M=y1 #039;*y2;
y2=zeros(1,98*i+1);
for j=1:99
y2(j:j+98*(i-1))=y2(j:j+98*(i-1))+M(j,:);
endfor
Y0(i:99*i)=Y0(i:99*i)+y2*y0(i);
figure(2)
plot(i:99*i,y2, #039;- #039;)
endfor
%print -dpng #039;02-2.png #039;
figure(3)
plot(1:min(up_bound,99*m),Y0(1:min(up_bound,99*m)), #039;-b #039;)
hold on
%print -dpng #039;03-1.png #039;
Y1=zeros(1,99*m);
for i=1:99*m
Y1(i)=sum(Y0(1:i));
endfor
figure(4)
plot(1:min(up_bound,99*m),Y1(1:min(up_bound,99*m)), #039;-b #039;)
hold on
%print -dpng #039;04-1.png #039;
然后是程式的执行结果
「抽到第 i 个六星时,才抽到所有要抽的六星角色」的机率分布
「抽第 n 抽时,才抽到第 i 个六星」的机率分布,最左边的图形是 i = 1 时的机率分布,向右依次是 i = 2、3、4、... 时的机率分布
「在第 n 抽时,才抽到所有要抽的六星角色」的机率分布
下面是在各种状况下,各机率分布的一些统计量
我这边需要说明一下,由于程式计算出的机率分布与实际的机率分布间会有些微差异,因此这些计算出的统计量也会与实际的统计量有些微差异
我还另外做了一个抽卡模拟器,生成了一千万笔随机样本,用这些样本去估计机率分布函数在各点的值,下面是部分程式码
y0= #91; #93;;
l=length(p2);
for i=1:n
C=0; %总抽卡数
G=0; %连续未抽到六星的次数
cop=zeros(1,l); %是否抽到指定的六星
while min(cop)==0
C=C+1;
G=G+1;
r=rand(1);
if G lt;=50 r lt;p1
for j=1:l
if r gt;=p1*sum(p2(1:j-1)) r lt;p1*sum(p2(1:j))
cop(j)=1;
break
endif
endfor
G=0;
elseif G gt;50 r lt;p1+0.02*(G-50)
for j=1:l
if r gt;=(p1+0.02*(G-50))*sum(p2(1:j-1)) r lt;(p1+0.02*(G-50))*sum(p2(1:j))
cop(j)=1;
break
endif
endfor
G=0;
endif
endwhile
y0= #91;y0 C #93;;
endfor
以及样本估计出的机率分布