分割の個数を出す
Ewens sampling formulaについて数日前に書いた。それは、ある正の整数を正の整数の和で表す表し方と関係していることも書いた。
このように整数を整数の和で表すことを整数分割という。それについては、こちらを参照。
その整数分割のパターン数をJavaでべたに数え上げるのが以下のソース。
使い方は
int n=5; Ewens.Ewens_All(n);
出力は
はじめに分割、次に和の構成 0 0 0 0 1 0 0 0 0 5 1 0 0 1 0 0 0 0 1 4 0 1 1 0 0 0 0 0 2 3 2 0 1 0 0 0 0 1 1 3 1 2 0 0 0 0 0 1 2 2 3 1 0 0 0 0 1 1 1 2 5 0 0 0 0 1 1 1 1 1 count 7
public static void Ewens_All(int n){
/*
* n-1本の区切りをn+1箇所に入れる。
* すべての区切りが同じ箇所に入っても可。
* ただし、前半の線分は後半の線分より長くてはいけない
*/
int[] kugiri=new int[n-1];
boolean loop=true;
int count=0;
System.out.println("はじめに分割、次に和の構成");
while(loop){
boolean tmpbool=true;
for(int i=0;i<kugiri.length;i++){
if(kugiri[i]<n){
tmpbool=false;
i=kugiri.length;
}
}
if(tmpbool){
loop=false;
}
int[] lengthVector=lengthFromKugiri(kugiri,n);
boolean lengthOK=CheckLength(lengthVector);
if(lengthOK){
count++;
int[] partition=fromLengthToPartition(lengthVector);
for(int i=0;i<partition.length;i++){
System.out.print(partition[i]+"\t");
}
System.out.print("\t");
for(int i=0;i<lengthVector.length;i++){
System.out.print(lengthVector[i]+"\t");
}
System.out.println();
}
kugiri=update(kugiri,n);
}
System.out.println("count\t"+count);
}
public static int[] fromLengthToPartition(int[] a){
int[] ret = new int[a.length];
for(int i=0;i<a.length;i++){
if(a[i]>0){
ret[a[i]-1]++;
}
}
return ret;
}
public static int[] lengthFromKugiri(int[] kugiri,int max){
int[] ret = new int[kugiri.length+1];
ret[0]=kugiri[0];
for(int i=0;i<kugiri.length-1;i++){
ret[i+1]=kugiri[i+1]-kugiri[i];
}
ret[ret.length-1]=max-kugiri[kugiri.length-1];
return ret;
}
/*
public static int[] updateEwens(int[] a,int max){
boolean ok=false;
while(!ok){
a=update(a,max);
ok=CheckSerial(a,max);
}
return a;
}
*/
public static boolean Maximum(int[] a,int max){
boolean ret=true;
for(int i=0;i<a.length;i++){
if(a[i]!=max){
ret=false;
return ret;
}
}
return ret;
}
public static boolean CheckLength(int[] a){
boolean ret=true;
for(int i=0;i<a.length-1;i++){
if(a[i+1]<a[i]){
ret=false;
return ret;
}
}
return ret;
}
/*
public static boolean CheckSerial(int[] a,int max){
boolean ret=true;
int length=a[0];
for(int i=0;i<a.length;i++){
if(i==a.length-1){
if(max-a[i]<length){
ret=false;
return ret;
}
}else{
if(a[i+1]-a[i]<length){
}
length=a[i+1]-a[i];
}
}
return ret;
}
*/
public static int[] update(int[] a,int max){
a[0]++;
for(int i=0;i<a.length-1;i++){
//System.out.println("i\t"+i+"\tret[i]\t"+a[i]);
if(a[i]>a[i+1]){
a[i+1]++;
if(i==0){
a[i]=0;
}else{
a[i]=a[i-1];
}
}
}
return a;
}
public static double term1(double x, int j,double a){
double ret=0;
for(int i=0;i<j;i++){
ret+=Math.log(x+a*i);
}
ret = Math.exp(ret);
return ret;
}
public static double factor(int n){
double ret =0;
for(int i=1;i<=n;i++){
ret += Math.log(i);
}
ret = Math.exp(ret);
return ret;
}
}