// Constructor
// _m must be a value in [0,1]
public VP_Forest(MetricDB _DB, double _m=0,double _tau=0)
{
this.DB=_DB;
this.Remaining=new List<int>(this.DB.Count);
this.Persist=new bool[this.DB.Count];
this.Tau=double.MaxValue;
int[] perm;
if (_m!=0)
this.m=_m;
if (_tau!=0)
{
BuildingWithTau=true;
this.wanted_Tau=2*_tau;
}
this.Forest=new List<VPF_Tree>();
int N=this.DB.Count;
for (int i=0;i<N;i++)
this.Remaining.Add(i);
do
{
int a,w,center;
double[] Distances=new double[N];
this.Persist=new bool[N];
this.Forest.Add ( new VPF_Tree() );
perm=new int[N];
for (int i=0;i<N;i++) {perm[i]=i;}
//Console.WriteLine("Building tree number: {0}",Forest.Count);
//Console.WriteLine("Remaining: {0}",Remaining.Count);
if (Divide_Interval(N,out a,out w,out center,out Distances,perm))
{
this.Forest[this.Forest.Count-1].Root=new VPF_Node(center);
BuildTree((VPF_Node)this.Forest[this.Forest.Count-1].Root,Distances,perm,a,w);
}
else // The root is a leaf
{
leafs+=N;
VPF_Leaf L=new VPF_Leaf(N);
L.center=center;
for (int i=0;i<N;i++)
L.SetValues(this.Remaining[perm[i]],Distances[i],i);
this.Forest[this.Forest.Count-1].Root=L;
Console.WriteLine("Tau very big. Remaining:{0}",Remaining.Count);
}
RemoveMarkedOnes();
N=Remaining.Count;
}while(Remaining.Count>0);
this.Tau/=2;
Console.WriteLine("Total trees: {0}",this.Forest.Count);
Console.WriteLine("Tau: {0}",this.Tau);
Console.WriteLine("Leafs:{0}",leafs);
}