/**
 * File Name: cUnivers.cpp
 * @author: Betti Oesterholz
 * @date 12.01.2005
 * @mail webmaster@bernd-oesterholz.name
 *
 * System: C++
 * 
 * 
 * Copyright (C) 2004  Betti Oesterholz
 * 
 * This class represents a basic univers.
 * Copyright (C) @c GPL3 2008  Betti Oesterholz
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * 
 * This file contains the program for a univers.
 * Ther are 2 basictypes in this univers points and conections(positiv and
 * negativ) betwean them. Points are changing Points of the univers.
 * Every tick(minimum time) every point creates a new zero distance. (nothing is
 * produced, conservation of distances) A zero distance is a positiv (+1) and a
 * negativ (-1) distance. The 2 signed distances are random conected to a
 * neigbor of the point or a new point. (each possibility has same probability)
 * Neigbor points of a point are points that are conected with distances to the point.
 * Two not eqaul signed distances betwean to points destroy each other.(add to zero)
 * If one part (signed distance) of a zero distanc is destroyed, but not the
 * other, the other distance one end ist displaced from the point of his
 * creation to the point that was conected with the creation point by the
 * destroyed distance. (the distance betwean the end and the point becomes zero)
 * 
 * translation diagram:(for tree points)
 * 	pi point i=1..3
 * 	+ positiv distance
 * 	- negativ distance
 * 	no distance
 * 	befor -> after
 * 	p2 is the point wher the zero distance is created, p1 is the point choosen
 * 	for the positiv part(distance) to go to and p3 is the point choosen
 * 	for the negativ part(distance) to go to 
 * 
 * 	1) p1+p2+p3 -> p3+p1+p2
 * 	2) p1+p2-p3 -> p1++p2--p3
 * 	3) p1-p2+p3 -> p1 p2 p3
 * 	4) p1-p2-p3 -> p3-p1-p2
 * 	5) p1+p2 p3 -> p1++p2-p3
 * 	6) p1 p2+p3 -> p1+p3 p2
 * 	7) p1-p2 p3 -> p1-p3 p2
 * 	8) p1 p2-p3 -> p1+p2--p3
 * 	9) p1 p2 p3 -> p1+p2-p3
 */
/*
History: 
22.12.2007  Oesterholz  eof() check in readUnivers() 
18.10.2008  Oesterholz  new function for outputting the statistic for the univers parts
*/

#include "cstring"
#include "cUnivers.h"


#define FEATURE_FASTER_PART_SPLIT 1


/**
 * standart constructor, constructs a new univers with standart values
 * standart statistic file is: "./statistics.txt"
 */
cUnivers::cUnivers():iTime(0),pDistance(0),nDistance(0),
	outComent(true),cutAfter(0),outUniv(0),outStat(0),bTime(0),
	maxTime(100),maxPoints(0),checkMaxPoints(1),statFileName(0),statFile(NULL),
	bStatParameterChanged(true),uFolder(0),bUName(0),bUniversParameterChanged(true),
	cutNearDimension(3.0),cutMaxClassRatio(1.0),appendUnivers(false),
	parameterFile(0),outRealTime(0),rTimeFileName(0),rTimeFile(0),bRTimeParameterChanged(true),
	outCutStatistic(0),cutFileName(0),cutFile(NULL),bCutParameterChanged(true),
	lOutUniversPartStatistic(0),szUniversPartStatisticFileName(NULL),
	universPartStatisticFile(NULL),bUniversPartStatisticParameterChanged(true),
	transPosible(1),tmpValue(0),bEndEvaluation(false)
{
	cout<<endl<<UNIVERS_TYP<<" "<<UNIVERS_VERSION<<endl<<endl;
	rg1=new cRandomMersenne(time(0)); // make instance of random number generator0
	//new univers
	cPoint* bang=new cPoint();//the littel bang point
	bang->name=1;
	last=1;
	univers.push_back(bang);
	actualPoint=univers.begin();
	setStatisticFileName( "./statistics.txt" );
	setUniversFolderName("./universes/");//standart folder for the universes
	setUniversFileBaseName("univers");//standart file base name for the universes
	setRTimeFileName("./rTime.txt");
	setCutFileName("./cut.txt");
	setUniversPartStatisticFileName("./universParts.txt");
	for (unsigned long i=0;i<10;i++){
		trans[i]=0;
	}
}

/**
 * parameter constructor, constructs a new univers with standart values
 * beware this constructor copies just the char* pointers, but not the string in them!
 * @param outC output comments
 * @param cutA cut after steps
 * @param mTm number of maxTime
 * @param maxP maxPoints the univers should have
 * @param cMP check maxPoints condition every  (checkMaxPoints) ticks
 * @param stat name of the statistic file
 * @param cutDim the dimension to prefer by cut (cutNearDimension)
 * @param cutRatio the Ratio till wich to generate the max class by cut (cutMaxClassRatio)
 * @param appU append univers if appU is true
 * standart statistic file is: "./statistics.txt"
 */
cUnivers::cUnivers(bool outC, unsigned int cutA, unsigned long mTm, unsigned long maxP, unsigned long cMP, const char* stat, const char* uFol, const char* bUN, double cutDim, double cutRatio, bool appU):
	iTime(0),pDistance(0),nDistance(0),
	outComent(outC),cutAfter(cutA),outUniv(0),outStat(0),bTime(0),
	maxTime(mTm),maxPoints(maxP),checkMaxPoints(cMP),statFileName(0),statFile(NULL),
	bStatParameterChanged(true),uFolder(0),bUName(0),bUniversParameterChanged(true),cutNearDimension(cutDim),
	cutMaxClassRatio(cutRatio),appendUnivers(appU),parameterFile(0),
	outRealTime(0),rTimeFileName(0),rTimeFile(0),bRTimeParameterChanged(true),outCutStatistic(0),
	cutFileName(0),cutFile(NULL),bCutParameterChanged(true),
	lOutUniversPartStatistic(0),szUniversPartStatisticFileName(NULL),
	universPartStatisticFile(NULL),bUniversPartStatisticParameterChanged(true),
	transPosible(1),tmpValue(0),bEndEvaluation(false)
{
	cout<<endl<<UNIVERS_TYP<<" "<<UNIVERS_VERSION<<endl<<endl;
	rg1=new cRandomMersenne(time(0)); // make instance of random number generator0
	//new univers
	cPoint* bang=new cPoint();//the littel bang point
	bang->name=1;
	last=1;
	univers.push_back(bang);
	actualPoint=univers.begin();
	setStatisticFileName(stat);
	setUniversFolderName(uFol);
	setUniversFileBaseName(bUN);
	setRTimeFileName("./rTime.txt");
	setCutFileName("./cut.txt");
	setUniversPartStatisticFileName("./universParts.txt");
	for (unsigned long i=0;i<10;i++){
		trans[i]=0;
	}
}


/** 
 * copy constructor, constructs a copy of the given univers;
 * statistic output cycles will be set to 0 and append univers will be false
 */
cUnivers::cUnivers(cUnivers &univ):iTime(univ.iTime),pDistance(univ.pDistance),nDistance(univ.nDistance),last(univ.last),
	outComent(univ.outComent),cutAfter(univ.cutAfter),outUniv(univ.outUniv),outStat(0),bTime(univ.bTime),
	maxTime(univ.maxTime),maxPoints(univ.maxPoints),checkMaxPoints(univ.checkMaxPoints),
	statFileName(NULL),statFile(NULL),bStatParameterChanged(true),uFolder(NULL),
	bUName(0),bUniversParameterChanged(true),cutNearDimension(univ.cutNearDimension),
	cutMaxClassRatio(univ.cutMaxClassRatio),appendUnivers(false),parameterFile(0),
	outRealTime(0),rTimeFileName(NULL),rTimeFile(NULL),bRTimeParameterChanged(true),
	outCutStatistic(0),cutFileName(NULL),cutFile(NULL),bCutParameterChanged(true),
	lOutUniversPartStatistic(0),szUniversPartStatisticFileName(NULL),
	universPartStatisticFile(NULL),bUniversPartStatisticParameterChanged(true),
	tmpValue(0),bEndEvaluation(false)
{
	cout<<endl<<UNIVERS_TYP<<" "<<UNIVERS_VERSION<<endl<<endl;
	rg1=new cRandomMersenne( time(0) ); // make instance of random number generator
	univers=copyUniversStructur(univ.univers);
	actualPoint=univers.begin();
	setStatisticFileName( univ.getUniversFolderName() );
	setUniversFolderName( univ.getUniversFolderName() );
	setUniversFileBaseName( univ.getUniversFileBaseName() );
	setRTimeFileName( univ.getRTimeFileName() );
	setCutFileName( univ.getCutFileName() );
	setUniversPartStatisticFileName( univ.getUniversPartStatisticFileName() );
	
	transPosible=univ.transPosible;
	for ( unsigned long i=0 ; i<10 ; i++ ){
		trans[i]=univ.trans[i];
	}
}


/**
 * destructor
 * destructs the univers and closes all open files
 */
cUnivers::~cUnivers(){

	//delete all points
	for ( list<cPoint*>::iterator itr=univers.begin() ; itr!=univers.end() ; itr++ ){
		delete (*itr);
	}
	univers.clear();
	if (statFile!=NULL){
		statFile->close();
		delete statFile;
	}
	delete [] statFileName;
	delete [] uFolder;
	delete [] bUName;
	
	if ( rTimeFile!=NULL ){
		rTimeFile->close();
		delete rTimeFile;
	}
	delete [] rTimeFileName;
	
	if (cutFile!=NULL){
		cutFile->close();
		delete cutFile;
	}
	delete [] cutFileName;
	
	if (universPartStatisticFile!=NULL){
		universPartStatisticFile->close();
		delete universPartStatisticFile;
	}
	delete [] szUniversPartStatisticFileName;
}

/**
 * returns a copy of the given univers
 * @param univ a univers to copy
 * @return a copy of the given univers
 */
list<cPoint*> &cUnivers::copyUniversStructur(list<cPoint*> &univ) const{

	list<cPoint*> *univCopy=new list<cPoint*>;
	cPoint* poi;
	univ.sort(&cPoint::lower);
	for (list<cPoint*>::iterator itr=univ.begin();itr!=univ.end();itr++){
		poi=new cPoint;
		poi->name=(*itr)->name;
		univCopy->push_back(poi);
	}
	list<cPoint*>::iterator itr1,itr2;
	list<cPoint*>::iterator itrC=univCopy->begin();
	for (list<cPoint*>::iterator itr=univ.begin();(itr!=univ.end())&&(itrC!=univCopy->end());itr++,itrC++){
	
		(*itr)->pPoint.sort(&cPoint::lower);
		itr1=univCopy->begin();
		for (itr2=(*itr)->pPoint.begin();itr2!=(*itr)->pPoint.end();itr2++){
		
			if(((*itr)->name)>=(*itr2)->name){
				break;
			}
			while (itr1!=univCopy->end()){
			
				if ((*itr1)->name==(*itr2)->name) {
					break;
				}
				itr1++;
			}
			if(itr1!=univers.end()){//create positiv distance
				(*itrC)->pPoint.push_back(*itr1);
				(*itr1)->pPoint.push_back(*itrC);
			}
		}
		(*itr)->nPoint.sort(&cPoint::lower);
		itr1=univCopy->begin();
		for ( itr2=(*itr)->nPoint.begin() ; itr2!=(*itr)->nPoint.end() ; itr2++ ){
			if(((*itr)->name)>=(*itr2)->name){
				break;
			}
			while (itr1!=univers.end()){
				if ((*itr1)->name==(*itr2)->name){
					break;
				}
				itr1++;
			}
			if(itr1!=univers.end()){//create positiv distance
				(*itrC)->nPoint.push_back(*itr1);
				(*itr1)->nPoint.push_back(*itrC);
			}
		}
	}
	return *univCopy;
}

//get methods

/** 
 * returns a pointer to the univers
 * @return the pointer to the univers structur
 */
list<cPoint*>* cUnivers::getUniversStructur() {
	return &univers;
}

/**
 * returns the univers data;
 * dosn't copies the univers, you get the data of the original univers 
 * @return the data of the univers in a TUPart, with the pointer to the univers structur
 */
TUPart cUnivers::getUnivers(){

	TUPart tmpU;
	tmpU.partUnivers=univers;
	tmpU.pDistances=pDistance;//positiv Distances
	tmpU.nDistances=nDistance;//negativ Distance
	tmpU.last=last;
	return tmpU;
}

/**
 * @return the number of the points of the univers
 */
unsigned long cUnivers::getNumberOfPoints() const {
	return univers.size();
}

/**
 * returns the internal time (number of ticks till creation) of the univers
 * @return the internal time of the univers
 */
unsigned long cUnivers::getInternalTime() const {
	return iTime;
}

/** 
 * @return the number of the positiv distances of the univers
 */
unsigned long cUnivers::getNumberOfPDistance() const {
	return pDistance;
}

/**
 * @return the number of the negativ Distances of the univers
 */
unsigned long cUnivers::getNumberOfNDistance() const {
	return nDistance;
}

/**
 * returns the number of the different transitions in the last tick(0-9)
 * like in the transition diagram above; array point 0 is the transition sum
 * @return the number of differnt transitions of the last tick
 */
unsigned long* cUnivers::getNumberOfLastTransitions(){
	trans[0]=trans[1]+trans[2]+trans[3]+trans[4]+trans[5]+trans[6]+trans[7]+trans[8]+trans[9];
	return trans;
}

/**
 * @return the last name number a new point in the univers was given
 */
unsigned long cUnivers::getLastName() const {
	return last;
}

/**
 * returns if comments are shown
 * @return true if comments are shown, else false
 */
bool cUnivers::getCommentsActiv() const {
	return outComent;
}

/**
 * returns the after wich number of ticks a cut is performed,
 * if 0 is returned, it wouldn't be cut
 * @return after wich number of ticks a cut is performed
 */
unsigned long cUnivers::getCutCycle() const {
	return cutAfter;
}

/**
 * returns after wich number of ticks a the univers is outputed,
 * if 0 is returned the univers isn't outputed
 * @return after wich number of ticks the univers is outputed
 */
unsigned long cUnivers::getOutUniversCycle() const {
	return outUniv;
}

/**
 * returns the after wich number of ticks a the statistics is outputed,
 * if 0 is returned no statistic will be outputed
 * @return after wich number of ticks the statistics is outputed
 */
unsigned long cUnivers::getOutStatisticCycle() const {
	return outStat;
}

/**
 * @return the time base (=beginning time) of the univers (the time the univers begins is user defined)
 */
long cUnivers::getTimeBase() const {
	return bTime;
}

/**
 * returns the maximal time, at this time the evaluation of the univers 
 * will be stoped;
 * if the maximal time is 0 evaluation isn't stop because of the time
 * @return the maximal time
 */
unsigned long cUnivers::getMaxNumberOfTime() const {
	return maxTime;
}

/**
 * returns how many point the univers can have bevor it's evaluetion is stoped; 
 * if the number is 0 the univers wouldn't be stoped because it has to much points
 * @return the maximal number of point
 */
unsigned long cUnivers::getMaxNumberOfPoints() const {
	return maxPoints;
}

/**
 * returns every wich number of ticks the max points condition should be
 * checked; if 0 the condition will be never check
 * @return the number of ticks the max points condition is checked
 */
unsigned long cUnivers::getCheckMaxPoints() const {
	return checkMaxPoints;
}

/**
 * @return the statistic file name
 */
char* cUnivers::getStatisticFileName() const {
	return statFileName;
}

/**
 * @return the univers folder name, wher the actual universes files are writen to
 */
char* cUnivers::getUniversFolderName() const {
	return uFolder;
}

/**
 * @return the univers file base name, with wich the saved universes files begin with
 */
char* cUnivers::getUniversFileBaseName() const {
	return bUName;
}

/**
 * @return the cutNearDimension value 
 * (the value the dimension of the remaining part after a cut operation 
 * should be near to )
 */
double cUnivers::getCutNearDimension() const {
	return cutNearDimension;
}

/**
 * @return the cutMaxClassRatio value
 */
double cUnivers::getCutMaxClassRatio() const {
	return cutMaxClassRatio;
}

/**
 * @return the number of ticks betwean writing the realtime statistic 
 *   to a file, if the number is 0 no statistic is writen
 */
unsigned long cUnivers::getOutRealTime() const {return outRealTime;}

/**
 * @return the name of the real time statistic file
 */
char* cUnivers::getRTimeFileName() const {
	return rTimeFileName;
}

/**
 * @return the number of ticks betwean writing the cut statistic 
 *   to a file, if the number is 0 no statistic is writen
 */
unsigned long cUnivers::getOutCutStatistic() const {
	return outCutStatistic;
}

/**
 * @return the name of the cut statistic file
 */
char* cUnivers::getCutFileName() const {
	return cutFileName;
}


//set methods:

/** adds the given number to the number of positiv distances of the univers
 * if the old number of positiv distances plus the given value is lower 0 the
 * number of positiv distances is set to 0
 * @param  pDDist number( positiv or negativ) to add to the positiv distances
 * @return the changed number of postitiv distances of the univers
 */
unsigned long cUnivers::addNumberOfPDistance( const long pDDist ){
	if (long(pDistance)>=(-pDDist)){
		pDistance+=pDDist;
	}else{
		pDistance=0;
	}
	return pDistance;
}

/**
 * adds the given number to the number of negativ distances of the univers;
 * if the old number of negativ distances plus the given value is lower 0 
 * the number of negativ distances is set to 0
 * @param nDDist number(positiv or negativ) to add to the negativ distances
 * @return the changed negativ distances of the univers
 */
unsigned long  cUnivers::addNumberOfNDistance( const long nDDist ){
	if ( long(nDistance) >= -nDDist ){
		nDistance+=nDDist;
	}else{
		nDistance=0;
	}
	return pDistance;
}

/**
 * adds the given number to the number of posible transitions of the univers;
 * if the old number of transitions posible plus the given value is 
 * lower 0 the number of transitions posible is set to 0
 * @param lTransitions number(positiv or negativ) to add to the transitions posible
 * @return the changed transitions posible of the univers
 */
unsigned long  cUnivers::addTransPosible(const long lTransitions){
	if (long(transPosible)>=-lTransitions){
		transPosible+=lTransitions;
	}else{
		transPosible=0;
	}
	return transPosible;
}

/**
 * evalues the posible transitions for this univers;
 * the transPosible value of this univers is changed
 * @return the number of posible transitions
 */
unsigned long cUnivers::evalueTransPosible(){
	transPosible=0;
	for ( list<cPoint*>::iterator itr=univers.begin() ; itr!=univers.end() ; itr++ ){
		transPosible+=(*itr)->getTransPosible();
	}
	return transPosible;
}

/**
 * set if comments are shown
 * @param bCommentActive a value if the comments should be shown
 */
void cUnivers::setCommentsActiv( const bool bCommentActive ) {
	outComent=bCommentActive;
}

/**
 * set in which intervall (every which number of ticks) a cut is 
 * performed, 0 means never cut
 * @param ulCutAfter number of ticks betwean the cut operation
 */
void cUnivers::setCutCycle(const unsigned long ulCutAfter){
	cutAfter=ulCutAfter;
}


/**
 * set in which interval (every which number of ticks) a the statistics 
 * is generated and writen, 0 means never generate the statistic
 * @param ulOutStatistic after wich number of ticks the statistics is outputed
 * @return true if the interval for the statistics is changed to the
 * 	given value, else false
 */
bool cUnivers::setOutStatisticCycle( const unsigned long ulOutStatistic ){

	if ( outStat!=ulOutStatistic ){
		outStat=ulOutStatistic;
		bStatParameterChanged=true;
		return true;
	}
	return false;
}

/**
 * set the time base of the univers (the time the univers begins with
 * is user defined), the first tick of the univers will be at this time
 * @param lBaseTime the time base
 */
void cUnivers::setTimeBase( const long lBaseTime ) {
	bTime=lBaseTime;
}

/**
 * set the maximal time; 
 * if this time is reached the evaluation of the univers will stop;
 * if the maximal time is set to 0 the univers won't stop because of
 * the time
 * @param ulMaxTime the maximal time to set
 */
void cUnivers::setMaxNumberOfTime( const unsigned long ulMaxTime ) {
	maxTime=ulMaxTime;
}

/**
 * set maximal number of points (counted after a tick);
 * if this number is reached the evaluation of the univers will stop;
 * if the maximal number of points is set to 0 the univers won't stop
 * because of the number of points
 * @param ulMaxPoints the maximal number of points to set
 */
void cUnivers::setMaxNumberOfPoints( const unsigned long ulMaxPoints ) {
	maxPoints=ulMaxPoints;
}

/**
 * set in which interval (every which number of ticks) a the maximal
 * number of points condition is checked; 
 * 0 means never checked the condition
 * @param ulCeckMaxPoints after wich number of ticks the maximal number 
 *		of points condition
 */
void cUnivers::setCheckMaxPoints( const unsigned long ulCeckMaxPoints ) {
	checkMaxPoints=ulCeckMaxPoints;
}


/**
 * set statistic file name
 * @param  pStatFileName a pointer to the statistic file name
 * @return true if the filename was set, else false
 */
bool cUnivers::setStatisticFileName( const char* pStatFileName){
	if ( !pStatFileName ){
		//if no string is given, don't change
		return false;
	}
	if ( statFileName ){//realy new name
		if ( strcmp(statFileName, pStatFileName)==0 ){
			//if no new statistic file name is given
			return true;
		}
	}
	//else change statistic file name
	bStatParameterChanged=true;
	if ( statFileName ) {
		delete [] statFileName;
	}
	statFileName=new char[ strlen(pStatFileName)+1 ];
	strcpy(statFileName,pStatFileName);//copy string
	
	return true;
}

/**
 * set in which interval (wich number of ticks) a the univers is outputed;
 * if the value is 0 the univers isn't outputed in an interval
 * @see setUniversFolderName
 * @see setUniversFileBaseName
 * @param ulOutputUnivers after wich number of ticks the univers is outputed
 * @return true if the value was changed, else false
 */
bool cUnivers::setOutUniversCycle(const unsigned long outU){
	if (outUniv!=outU){
	
		bUniversParameterChanged=true;
		outUniv=outU;
		return true;
	}
	return false;
}

/**
 * set the univers folder name, wher the files for the universes are
 * writen to
 * @see setOutUniversCycle
 * @see setUniversFileBaseName
 * @param pUniversFolder a pointer to the the univers folder
 * @return true if the value is changed, else false
 */
bool cUnivers::setUniversFolderName( const char* pUniversFolder ){
	if ( !pUniversFolder ){
		//if no string is given, don't change
		return false;
	}
	//check if realy new name
	if ( uFolder ) {
		if ( strcmp(uFolder, pUniversFolder)==0 ){
			return false;
		}
	}
	//else change statistic file name
	bUniversParameterChanged=true;
	if ( uFolder ) {
		delete [] uFolder;
	}
	uFolder=new char[ strlen(pUniversFolder)+1 ];
	strcpy( uFolder, pUniversFolder );//copy string
	return true;
}

/**
 * set the univers file base name, with wich the saved universes begin with
 * @see setOutUniversCycle
 * @see setUniversFolderName
 * @param pUniversFileBaseName the univers base name
 * @return true if the value is changed, else false
 */
bool cUnivers::setUniversFileBaseName( const char* pUniversFileBaseName ){
	if ( !pUniversFileBaseName ){
		//if no string is given, don't change
		return false;
	}
	//check if realy new name
	if ( bUName ) {
		if ( strcmp(bUName, pUniversFileBaseName)==0 ){
			return false;
		}
	}
	//else change statistic file name
	bUniversParameterChanged=true;
	if ( bUName ) {
		delete [] bUName;
	}
	bUName=new char[ strlen(pUniversFileBaseName)+1 ];
	strcpy( bUName, pUniversFileBaseName );//copy string
	return true;
}

/**
 * set the cutNearDimension value (the value the dimension of the 
 * remaining part after a cut operation should be near to )
 * @see getCutNearDimension
 * @see setCutMaxClassRatio
 * @param dCutNearDimension the cutNearDimension value to set
 */
void cUnivers::setCutNearDimension( const double dCutNearDimension ) {
	cutNearDimension=dCutNearDimension;
}

/**
 * set the cutMaxClassRatio value; the size, in ratio to the biggest
 * univers parts, the universparts from which the after the cut
 * remaining universpart is choosen from
 * @see getCutMaxClassRatio
 * @see setCutNearDimension
 * @param dCutMaxClassRatio the cutMaxClassRatio value to set
 */
void cUnivers::setCutMaxClassRatio( const double dCutMaxClassRatio ) {
	cutMaxClassRatio=dCutMaxClassRatio;
}


/**
 * set if the real time statistic should be outputed
 * @see setRTimeFileName
 * @param bRealTime if the real time statistic should be outputed
 * @return true if the value is changed, else false
 */
bool cUnivers::setOutRealTime( bool bRealTime ){
	if ( outRealTime!=bRealTime ){
		bRTimeParameterChanged=true;
		outRealTime=bRealTime;
		return true;
	}
	return false;
}

/**
 * set real time statistic path
 * @see setOutRealTime
 * @param pRealTimePath a pointer to the real time statistic file name
 * @return true if the value is changed, else false
 */
bool cUnivers::setRTimeFileName( const char* pRealTimePath ){
	if ( !pRealTimePath ){
		//if no string is given, don't change
		return false;
	}
	//realy new name?
	if ( rTimeFileName ) {
		if ( strcmp(rTimeFileName, pRealTimePath)==0 ){
			//if no new statistic file name is given -> return false
			return false;
		}
	}
	//else change statistic file name
	bRTimeParameterChanged=true;
	if (rTimeFileName) {
		delete [] rTimeFileName;
	}
	rTimeFileName=new char[ strlen(pRealTimePath)+1 ];
	strcpy( rTimeFileName, pRealTimePath );//copy string
	return true;
}

/** prints the head of the real time statistic to the real time statistic file */
void cUnivers::printRealTimeStatisticHead() const{
	if (rTimeFile!=NULL){
		(*rTimeFile)<<"time; real time; time till last tick; time for tick; time for cut;";
		(*rTimeFile)<<"time for output the univers; time for direct statistic; ";
		(*rTimeFile)<<"time for neibour statistic; time for distance statistic; time for part size statistic;";
		(*rTimeFile)<<"time for parts statistic;"<<endl;
	}
}

/**
 * set in which interval (every which number of ticks) the cut
 * statistic should be outputed;
 * 0 means never output the statistic;
 * the cut statistic interval should be a multiple of the cut interval,
 * because if ther is no cut operation no cut statistic can be generated
 * @see setCutFileName
 * @see getOutCutStatistic
 * @param lOutCutStatistic after wich number of ticks the cut statistic 
 * 	should be outputed
 */
bool cUnivers::setOutCutStatistic( const unsigned long lOutCutStatistic ){
	if ( outCutStatistic!=lOutCutStatistic ){
		bCutParameterChanged=true;
		outCutStatistic=lOutCutStatistic;
		return true;
	}
	return false;
}

/**
 * set cut statistic path
 * @see setOutCutStatistic
 * @see getCutFileName
 * @param pCutStatisticPath a pointer to the cut statistic file name
 * @return true if the value is changed, else false
 */
bool cUnivers::setCutFileName( const char* pCutStatisticPath ){
	if ( !pCutStatisticPath ){
		//if no string is given, don't change
		return false;
	}
	//realy new name?
	if ( cutFileName ) {
		if ( strcmp(cutFileName, pCutStatisticPath)==0 ){
			//if no new statistic file name is given -> return false
			return false;
		}
	}
	//else change statistic file name
	bCutParameterChanged=true;
	if ( cutFileName ) {
		delete [] cutFileName;
	}
	cutFileName=new char[ strlen(pCutStatisticPath)+1 ];
	strcpy( cutFileName, pCutStatisticPath );//copy string
	return true;
}

/**
 * set if the univers parts statistic should be outputed
 * @param universPartStatisticInterval how often the univers part statistic should be outputed (0=never)
 * @return true if the value is changed, else false
 */
bool cUnivers::setOutUniversPartStatistic( const unsigned long universPartStatisticInterval ){
	if (lOutUniversPartStatistic!=universPartStatisticInterval){
	
		bUniversPartStatisticParameterChanged=true;
		lOutUniversPartStatistic=universPartStatisticInterval;
		return true;
	}
	return false;
}

/**
 * set univers parts statistic file name, close the old statistic file, opens the new
 * statistic File and print the statistic head to it, if posibel
 * @param  universPartFilename a pointer to the file name statistic file name
 * @return true if the value is changed, else false
 */
bool cUnivers::setUniversPartStatisticFileName( const char* universPartFilename )
{
	if ( !universPartFilename ){
		//if no string is given, don't change
		return false;
	}
	//realy new name?
	if ( szUniversPartStatisticFileName ){
		if ( strcmp(szUniversPartStatisticFileName, universPartFilename)==0 )
		{//if no new statistic file name is given
			return false;
		}
	}
	//else change statistic file name
	bUniversPartStatisticParameterChanged=true;
	if ( szUniversPartStatisticFileName ){
		delete [] szUniversPartStatisticFileName;
	}
	szUniversPartStatisticFileName=new char[ strlen(universPartFilename)+1 ];
	strcpy(szUniversPartStatisticFileName , universPartFilename );//copy string
	return true;
}


/**
 * prints the head of the parts statistic to the given stream
 * @see setUniversPartStatisticFileName
 * @see getUniversPartStatisticFileName
 * @see setOutUniversPartStatistic
 * @param statisticStream stream wher to write the parts statistic head to
 */
void cUnivers::printUniversPartsStatisticHead( ostream &statisticStream ) const{

	if (statisticStream!=NULL){
		statisticStream<<"time; all points; all positiv distances; all negativ distances; coherent parts;";
		statisticStream<<"data for parts (points, positiv distances, negativ distances); "<<endl;
	}//6 * ';'
}


/**
 * writes the values of the univers to the given output stream, if it exists
 * @see readUnivers
 * @param ostream the outputstream ostream to write the univers to
 * @return if the stream exists true and the actual univers in the stream
 * 	ostream in a readebel form(integer numbers seperated by ",",";" and "."),
 * 	false else
 */
bool cUnivers::printUnivers( ostream &ostream )
{
	if( !ostream ){
		return false;
	}
	univers.sort( &cPoint::lower );
	//convert and output the univers to a output form
	ostream<<(unsigned long)univers.size()<<"."<<endl;
	for ( list<cPoint*>::iterator itr=univers.begin() ; itr!=univers.end() ; itr++){
		ostream<<(**itr);
	}
	return true;
}


/**
 * replaces the actual univers with the univers of the stream, if it exists;
 * for that deletes the old univers and reads the values of the univers from
 * the stream (the values should be of the form of printUnivers uses)
 * @see printUnivers
 * @param istream the input stream to read the univers from
 * @return if the stream exists true and this univers is the univers readed from
 * the stream, else false
 */
bool cUnivers::readUnivers( istream &istream ){
	if (!istream){
		return false;
	}
	//delete old universe
	pDistance=0;//positiv Distances
	nDistance=0;//negativ Distances
	for ( list<cPoint*>::iterator itr=univers.begin() ; itr!=univers.end() ; itr++ ){
		//delete all points
		delete (*itr);
	}
	univers.clear();
	//read Data
	unsigned long size,a;
	unsigned long name;
	char c;
	istream>>size;
	if(outComent){
		cout<<"univers size : "<<size<<endl;
	}
	istream>>c;//"."
	list<TOPoint> lTOPoint;
	for ( unsigned long i=0 ; i<size ; i++ ){
	
		TOPoint tmpPoint;
		istream>>name;
		istream>>c;
		while( !istream.eof() ){
			istream>>c;
			if (c==';'){
				break;
			}
			istream>>a;
			tmpPoint.pPoint.push_back(a);
			pDistance++;
		}
		while( !istream.eof() ){
			istream>>c;
			if (c=='.'){
				break;
			}
			istream>>a;
			tmpPoint.nPoint.push_back(a);
			nDistance++;
		}
		tmpPoint.pPoint.sort();
		tmpPoint.nPoint.sort();//find faster the conected points
		tmpPoint.original=new cPoint;
		tmpPoint.original->name=name;
		univers.push_back( tmpPoint.original );//insert Point in universe
		lTOPoint.push_back( tmpPoint );
		if (name>last){
			last=name;
		}
	}
	univers.sort( &cPoint::lower );//find faster the conected points
	//distances are double counted -> divide with 2
	pDistance = pDistance/2;
	nDistance = nDistance/2;
	//convert Distances
	list<cPoint*>::iterator itr1;
	unsigned long i=0;
	if(outComent){
		cout<<endl;
	}
	//connect the points
	for (list<TOPoint>::iterator itrTOPoint = lTOPoint.begin(); itrTOPoint != lTOPoint.end() ; itrTOPoint++,i++){
		if(outComent){
			//print a status comment every 256 points
			if( ((i>>8)<<8)==i ){
				cout<<i<<" : "<<flush;
			}
		}
		//find conected points and make conection to them
		itr1=univers.begin();
		for ( list<unsigned long>::iterator itr=itrTOPoint->pPoint.begin() ; itr!=itrTOPoint->pPoint.end() ; itr++ ){
			if( (itrTOPoint->original->name)<=(*itr) ){
				break;
			}
			while ( itr1!=univers.end() ){
				if ( (*itr1)->name==(*itr) ) {
					break;
				};
				itr1++;
			}
			if( itr1!=univers.end() ){//create positiv distance
				itrTOPoint->original->pPoint.push_back( *itr1 );
				(*itr1)->pPoint.push_back( itrTOPoint->original );
			}
		}
		itr1=univers.begin();
		for ( list<unsigned long>::iterator itr=itrTOPoint->nPoint.begin() ; itr!=itrTOPoint->nPoint.end() ; itr++){
			if( (itrTOPoint->original->name)<=(*itr) ){
				break;
			}
			while ( itr1!=univers.end() ){
				if ((*itr1)->name==(*itr)) {
					break;
				};
				itr1++;
			}
			if( itr1!=univers.end() ){//create negativ distance
				itrTOPoint->original->nPoint.push_back( *itr1 );
				(*itr1)->nPoint.push_back( itrTOPoint->original );
			}
		}
	}
	evalueTransPosible();
	actualPoint=univers.begin();
	if(outComent){
		cout<<"reading done"<<endl;
	}
	return true;
}


/** sets all tmpValues (of all points and the univers) to 0 */
void cUnivers::nullTMPValues(){
	for ( list<cPoint*>::iterator uItr=univers.begin() ; uItr!=univers.end() ; uItr++ ){
		(*uItr)->tmpValue=0;
	}
	tmpValue=0;
}

#if FEATURE_FASTER_PART_SPLIT > 0
/**
 * This method splits this univers into its parts. 
 * The points of the parts are connected to each other and no point in a
 * part is not connected to any other point of the part.
 * This univers will be deleted afterwarts.
 * pre: this univers
 * @return this univers as its interconnected parts
 */
list<TUPart> cUnivers::splitUniversIntoParts(){

	list<TUPart> uParts;
	list<TUPart>::iterator pItr;
	list<cPoint*>::iterator itr1;
	list<cPoint*>::iterator actualPartBeginPoint=univers.begin();
	
	if(tmpValue>=+4294967000U){
		nullTMPValues();
	}
	tmpValue++;
	//seperate the parts
	while( actualPartBeginPoint!=univers.end() ){
	
		//insert new empty part univers
		TUPart ePart;
		pItr=uParts.insert( uParts.end(), ePart );
		pItr->pDistances=0;
		pItr->nDistances=0;
		
		//find first point of the next part
		while ( (actualPartBeginPoint!=univers.end()) && 
				((*actualPartBeginPoint)->tmpValue==tmpValue) ){
			actualPartBeginPoint++;
		};
		
		if ( actualPartBeginPoint==univers.end() ){
			break;//no other parts in the univers
		}
		//add found point as first point of the part
		pItr->partUnivers.push_back( *actualPartBeginPoint );
		(*actualPartBeginPoint)->tmpValue=tmpValue;
		
		for ( list<cPoint*>::iterator uItr=pItr->partUnivers.begin() ; uItr!=pItr->partUnivers.end() ; uItr++ ){
			//for all conections to the Point transfer conected points to the part
			pItr->pDistances+=(*uItr)->pPoint.size(); 
			pItr->nDistances+=(*uItr)->nPoint.size();
			//distances are double counted
			for ( itr1=(*uItr)->pPoint.begin() ; itr1!=(*uItr)->pPoint.end() ; itr1++ ){
			
				if((*itr1)->tmpValue!=tmpValue){
					//if the Point is not in the part, insert it and erase right point from the univers
					(*itr1)->tmpValue=tmpValue;
					pItr->partUnivers.push_back(*itr1);
				}
			}
			for (itr1=(*uItr)->nPoint.begin();itr1!=(*uItr)->nPoint.end();itr1++){
				//get right point
				if((*itr1)->tmpValue!=tmpValue){
					//if the Point is not in the part, insert it and erase right point from the univers
					(*itr1)->tmpValue=tmpValue;
					pItr->partUnivers.push_back(*itr1);
				}
			}
		}
	}
	//delete the points which wher inserted in the parts or delete alle points from the splited univers
	univers.clear();
	
	//sort to bigger universes first
	uParts.sort();
	uParts.reverse();
	return uParts;
}

#else

/**
 * This method splits this univers into its parts. 
 * The points of the parts are connected to each other and no point in a
 * part is not connected to any other point of the part.
 * This univers will be deleted afterwarts.
 * pre: this univers
 * @return this univers as its interconnected parts
 */
list<TUPart> cUnivers::splitUniversIntoParts(){

	list<TUPart> uParts;
	list<TUPart>::iterator pItr;
	list<cPoint*>::iterator itr1;
	
	if(tmpValue>=+4294967000U){
		nullTMPValues();
	}
	tmpValue++;
	//seperate the parts
	while( !univers.empty() ){
		//insert new empty part univers
		TUPart ePart;
		pItr=uParts.insert( uParts.end(), ePart );
		pItr->pDistances=0;
		pItr->nDistances=0;
		
		//transfer the firts point of the univers to the new part and delete transfered part
		pItr->partUnivers.push_back( *(univers.begin()) );
		(*(univers.begin()))->tmpValue=tmpValue;
		univers.erase( univers.begin() );
		
		for ( list<cPoint*>::iterator uItr=pItr->partUnivers.begin() ; uItr!=pItr->partUnivers.end() ; uItr++ ){
			//for all conections to the Point transfer conected points to the part
			pItr->pDistances+=(*uItr)->pPoint.size(); 
			pItr->nDistances+=(*uItr)->nPoint.size();
			//distances are double counted
			for ( itr1=(*uItr)->pPoint.begin() ; itr1!=(*uItr)->pPoint.end() ; itr1++ ){
			
				if((*itr1)->tmpValue!=tmpValue){
					//if the Point is not in the part, insert it and erase right point from the univers
					(*itr1)->tmpValue=tmpValue;
					pItr->partUnivers.push_back(*itr1);
				}
			}
			for (itr1=(*uItr)->nPoint.begin();itr1!=(*uItr)->nPoint.end();itr1++){
				//get right point
				if((*itr1)->tmpValue!=tmpValue){
					//if the Point is not in the part, insert it and erase right point from the univers
					(*itr1)->tmpValue=tmpValue;
					pItr->partUnivers.push_back(*itr1);
				}
			}
		}
		//delete the points which wher inserted in a part
		for ( list<cPoint*>::iterator uItr=univers.begin() ; uItr!=univers.end() ; uItr++){
			if( (*uItr)->tmpValue==tmpValue ){
				uItr=univers.erase(uItr);
				uItr--;
			}
		}
	}
	//sort to bigger universes first
	uParts.sort();
	uParts.reverse();
	return uParts;
}
#endif

/**
 * this method writes the statistic for the given universparts into an stream
 * @param universParts the univers parts for which to write the statistic
 * @param partStatistic the output stream, wher to write the statistic to
 * @return true if the statistic is written to the stream, else false
 */
bool cUnivers::writeUniversPartStatistic(const list<TUPart> &universParts, ostream &partStatisticStream){

	partStatisticStream<<universParts.size()<<"; ";
	for (list<TUPart>::const_iterator actualPart=universParts.begin() ; 
			actualPart!=universParts.end() ; actualPart++){
		/*write the data of the actual univers part to the stream*/
		partStatisticStream<<"( "<<actualPart->partUnivers.size()<<", "<<
			actualPart->pDistances/2<<", "<<actualPart->nDistances/2<<" ) ";
	}
	partStatisticStream<<";"<<endl;
	
	return true;
}

/**
 * adds the given univers parts to (the end) of this univers
 * @param universParts the universParts to add
 * @return true if the univers parts are added, else false
 */
bool cUnivers::addUniversParts( const list<TUPart> &universParts){

	for (list<TUPart>::const_iterator actualPart=universParts.begin() ; 
			actualPart!=universParts.end() ; actualPart++){
		univers.insert( univers.end(), actualPart->partUnivers.begin(), actualPart->partUnivers.end() );
	}

	return true;
}

/**
 * This method prints the statistic of the univers parts to the
 * universpart statistic file
 * @return true if the statistic is written, else false
 */
bool cUnivers::evaluePartStatistic(){

	if ( universPartStatisticFile==NULL ){
		return false;
	}
	
	/*remember actual point to restore it later*/
	unsigned long actualPointName=(*actualPoint)->name;
	
	/*print first part of univers part statistics*/
	(*universPartStatisticFile)<<bTime+iTime<<" ; "<<getNumberOfPoints()<<"; "<<pDistance<<"; "<<nDistance<<"; ";
	
	list<TUPart> uParts=splitUniversIntoParts();

	addUniversParts(uParts);
	
	/*restore the actual point*/
	actualPoint=univers.begin();//default is univers begin
	
	for (list<cPoint*>::iterator actPoint=univers.begin() ; 
			actPoint!=univers.end(); actPoint++){
		if ( (*actPoint)->name==actualPointName ){
			actualPoint=actPoint;
		}
	}
	
	//write the univers part statistic
	bool statisticWritten= writeUniversPartStatistic(uParts, *universPartStatisticFile);
	if ( !statisticWritten ){
		return false;
	}
	return true;
}



/**
 * Trys to delete parts of the univers that are no more conected to the main part.
 * The main part is the part, wich is the biggest(in number of Distances)
 * under the parts that are not smaler than (maxClass * (biggest Part)) and that
 * has a dimension nearest to dim.
 * @param dim the value of the dimension to be nearest to 
 * @param maxClass the minimum ratio the universes to choos must have (if 1 the bigest univers will allways be choosen)
 * @return the choosen univers as this univers
 */
void cUnivers::cutUnivers(const double dim, const double maxClass){

	if( outCutStatistic && (cutFile!=NULL) ) if ( (bTime+iTime)%outCutStatistic == 0  ){
		(*cutFile)<<bTime+iTime<<" ; "<<getNumberOfPoints()<<"; "<<pDistance<<"; "<<nDistance<<"; ";
	}
	
	list<TUPart> uParts=splitUniversIntoParts();
	
	list<TUPart>::iterator pItr;
	list<cPoint*>::iterator uItr;

	if(outComent){cout<<"cutparts : "<<uParts.size()<<" ";}
	if( outCutStatistic && (cutFile!=NULL) ) if ( (bTime+iTime)%outCutStatistic == 0 ){
		writeUniversPartStatistic(uParts, *cutFile);
	}
	
	//choos part
	pItr=uParts.begin();//choos biggest part univers
	if( (maxClass<=1.0) && (maxClass>0.0)  ){
	
		list<TUPart>::iterator tItr=uParts.begin();
		
		double dimDist=((double)((pItr->pDistances+pItr->nDistances)/2)/(double)(pItr->partUnivers.size()))-dim;
		if (dimDist<0){
			dimDist=dimDist*(-1.0);
		}
		double tDist;
		double biggest=((double)(pItr->pDistances+pItr->nDistances));
		for(;;){
			tItr++;
			if ( tItr==uParts.end() ){
				break;
			}
			if( (double)(tItr->pDistances+tItr->nDistances)<(biggest*maxClass) ){
				/*part is not in the max class*/
				break;
			}
			//if the part is in the max class and has a nearer dimension to dim, choos it
			tDist=((double)((tItr->pDistances+tItr->nDistances)/2)/(double)(tItr->partUnivers.size()))-dim;
			if (tDist<0.0){
				tDist=tDist*(-1.0);
			}
			if (dimDist>tDist) {
				pItr=tItr;
				dimDist=tDist;
			}
		}
	}
	//transfer choosen part pItr to univers
	univers=pItr->partUnivers;
	pDistance=(pItr->pDistances)/2;nDistance=(pItr->nDistances)/2;//all distances wher counted double
	uParts.erase(pItr);//don't delete points
	evalueTransPosible();
	actualPoint=univers.begin();
	//delete other parts points
	for (pItr=uParts.begin();pItr!=uParts.end();pItr++){
	
		for (uItr=pItr->partUnivers.begin();uItr!=pItr->partUnivers.end();uItr++)
			{delete (*uItr);}
		pItr->partUnivers.clear();
	}
}



#ifdef UNIVERS

/**
 * Makes a transition of the transition diagram with the cPoint poi
 * (p2 in the diagram) and two neigthbours (includes new cPoints)(p1 and
 * p3 in the diagram), which are selected with the wich parameter.
 * The possible transitions for a point are evaluated trougth the number 
 * of his neibours.
 *
 * @param poi the choosen point of the univers
 * @param wich the number of the transition to choos, from the possible
 *		transitions at the point poi
 * returns the this univers changed through the transition
 */
inline void cUnivers::evalueTransition( cPoint* poi, unsigned long wich ){

	unsigned long posible=poi->posNeibours+poi->negNeibours+1;
	unsigned long Point1=wich/posible;//choos first point(p1)
	unsigned long Point2=wich%posible;//choos secound(p3) point
	unsigned long tmpT;
	//if Point1/2 is (pDist+nDist) it is a new Point, if it is smaler then pDist
	//it has a positiv conection(distance) to pio(p2) else it has negativ
	//conection(distance) to pio(p2)
	list<cPoint*>::iterator itr1;//Point1
	list<cPoint*>::iterator itr2;//Point2
	list<cPoint*>::iterator itr3;//Point3; this point
	list<cPoint*>::iterator itr4;
	//3 posibilitys for each point: point is new, point is pDist or point is nDist
	//trans = transition as in the transitions diagram
	if ( Point1<poi->posNeibours ){
		itr1=poi->pPoint.begin();
		for ( itr4=itr1;Point1!=0; ){//get right point
			itr1++;
			if((*itr1)!=(*itr4)){
				itr4=itr1;
				Point1--;
			}
		}
		if ( Point2<poi->posNeibours ){
			//trans 1
			itr2=poi->pPoint.begin();
			for ( itr4=itr2 ; Point2!=0 ; ){//get right point
				itr2++;
				if( (*itr2)!=(*itr4) ){
					itr4=itr2;
					Point2--;
				}
			}
			if ( !((*itr1)==(*itr2)) ){
				cPoint* tmpP2=(*itr2);
				for ( itr3=(*itr1)->pPoint.begin() ; itr3!=(*itr1)->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=tmpP2->name ){
						break;//get right point
					}
				}
				(*itr1)->pPoint.insert( itr3, tmpP2 );
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=(*itr1)->name ){
						break;//get right point
					}
				}
				if ( itr3==tmpP2->pPoint.end() || (*itr3)!=(*itr1) ){
					//if a new neibour is added
					((*itr1)->posNeibours)++;
					tmpT=2*(((*itr1)->posNeibours)+((*itr1)->negNeibours))+1;
					(*itr1)->transPosible+=tmpT;
					transPosible+=tmpT;
					(tmpP2->posNeibours)++;
					tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+1;
					tmpP2->transPosible+=tmpT;
					transPosible+=tmpT;
				}
				tmpP2->pPoint.insert(itr3,(*itr1));
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					if ((*itr3)==poi){
						break;//get right point
					}
				}
				itr4=itr2;
				itr4++;
				if (itr4==poi->pPoint.end()||(*itr2)!=(*itr4)){
					//if the neibour points will be disconected
					(poi->posNeibours)--;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
					poi->transPosible-=tmpT;
					transPosible-=tmpT;
					(tmpP2->posNeibours)--;
					tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+3;
					tmpP2->transPosible-=tmpT;
					transPosible-=tmpT;
				}
				poi->pPoint.erase( itr2 );
				tmpP2->pPoint.erase( itr3 );
				trans[1]++;
			}
	}else{
			if ( Point2<(poi->posNeibours+poi->negNeibours) ){
				//Point2>=pDist; trans 2
				Point2-=poi->posNeibours;
				itr2=poi->nPoint.begin();
				for ( itr4=itr2 ; Point2!=0 ; ){//get right point
					itr2++;
					if( (*itr2)!=(*itr4) ){
						itr4=itr2;
						Point2--;
					}
				}
				for ( itr3=(*itr1)->pPoint.begin() ; itr3!=(*itr1)->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=poi->name ){
						break;//get right point
					}
				}
				(*itr1)->pPoint.insert( itr3 , poi );
				for ( itr3=(*itr2)->nPoint.begin() ; itr3!=(*itr2)->nPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=poi->name ){
						break;//get right point
					}
				}
				(*itr2)->nPoint.insert( itr3 , poi );
				for ( itr3=poi->pPoint.begin() ; itr3!=poi->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=(*itr1)->name ){
						break;//get right point
					}
				}
				if (itr3==poi->pPoint.end()||(*itr3)!=(*itr1)){
					//if a new neibour is added
					((*itr1)->posNeibours)++;
					tmpT=2*(((*itr1)->posNeibours)+((*itr1)->negNeibours))+1;
					(*itr1)->transPosible+=tmpT;
					transPosible+=tmpT;
					(poi->posNeibours)++;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+1;
					poi->transPosible+=tmpT;
					transPosible+=tmpT;
				}
				poi->pPoint.insert(itr3,*itr1);
				for ( itr3=poi->nPoint.begin() ; itr3!=poi->nPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=(*itr2)->name ){
						break;//get right point
					}
				}
				if ( itr3==poi->nPoint.end() || (*itr3)!=(*itr2) ){
					//if a new neibour is added
					((*itr2)->negNeibours)++;
					tmpT=2*(((*itr2)->posNeibours)+((*itr2)->negNeibours))+1;
					(*itr2)->transPosible+=tmpT;
					transPosible+=tmpT;
					(poi->negNeibours)++;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+1;
					poi->transPosible+=tmpT;
					transPosible+=tmpT;
				}
				poi->nPoint.insert(itr3,*itr2);
				pDistance++;
				nDistance++;
				trans[2]++;
			}else{//Point2==pDist+nDist->make new point; trans 5
				for ( itr3=(*itr1)->pPoint.begin() ; itr3!=(*itr1)->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ((*itr3)->name>=poi->name){
						break;//get right point
					}
				}
				(*itr1)->pPoint.insert( itr3 , poi );
				for ( itr3=poi->pPoint.begin() ; itr3!=poi->pPoint.end() ; itr3++ ){
					//keep the neibour list sorted
					if ( (*itr3)->name>=(*itr1)->name ){
						break;//get right point
					}
				}
				if ( itr3==poi->pPoint.end() || (*itr3)!=(*itr1) ){
					//if a new neibour is added
					((*itr1)->posNeibours)++;
					tmpT=2*(((*itr1)->posNeibours)+((*itr1)->negNeibours))+1;
					(*itr1)->transPosible+=tmpT;
					transPosible+=tmpT;
					(poi->posNeibours)++;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+1;
					poi->transPosible+=tmpT;
					transPosible+=tmpT;
				}
				poi->pPoint.insert( itr3, (*itr1) );
				cPoint* tmpP=new cPoint();
				last++;tmpP->name=last;//point is new and has the greatest name number
				univers.push_back( tmpP );
				(poi->negNeibours)++;
				tmpT=2*( (poi->posNeibours)+(poi->negNeibours) )+1;
				poi->transPosible+=tmpT;
				transPosible+=tmpT;
				poi->nPoint.push_back(tmpP);
				(tmpP->negNeibours)=1;
				tmpP->transPosible=4;
				transPosible+=4;
				tmpP->nPoint.push_back(poi);
				pDistance++;
				nDistance++;
				trans[5]++;
			}
		}
	}else{
		if ( Point1 < (poi->posNeibours+poi->negNeibours) ){
			//Point1>=pDist
			Point1-=poi->posNeibours;
			itr1=poi->nPoint.begin();
			for ( itr4=itr1; Point1!=0; ){
				//get right point
				itr1++;
				if( (*itr1)!=(*itr4) ){
					itr4=itr1;
					Point1--;
				}
			}
			
			if ( Point2 < poi->posNeibours )//trans 3
			{
				itr2=poi->pPoint.begin();
				for ( itr4=itr2 ; Point2!=0 ; ){
					//get right point
					itr2++;
					if( (*itr2)!=(*itr4) ){
						itr4=itr2;
						Point2--;
					}
				}
				cPoint* tmpP1=(*itr1);
				cPoint* tmpP2=(*itr2);
				poi->nPoint.erase(itr1);
				for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
					if ((*itr3)==poi){
						//get right point
						break;
					}
				}
				itr4=itr3;
				itr4++;
				if ( itr4==tmpP1->nPoint.end() || (*itr3)!=(*itr4) ){
					//if the neibour points will be disconected
					(poi->negNeibours)--;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
					poi->transPosible-=tmpT;
					transPosible-=tmpT;
					(tmpP1->negNeibours)--;
					tmpT=2*((tmpP1->posNeibours)+(tmpP1->negNeibours))+3;
					tmpP1->transPosible-=tmpT;
					transPosible-=tmpT;
				}
				tmpP1->nPoint.erase(itr3);
				poi->pPoint.erase(itr2);
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					if ((*itr3)==poi){
						//get right point
						break;
					}
				}
				itr4=itr3;
				itr4++;
				if ( itr4==tmpP2->pPoint.end() || (*itr3)!=(*itr4) ){
					//if the neibour points will be disconected
					(poi->posNeibours)--;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
					poi->transPosible-=tmpT;
					transPosible-=tmpT;
					(tmpP2->posNeibours)--;
					tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+3;
					tmpP2->transPosible-=tmpT;
					transPosible-=tmpT;
				}
				tmpP2->pPoint.erase(itr3);
				pDistance--;
				nDistance--;
				trans[3]++;
			}else{
				if ( Point2 < (poi->posNeibours+poi->negNeibours) ){
					//Point2>=pDist; trans 4
					Point2-=poi->posNeibours;
					itr2=poi->nPoint.begin();
					for ( itr4=itr2 ; Point2!=0 ; ){
						//get right point
						itr2++;
						if((*itr2)!=(*itr4)){
							itr4=itr2;
							Point2--;
						}
					}
					if ( !((*itr1)==(*itr2)) ){
						cPoint* tmpP1=(*itr1);
						for ( itr3=(*itr2)->nPoint.begin() ; itr3!=(*itr2)->nPoint.end() ; itr3++ ){
							//keep the neibour list sorted
							if ( (*itr3)->name>=tmpP1->name ){
								//get right point
								break;
							}
						}
						(*itr2)->nPoint.insert( itr3, tmpP1 );
						for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
							//keep the neibour list sorted
							if ( (*itr3)->name >= (*itr2)->name ){
								//get right point
								break;
							}
						}
						if ( itr3==tmpP1->nPoint.end() || (*itr3)!=(*itr2) ){
							//if a new neibour is added
							((*itr2)->negNeibours)++;
							tmpT=2*(((*itr2)->posNeibours)+((*itr2)->negNeibours))+1;
							(*itr2)->transPosible+=tmpT;
							transPosible+=tmpT;
							(tmpP1->negNeibours)++;
							tmpT=2*((tmpP1->posNeibours)+(tmpP1->negNeibours))+1;
							tmpP1->transPosible+=tmpT;
							transPosible+=tmpT;
						}
						tmpP1->nPoint.insert( itr3, (*itr2) );
						poi->nPoint.erase( itr1 );
						for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++){
							if ((*itr3)==poi){
								//get right point
								break;
							}
						}
						itr4=itr3;
						itr4++;
						if ( itr4==tmpP1->nPoint.end() || (*itr3)!=(*itr4) ){
							//if the neibour points will be disconected
							(poi->negNeibours)--;
							tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
							poi->transPosible-=tmpT;
							transPosible-=tmpT;
							(tmpP1->negNeibours)--;
							tmpT=2*((tmpP1->posNeibours)+(tmpP1->negNeibours))+3;
							tmpP1->transPosible-=tmpT;
							transPosible-=tmpT;
						}
						tmpP1->nPoint.erase( itr3 );
						trans[4]++;
					}
				}else{//Point2==pDist+nDist; trans 7
					cPoint* tmpP2=new cPoint();
					last++;tmpP2->name=last;
					univers.push_back( tmpP2 );
					cPoint* tmpP1=(*itr1);
					for ( itr3=(*itr1)->nPoint.begin() ; itr3!=(*itr1)->nPoint.end() ; itr3++ ){
						//keep the neibour list sorted
						if ((*itr3)->name>=tmpP2->name){
							//get right point
							break;
						}
					}
					(*itr1)->nPoint.insert( itr3, tmpP2 );
					for ( itr3=tmpP2->nPoint.begin(); itr3!=tmpP2->nPoint.end(); itr3++ ){
						//keep the neibour list sorted
						if ( (*itr3)->name >= (*itr1)->name ){
							//get right point
							break;
						}
					}
					if ( itr3==tmpP2->nPoint.end() || (*itr3)!=(*itr1) ){
						//if a new neibour is added
						((*itr1)->negNeibours)++;
						tmpT=2*(((*itr1)->posNeibours)+((*itr1)->negNeibours))+1;
						(*itr1)->transPosible+=tmpT;
						transPosible+=tmpT;
						(tmpP2->negNeibours)++;
						tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+1;
						tmpP2->transPosible+=tmpT;
						transPosible+=tmpT;
					}
					tmpP2->nPoint.insert( itr3, (*itr1) );
					poi->nPoint.erase( itr1 );
					for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
						if ( (*itr3)==poi ){
							//get right point
							break;
						}
					}
					itr4=itr3; itr4++;
					if ( itr4==tmpP1->nPoint.end() || (*itr3)!=(*itr4) ){
						//if the neibour points will be disconected
						(poi->negNeibours)--;
						tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
						poi->transPosible-=tmpT;
						transPosible-=tmpT;
						(tmpP1->negNeibours)--;
						tmpT=2*((tmpP1->posNeibours)+(tmpP1->negNeibours))+3;
						tmpP1->transPosible-=tmpT;
						transPosible-=tmpT;
					}
					tmpP1->nPoint.erase( itr3 );
					trans[7]++;
				}
			}
		}else{//Point1==pDist+nDist
			if ( Point2<poi->posNeibours ){
				//; trans 6
				itr2=poi->pPoint.begin();
				for ( itr4=itr2 ; Point2!=0 ; ){
					//get right point
					itr2++;
					if((*itr2)!=(*itr4)){
						itr4=itr2;
						Point2--;
					}
				}
				cPoint* tmpP1=new cPoint();
				last++;tmpP1->name=last;
				univers.push_back( tmpP1 );
				cPoint* tmpP2=(*itr2);
				(tmpP2->posNeibours)++;
				tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+1;
				tmpP2->transPosible+=tmpT;
				transPosible+=tmpT;
				tmpP2->pPoint.push_back( tmpP1 );
				(tmpP1->posNeibours)=1;
				tmpP1->transPosible=4;
				transPosible+=4;
				tmpP1->pPoint.push_back( tmpP2 );
				poi->pPoint.erase( itr2 );
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++){
					if ((*itr3)==poi){
						//get right point
						break;
					}
				}
				itr4=itr3;
				itr4++;
				if ( itr4==tmpP2->pPoint.end() || (*itr3)!=(*itr4) ){
					//if the neibour points will be disconected
					(poi->posNeibours)--;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+3;
					poi->transPosible-=tmpT;
					transPosible-=tmpT;
					(tmpP2->posNeibours)--;
					tmpT=2*((tmpP2->posNeibours)+(tmpP2->negNeibours))+3;
					tmpP2->transPosible-=tmpT;
					transPosible-=tmpT;
				}
				tmpP2->pPoint.erase( itr3 );
				trans[6]++;
			}else{
				if ( Point2 < (poi->posNeibours+poi->negNeibours) ){
					//Point2>=pDist; trans 8
					Point2-=poi->posNeibours;
					itr2=poi->nPoint.begin();
					for ( itr4=itr2 ; Point2!=0 ; ){
						//get right point
						itr2++;
						if( (*itr2)!=(*itr4) ){
							itr4=itr2;
							Point2--;
						}
					}
					for ( itr3=(*itr2)->nPoint.begin() ; itr3!=(*itr2)->nPoint.end() ; itr3++ ){
						//keep the neibour list sorted
						if ((*itr3)->name>=poi->name){
							//get right point
							break;
						}
					}
					(*itr2)->nPoint.insert( itr3, poi );
					for ( itr3=poi->nPoint.begin() ; itr3!=poi->nPoint.end() ; itr3++ ){
						//keep the neibour list sorted
						if ( (*itr3)->name>=(*itr2)->name ){
							//get right point
							break;
						}
					}
					if ( itr3==poi->nPoint.end() || (*itr3)!=(*itr2) ){
						//if a new neibour is added
						((*itr2)->negNeibours)++;
						tmpT=2*(((*itr2)->posNeibours)+((*itr2)->negNeibours))+1;
						(*itr2)->transPosible+=tmpT;
						transPosible+=tmpT;
						(poi->negNeibours)++;
						tmpT=2*((poi->posNeibours)+(poi->negNeibours))+1;
						poi->transPosible+=tmpT;
						transPosible+=tmpT;
					}
					poi->nPoint.insert( itr3, (*itr2) );
					cPoint* tmpP1=new cPoint();
					last++;
					tmpP1->name=last;
					univers.push_back(tmpP1);
					(poi->posNeibours)++;
					tmpT=2*((poi->posNeibours)+(poi->negNeibours))+1;
					poi->transPosible+=tmpT;
					transPosible+=tmpT;
					poi->pPoint.push_back( tmpP1 );
					(tmpP1->posNeibours)=1;
					tmpP1->transPosible=4;
					transPosible+=4;
					tmpP1->pPoint.push_back(poi);
					pDistance++;
					nDistance++;
					trans[8]++;
				}else{//Point2==pDist+nDist->two new points; trans 9
					cPoint* tmpP1=new cPoint();
					last++;
					tmpP1->name=last;
					univers.push_back( tmpP1 );
					cPoint* tmpP2=new cPoint();
					last++;
					tmpP2->name=last;
					univers.push_back( tmpP2 );
					(poi->posNeibours)++;
					(poi->negNeibours)++;
					tmpT=4*((poi->posNeibours)+(poi->negNeibours));
					poi->transPosible+=tmpT;
					transPosible+=tmpT;
					poi->pPoint.push_back( tmpP1 );
					poi->nPoint.push_back( tmpP2 );
					(tmpP1->posNeibours)=1;
					tmpP1->transPosible=4;
					tmpP1->pPoint.push_back( poi );
					(tmpP2->negNeibours)=1;
					tmpP2->transPosible=4;
					transPosible+=8;//both points: 4+4
					tmpP2->nPoint.push_back( poi );
					pDistance++;
					nDistance++;
					trans[9]++;
				}
			}
		}
	}
	
}

#endif


#ifdef UNIVERS_D

/**
 * Makes a transition of the transition diagram with the cPoint poi
 * (p2 in the diagram) and two neigthbours (includes new cPoints)(p1 and
 * p3 in the diagram), which are selected with the wich parameter.
 * The possible transitions for a point are evaluated trougth the number 
 * of his outgoing distances.
 *
 * @param poi the choosen point of the univers 
 * @param wich the number of the transition to choos, from the possible
 *		transitions at the point poi
 * returns the this univers changed through the transition
 */
inline void cUnivers::evalueTransition(cPoint* poi, unsigned long wich){
	unsigned long pDist=poi->pPoint.size();
	unsigned long nDist=poi->nPoint.size();
	unsigned long posible=pDist+nDist+1;
	unsigned long Point1=wich/posible;//choos first point(p1)
	unsigned long Point2=wich%posible;//choos secound(p3) point
	//cout<<" transp "<<poi->transPosible<<" pos "<<pDist<<" neg "<<nDist<<" p1 "<<(long)Point1-(long)pDist<<" p2 "<<(long)Point2-(long)pDist<<endl;
	
	
	//if Point1/2 is (pDist+nDist) it is a new Point, if it is smaler then pDist
	//it has a positiv conection(distance) to pio(p2) else it has negativ
	//conection(distance) to pio(p2)
	list<cPoint*>::iterator itr1;//Point1
	list<cPoint*>::iterator itr2;//Point2
	list<cPoint*>::iterator itr3;//Point3; this point
	//3 posibilitys for each point: point is new, point is pDist or point is nDist
	//trans = transition as in the transitions diagram
	if ( Point1 < pDist ){
	
		for ( itr1=poi->pPoint.begin() ; itr1!=poi->pPoint.end() ; itr1++){
			//get right point
			if ( Point1==0 ){
				break;
			}
			Point1--;
		}
		if ( Point2 < pDist ){
			//transition 1
			for ( itr2=poi->pPoint.begin() ; itr2!=poi->pPoint.end() ; itr2++ ){
				//get right point
				if ( Point2==0 ){
					break;
				}
				Point2--;
			}
			if ( !( (*itr1)==(*itr2) ) ){
				cPoint* tmpP2=(*itr2);
				(*itr1)->pPoint.push_back( tmpP2 );
				tmpP2->pPoint.push_back( *itr1 );
				poi->pPoint.erase( itr2 );
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					//get right point
					if ( (*itr3)==poi ){
						break;
					}
				}
				tmpP2->pPoint.erase( itr3 );
				(*itr1)->getTransPosible();
				poi->getTransPosible();
				transPosible+=( (*itr1)->pPoint.size()+(*itr1)->nPoint.size()+1 )*2;
				transPosible-=2*posible;
				trans[1]++;
			}
	}else{
			if ( Point2 < (pDist+nDist) ){
				//Point2>=pDist; transition 2
				Point2-=pDist;
				for ( itr2=poi->nPoint.begin() ; itr2!=poi->nPoint.end() ; itr2++ ){
					//get right point
					if ( Point2==0 ){
						break;
					}
					Point2--;
				}
				(*itr1)->pPoint.push_back( poi );
				poi->pPoint.push_back( *itr1 );
				(*itr2)->nPoint.push_back( poi );
				poi->nPoint.push_back( *itr2 );
				(*itr1)->getTransPosible();
				(*itr2)->getTransPosible();
				poi->getTransPosible();
				transPosible+=( (*itr1)->pPoint.size()+(*itr1)->nPoint.size()
					+(*itr2)->pPoint.size()+(*itr2)->nPoint.size()+3+posible*2 )*2;
				pDistance++;
				nDistance++;
				trans[2]++;
			}else{
				//Point2==pDist+nDist->make nnew point; transition 5
				(*itr1)->pPoint.push_back( poi );
				poi->pPoint.push_back( *itr1 );
				cPoint* tmpP=new cPoint();
				last++;tmpP->name=last;
				univers.push_back( tmpP );
				poi->nPoint.push_back( tmpP );
				tmpP->nPoint.push_back( poi );
				(*itr1)->getTransPosible();
				tmpP->getTransPosible();
				(poi)->getTransPosible();
				transPosible+=( (*itr1)->pPoint.size()+(*itr1)->nPoint.size()+posible*2 )*2+9;
				pDistance++;
				nDistance++;
				trans[5]++;
			}
		}
	}else{
		if ( Point1<(pDist+nDist) ){
			//Point1>=pDist
			Point1-=pDist;
			for ( itr1=poi->nPoint.begin() ; itr1!=poi->nPoint.end() ; itr1++ ){
				//get right point
				if ( Point1==0 ){
					break;
				}
				Point1--;
			}
			if ( Point2<pDist ){
				//transition 3
				for ( itr2=poi->pPoint.begin() ; itr2!=poi->pPoint.end() ; itr2++ ){
					//get right point
					if ( Point2==0 ){
						break;
					}
					Point2--;
				}
				cPoint* tmpP1=(*itr1);
				cPoint* tmpP2=(*itr2);
				poi->nPoint.erase( itr1 );
				for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
					//get right point
					if ( (*itr3)==poi ){
						break;
					}
				}
				tmpP1->nPoint.erase( itr3 );
				poi->pPoint.erase( itr2 );
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					//get right point
					if ( (*itr3)==poi ){
						break;
					}
				}
				tmpP2->pPoint.erase( itr3 );
				tmpP1->getTransPosible();
				tmpP2->getTransPosible();
				poi->getTransPosible();
				transPosible-=( tmpP1->pPoint.size()+tmpP1->nPoint.size()
					+tmpP2->pPoint.size()+tmpP2->nPoint.size()+posible*2+1 )*2;
				/*(tmpP1->pPoint.size()+tmpP1->nPoint.size()+1)*2+1
					+(tmpP2->pPoint.size()+tmpP2->nPoint.size()+1)*2+1
					+(posible*4)-4;*/
				pDistance--;
				nDistance--;
				trans[3]++;
			}else{
				if ( Point2<(pDist+nDist) ){
					//Point2>=pDist; transition 4
					Point2-=pDist;
					for ( itr2=poi->nPoint.begin() ; itr2!=poi->nPoint.end() ; itr2++ ){
						//get right point
						if ( Point2==0 ){
							break;
						}
						Point2--;
					}
					if ( !( (*itr1)==(*itr2) ) ){
						cPoint* tmpP1=(*itr1);
						(*itr2)->nPoint.push_back( tmpP1 );
						tmpP1->nPoint.push_back( *itr2 );
						poi->nPoint.erase( itr1 );
						for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
							//get right point
							if ( (*itr3)==poi ){
								break;
							}
						}
						tmpP1->nPoint.erase( itr3 );
						poi->getTransPosible();
						(*itr2)->getTransPosible();
						transPosible+=( (*itr2)->pPoint.size()+(*itr2)->nPoint.size()+1 )*2;
						transPosible-=2*posible;
						trans[4]++;
					}
				}else{//Point2==pDist+nDist; transition 7
					cPoint* tmpP2=new cPoint();
					last++;tmpP2->name=last;
					univers.push_back( tmpP2 );
					cPoint* tmpP1=( *itr1 );
					tmpP1->nPoint.push_back( tmpP2 );
					tmpP2->nPoint.push_back( *itr1 );
					poi->nPoint.erase( itr1 );
					for ( itr3=tmpP1->nPoint.begin() ; itr3!=tmpP1->nPoint.end() ; itr3++ ){
						//get right point
						if ( (*itr3)==poi ){
							break;
						}
					}
					tmpP1->nPoint.erase( itr3 );
					tmpP2->getTransPosible();
					poi->getTransPosible();
					transPosible+=5;
					transPosible-=posible*2;
					trans[7]++;
				}
			}
		}else{//Point1==pDist+nDist
			if (Point2<pDist){
				//transition 6
				for ( itr2=poi->pPoint.begin() ; itr2!=poi->pPoint.end() ; itr2++ ){
					//get right poi
					if ( Point2==0 ){
						break;
					}
					Point2--;
				}
				cPoint* tmpP1=new cPoint();
				last++;tmpP1->name=last;
				univers.push_back( tmpP1 );
				cPoint* tmpP2=(*itr2);
				tmpP2->pPoint.push_back( tmpP1 );
				tmpP1->pPoint.push_back( *itr2 );
				poi->pPoint.erase( itr2 );
				for ( itr3=tmpP2->pPoint.begin() ; itr3!=tmpP2->pPoint.end() ; itr3++ ){
					//get right point
					if ( (*itr3)==poi ){
						break;
					}
				}
				tmpP2->pPoint.erase( itr3 );
				tmpP1->getTransPosible();
				poi->getTransPosible();
				transPosible+=5;
				transPosible-=posible*2;
				trans[6]++;
			}else{
				if ( Point2<(pDist+nDist) ){
					//Point2>=pDist; transition 8
					Point2-=pDist;
					for ( itr2=poi->nPoint.begin() ; itr2!=poi->nPoint.end() ; itr2++ ){
						//get right point
						if ( Point2==0 ){
							break;
						}
						Point2--;
					}
					(*itr2)->nPoint.push_back( poi );
					poi->nPoint.push_back( *itr2 );
					cPoint* tmpP1=new cPoint();
					last++;tmpP1->name=last;
					univers.push_back( tmpP1 );
					poi->pPoint.push_back( tmpP1 );
					tmpP1->pPoint.push_back( poi );
					(*itr2)->getTransPosible();
					tmpP1->getTransPosible();
					poi->getTransPosible();
					transPosible+=( (*itr2)->pPoint.size()+(*itr2)->nPoint.size()+posible*2 )*2+9;
					pDistance++;
					nDistance++;
					trans[8]++;
				}else{
					//Point2==pDist+nDist->two new points; transition 9
					cPoint* tmpP1=new cPoint();
					last++;tmpP1->name=last;
					univers.push_back( tmpP1 );
					poi->pPoint.push_back( tmpP1 );
					tmpP1->pPoint.push_back( poi );
					cPoint* tmpP2=new cPoint();
					last++;tmpP2->name=last;
					univers.push_back( tmpP2 );
					poi->nPoint.push_back( tmpP2 );
					tmpP2->nPoint.push_back( poi );
					tmpP1->getTransPosible();
					tmpP2->getTransPosible();
					poi->getTransPosible();
					transPosible+=12+posible*4;
					pDistance++;
					nDistance++;
					trans[9]++;
				}
			}
		}
	}

}

#endif


#ifdef UNIVERS_P
/*TODO: whts the difference to UNIVERS_D?*/
/**
 * Makes a transition of the transition diagram with the cPoint poi
 * (p2 in the diagram) and two neigthbours (includes new cPoints)(p1 and
 * p3 in the diagram), which are selected with the wich parameter.
 * The possible transitions for a point are evaluated trougth the number 
 * of his outgoing distances.
 *
 * @param poi the choosen point of the univers 
 * @param wich the number of the transition to choos, from the possible
 *		transitions at the point poi
 * returns the this univers changed through the transition
 */
inline void cUnivers::evalueTransition(cPoint* poi, unsigned long wich){
	unsigned long pDist=poi->pPoint.size();
	unsigned long nDist=poi->nPoint.size();
	unsigned long ulPossible=pDist+nDist+1;
	unsigned long Point1=wich / ulPossible;//choos first point(p1)
	unsigned long Point2=wich % ulPossible;//choos secound(p3) point
	
	//if Point1/2 is (pDist+nDist) it is a new Point, if it is smaler then pDist
	//it has a positiv conection(distance) to pio(p2) else it has negativ
	//conection(distance) to pio(p2)
	list<cPoint*>::iterator itr1;//Point1
	list<cPoint*>::iterator itr2;//Point2
	list<cPoint*>::iterator itr3;//Point3; this point
	//3 posibilitys for each point: point is new, point is pDist or point is nDist
	//trans = transition as in the transitions diagram
	if (Point1<pDist)
	{
		for (itr1=poi->pPoint.begin();itr1!=poi->pPoint.end();itr1++)
			{if (Point1==0){break;}Point1--;}//get right point
		if (Point2<pDist)//trans 1
		{
			for (itr2=poi->pPoint.begin();itr2!=poi->pPoint.end();itr2++)
				{if (Point2==0){break;}Point2--;}//get right point
			if (!((*itr1)==(*itr2)))
			{//don't make a distance with the same endpoints
				cPoint* tmpP2=(*itr2);
				(*itr1)->pPoint.push_back(tmpP2);
				tmpP2->pPoint.push_back(*itr1);
				poi->pPoint.erase(itr2);
				for (itr3=tmpP2->pPoint.begin();itr3!=tmpP2->pPoint.end();itr3++)
					{if ((*itr3)==poi){break;}}//get right point
				tmpP2->pPoint.erase(itr3);
				trans[1]++;
				//change transitions possible(subtract old possible transitions 
				//and add now new transitions possible)
				transPosible-=poi->transPosible;
				transPosible-=(*itr1)->transPosible;
				transPosible-=tmpP2->transPosible;
				//getTransPosible() changes also transPosible for the single points
				transPosible+=poi->getTransPosible();
				transPosible+=(*itr1)->getTransPosible();
				transPosible+=tmpP2->getTransPosible();
			}
	}else{
			if (Point2<(pDist+nDist))//Point2>=pDist; trans 2
			{
				Point2-=pDist;
				for (itr2=poi->nPoint.begin();itr2!=poi->nPoint.end();itr2++)
					{if (Point2==0){break;}Point2--;}//get right point
				(*itr1)->pPoint.push_back(poi);
				poi->pPoint.push_back(*itr1);
				(*itr2)->nPoint.push_back(poi);
				poi->nPoint.push_back(*itr2);
				pDistance++;nDistance++;trans[2]++;
				//change transitions possible(subtract old possible transitions 
				//and add now new transitions possible)
				transPosible-=poi->transPosible;
				transPosible-=(*itr1)->transPosible;
				transPosible-=(*itr2)->transPosible;
				//getTransPosible() changes also transPosible for the single points
				transPosible+=poi->getTransPosible();
				transPosible+=(*itr1)->getTransPosible();
				transPosible+=(*itr2)->getTransPosible();
			}else{//Point2==pDist+nDist->make nnew point; trans 5
				(*itr1)->pPoint.push_back(poi);
				poi->pPoint.push_back(*itr1);
				cPoint* tmpP=new cPoint();
				last++;tmpP->name=last;
				univers.push_back(tmpP);
				poi->nPoint.push_back(tmpP);
				tmpP->nPoint.push_back(poi);
				pDistance++;nDistance++;trans[5]++;
				//change transitions possible(subtract old possible transitions 
				//and add now new transitions possible)
				transPosible-=poi->transPosible;
				transPosible-=(*itr1)->transPosible;
				//getTransPosible() changes also transPosible for the single points
				transPosible+=poi->getTransPosible();
				transPosible+=(*itr1)->getTransPosible();
				transPosible+=tmpP->getTransPosible();
			}
		}
	}else{
		if (Point1<(pDist+nDist))//Point1>=pDist
		{
			Point1-=pDist;
			for (itr1=poi->nPoint.begin();itr1!=poi->nPoint.end();itr1++)
				{if (Point1==0){break;}Point1--;}//get right point
			if (Point2<pDist)//trans 3
			{
				for (itr2=poi->pPoint.begin();itr2!=poi->pPoint.end();itr2++)
					{if (Point2==0){break;}Point2--;}//get right point
				cPoint* tmpP1=(*itr1);
				cPoint* tmpP2=(*itr2);
				poi->nPoint.erase(itr1);
				for (itr3=tmpP1->nPoint.begin();itr3!=tmpP1->nPoint.end();itr3++)
					{if ((*itr3)==poi){break;}}//get right point
				tmpP1->nPoint.erase(itr3);
				poi->pPoint.erase(itr2);
				for (itr3=tmpP2->pPoint.begin();itr3!=tmpP2->pPoint.end();itr3++)
					{if ((*itr3)==poi){break;}}//get right point
				tmpP2->pPoint.erase(itr3);
				pDistance--;nDistance--;trans[3]++;
				//change transitions possible(subtract old possible transitions 
				//and add now new transitions possible)
				transPosible-=poi->transPosible;
				transPosible-=tmpP1->transPosible;
				transPosible-=tmpP2->transPosible;
				//getTransPosible() changes also transPosible for the single points
				transPosible+=poi->getTransPosible();
				transPosible+=tmpP1->getTransPosible();
				transPosible+=tmpP2->getTransPosible();
			}else{
				if (Point2<(pDist+nDist))//Point2>=pDist; trans 4
				{
					Point2-=pDist;
					for (itr2=poi->nPoint.begin();itr2!=poi->nPoint.end();itr2++)
						{if (Point2==0){break;}Point2--;}//get right point
					if (!((*itr1)==(*itr2)))
					{//don't make a distance with the same endpoints
						cPoint* tmpP1=(*itr1);
						(*itr2)->nPoint.push_back(tmpP1);
						tmpP1->nPoint.push_back(*itr2);
						poi->nPoint.erase(itr1);
						for (itr3=tmpP1->nPoint.begin();itr3!=tmpP1->nPoint.end();itr3++)
							{if ((*itr3)==poi){break;}}//get right point
						tmpP1->nPoint.erase(itr3);
						trans[4]++;
						//change transitions possible(subtract old possible transitions 
						//and add now new transitions possible)
						transPosible-=poi->transPosible;
						transPosible-=tmpP1->transPosible;
						transPosible-=(*itr2)->transPosible;
						//getTransPosible() changes also transPosible for the single points
						transPosible+=poi->getTransPosible();
						transPosible+=tmpP1->getTransPosible();
						transPosible+=(*itr2)->getTransPosible();
					}
				}else{//Point2==pDist+nDist; trans 7
					cPoint* tmpP2=new cPoint();
					last++;tmpP2->name=last;
					univers.push_back(tmpP2);
					cPoint* tmpP1=(*itr1);
					(*itr1)->nPoint.push_back(tmpP2);
					tmpP2->nPoint.push_back(*itr1);
					poi->nPoint.erase(itr1);
					for (itr3=tmpP1->nPoint.begin();itr3!=tmpP1->nPoint.end();itr3++)
						{if ((*itr3)==poi){break;}}//get right point
					tmpP1->nPoint.erase(itr3);
					trans[7]++;
					//change transitions possible(subtract old possible transitions 
					//and add now new transitions possible)
					transPosible-=poi->transPosible;
					transPosible-=tmpP1->transPosible;
					//getTransPosible() changes also transPosible for the single points
					transPosible+=poi->getTransPosible();
					transPosible+=tmpP1->getTransPosible();
					transPosible+=tmpP2->getTransPosible();
				}
			}
		}else{//Point1==pDist+nDist
			if (Point2<pDist)//; trans 6
			{
				for (itr2=poi->pPoint.begin();itr2!=poi->pPoint.end();itr2++)
					{if (Point2==0){break;}Point2--;}//get right poi
				cPoint* tmpP1=new cPoint();
				last++;tmpP1->name=last;
				univers.push_back(tmpP1);
				cPoint* tmpP2=(*itr2);
				(*itr2)->pPoint.push_back(tmpP1);
				tmpP1->pPoint.push_back(*itr2);
				poi->pPoint.erase(itr2);
				for (itr3=tmpP2->pPoint.begin();itr3!=tmpP2->pPoint.end();itr3++)
					{if ((*itr3)==poi){break;}}//get right point
				tmpP2->pPoint.erase(itr3);
				trans[6]++;
				//change transitions possible(subtract old possible transitions 
				//and add now new transitions possible)
				transPosible-=poi->transPosible;
				transPosible-=tmpP2->transPosible;
				//getTransPosible() changes also transPosible for the single points
				transPosible+=poi->getTransPosible();
				transPosible+=tmpP1->getTransPosible();
				transPosible+=tmpP2->getTransPosible();
			}else{
				if (Point2<(pDist+nDist))//Point2>=pDist; trans 8
				{
					Point2-=pDist;
					for (itr2=poi->nPoint.begin();itr2!=poi->nPoint.end();itr2++)
						{if (Point2==0){break;}Point2--;}//get right point
					(*itr2)->nPoint.push_back(poi);
					poi->nPoint.push_back(*itr2);
					cPoint* tmpP1=new cPoint();
					last++;tmpP1->name=last;
					univers.push_back(tmpP1);
					poi->pPoint.push_back(tmpP1);
					tmpP1->pPoint.push_back(poi);
					pDistance++;nDistance++;trans[8]++;
					//change transitions possible(subtract old possible transitions 
					//and add now new transitions possible)
					transPosible-=poi->transPosible;
					transPosible-=(*itr2)->transPosible;
					//getTransPosible() changes also transPosible for the single points
					transPosible+=poi->getTransPosible();
					transPosible+=tmpP1->getTransPosible();
					transPosible+=(*itr2)->getTransPosible();
				}else{//Point2==pDist+nDist->two new points; trans 9
					cPoint* tmpP1=new cPoint();
					last++;tmpP1->name=last;
					univers.push_back(tmpP1);
					poi->pPoint.push_back(tmpP1);
					tmpP1->pPoint.push_back(poi);
					cPoint* tmpP2=new cPoint();
					last++;tmpP2->name=last;
					univers.push_back(tmpP2);
					poi->nPoint.push_back(tmpP2);
					tmpP2->nPoint.push_back(poi);
					pDistance++;nDistance++;trans[9]++;
					//change transitions possible(subtract old possible transitions 
					//and add now new transitions possible)
					transPosible-=poi->transPosible;
					//getTransPosible() changes also transPosible for the single points
					transPosible+=poi->getTransPosible();
					transPosible+=tmpP1->getTransPosible();
					transPosible+=tmpP2->getTransPosible();
				}
			}
		}
	}
}

/**
 * evalue a tick (tick: minimal time change, of the univers);
 * on every points of the univers a random transition is performed.
 * Points that have no neigthbours are deleted.
 * post: this univers changed
 */
void cUnivers::tick()
{
	list<cPoint*>::iterator actualPoint=univers.begin();
	unsigned long uSz=univers.size();
	unsigned long ulRand=0;
	
	for ( unsigned long i=0 ; i<10 ; i++ ){
		trans[i]=0;
	}
	for ( unsigned long i=0 ; i<uSz ; i++ ){
		//evalue all old points
		if ( (((*actualPoint)->pPoint.empty()) && ((*actualPoint)->nPoint.empty())) 
				&& (univers.size()>1) ){
			//cut points with no conections
			delete (*actualPoint);
			actualPoint=univers.erase( actualPoint );
		}else{
			ulRand=rg1->IRandom( 1, (*actualPoint)->transPosible ) - 1;
			evalueTransition( *actualPoint, ulRand );
			actualPoint++;
		}
	}
}

/**
 * Evalue a tick, minimal time change, of the univers. 
 * For that, on trans points (after an random choosen startpoint) of the 
 * univers a random transition is performed.
 * Points that have no neigthbours are deleted.
 * post: this univers changed
 * @param trans number of transitions to perform
 */
void cUnivers::tick( unsigned long trans ){
	list<cPoint*>::iterator actualPoint=univers.begin();
	unsigned long ulRand=0;
	
	//choos random startpoint
	ulRand=rg1->IRandom( 0, univers.size() );
	for ( ; ulRand>0 ; ulRand-- ){
		actualPoint++;
		if( actualPoint==univers.end() ){
			actualPoint=univers.begin();
		}
	}
	//evalue next trans points
	for (unsigned long i=0;i<trans;i++){
		//evalue trans transitions
		if ( (((*actualPoint)->pPoint.empty()) && ((*actualPoint)->nPoint.empty())) 
				&& (univers.size()>1) ){
			//cut points with no conections
			delete (*actualPoint);
			actualPoint=univers.erase( actualPoint );
			i--;//don't count deleted points in trans
		}else{
			ulRand=rg1->IRandom( 1, (*actualPoint)->transPosible ) - 1;
			evalueTransition( *actualPoint, ulRand );
			//next point
			actualPoint++;
		}
		if( actualPoint==univers.end() ){
			actualPoint=univers.begin();
		}
	}
}


#else//not universP


/**
 * Evalue a tick, minimal time change, of the univers.
 * Evalue a transition for ervery point in the univers
 * post: this univers changed
 */
void cUnivers::tick(){
	unsigned long uSz=univers.size();
	unsigned long step=univers.size() / 256;
	if(step==0){
		step=1;
	}
	unsigned long ulRand=0;
	//init number of transition counters
	for ( unsigned long i=0 ; i<10 ; i++ ){
		trans[i]=0;
	}
	for ( unsigned long i=0 ; i<uSz ; i++ ){
		//make transitions
		ulRand+=rg1->IRandom( 0, transPosible/step );//evalue every average 128 point*average posible transitions
		while(ulRand>=(*actualPoint)->transPosible){
			ulRand-=(*actualPoint)->transPosible;
			actualPoint++;
			if( actualPoint==univers.end() ){
				actualPoint=univers.begin();
			}
		}
		evalueTransition( *actualPoint, ulRand );
	}
}

/**
 * Evalue a tick, minimal time change, of the univers.
 * For that, on trans points (after the actual point) of the 
 * univers a random transition is performed.
 * post: this univers changed
 *
 * @param trans number of transitions to perform
 */
void cUnivers::tick(unsigned long trans){
	unsigned long ulRand=0;
	for (unsigned long i=0;i<trans;i++){
		//evalue trans transitions
		ulRand+=rg1->IRandom( 0, transPosible );
		while( ulRand>=(*actualPoint)->transPosible ){
			ulRand-=(*actualPoint)->transPosible;
			actualPoint++;
			if( actualPoint==univers.end() ){
				actualPoint=univers.begin();
			}
		}
		evalueTransition( *actualPoint, ulRand );
	}
}

#endif

/**
 * Print the head of the statistics to the statistic stream, if it exists.
 * The diverent rows a seperated by ";".
 * @param ostream the output stream ostream to print the statistics head to
 * @return true if the head of the statistics is writen to the output 
 *		stream, else false 
 */
bool cUnivers::printStatisticHead( ostream& ostream ) const{
	if( !ostream ){
		return false;
	}
	ostream<<"time ; points ; pos distances ; neg distances ; distances/points ; ";
	ostream<<"transitions ins ; trans 1 ; trans 1 p ; trans 2 ; trans 2 p ; trans 3 ; trans 3 p ; trans 4 ; trans 4 p ; ";
	ostream<<"trans 5 ; trans 5 p ; trans 6 ; trans 6 p ; trans 7 ; trans 7 p ; trans 8 ; trans 8 p ; ";
	ostream<<"trans 9 ; trans 9 p ; number of posible transitions ; "<<endl;
	return true;
}

/**
 * Print the the statistics of the actual univers and the last transitions
 * to the statistic stream, if it exists. The diverent rows a seperated by ";".
 * Prints one line.
 * @param ostream the output stream ostream to print the actual statistics to
 * @return true if the actual statistics is written to in the output 
 * stream, else false*/
bool cUnivers::printStatistic( ostream& ostream ){
	if( !ostream ){
		return false;
	}
	//trans[0] is the transition sum
	trans[0]=trans[1]+trans[2]+trans[3]+trans[4]+trans[5]+trans[6]+trans[7]+trans[8]+trans[9];
	ostream<<iTime+bTime<<" ; "<<getNumberOfPoints()<<" ; "<<pDistance<<" ; "<<nDistance;
	ostream<<" ; "<< ((double)( pDistance+nDistance )/(double)( getNumberOfPoints()) ) <<" ; ";
	ostream<<trans[0]<<" ; "<<trans[1]<<" ; "<< (double)(trans[1])/(double)(trans[0]) <<" ; ";
	ostream<<trans[2]<<" ; "<<(double)(trans[2])/(double)(trans[0])<<" ; ";
	ostream<<trans[3]<<" ; "<<(double)(trans[3])/(double)(trans[0])<<" ; ";
	ostream<<trans[4]<<" ; "<<(double)(trans[4])/(double)(trans[0])<<" ; ";
	ostream<<trans[5]<<" ; "<<(double)(trans[5])/(double)(trans[0])<<" ; ";
	ostream<<trans[6]<<" ; "<<(double)(trans[6])/(double)(trans[0])<<" ; ";
	ostream<<trans[7]<<" ; "<<(double)(trans[7])/(double)(trans[0])<<" ; ";
	ostream<<trans[8]<<" ; "<<(double)(trans[8])/(double)(trans[0])<<" ; ";
	ostream<<trans[9]<<" ; "<<(double)(trans[9])/(double)(trans[0])<<" ; ";
	ostream<<transPosible<<" ; "<<endl;
	return true;
}

/**
 * output the the statistics of the actual univers and the last 
 * transitions	to the consol(cout).
 * post:  the actual statistics on the console
 */
void cUnivers::outputStatistic(){
	cout<<"Time : "<< bTime+iTime <<" iteration : "<< iTime <<" points : "<< getNumberOfPoints();
	cout<<" pos distances : "<< pDistance<<" neg distances : "<< nDistance;
	cout<<" distances/points : "<< ((double)(pDistance+nDistance)/(double)(getNumberOfPoints()));
	cout<<" posible transitions : "<< transPosible<<endl;
}

/**
 * Evalues the end condition for the univers. Means when the evaluation 
 * of	the univers is stoped.
 * case 1: the time iTime is higer than the maximum number of ticks (maxTime,
 * 	maxTime=0 -> inf) or (the number of points should be checked (it is the
 * 	checkMaxPoints tick) and it is higher then the maximal number of points
 * 	(maxPoints, maxPoints=0 -> inf))
 * @return true if the end condition holds and the univers should be stoped,
 * 	else false
 */
bool cUnivers::endCondition() const{
	if ( bEndEvaluation ){
		//end evaluation Flag is set
		return bEndEvaluation;
	}	
	if ( maxTime==0 ){
	
		if ( (maxPoints==0) || (checkMaxPoints==0) ){
			//run infinity
			return false;
		}
		if ( (checkMaxPoints) && (((iTime/checkMaxPoints)*checkMaxPoints)==iTime) ){
			return ( maxPoints < getNumberOfPoints() );
		}
		return false;
	}
	if ( (maxPoints==0) || (checkMaxPoints==0) ){
		return (iTime+bTime>=maxTime);
	}
	if ( ((iTime/checkMaxPoints)*checkMaxPoints) == iTime ){
		return ( (iTime+bTime >= maxTime) || (maxPoints < getNumberOfPoints()) );
	}
	return ( iTime+bTime >= maxTime );
}

/**
 * Starts the evaluation of the univers. Makes ticks till the end 
 * condition ( endCondition() ) holds.
 * post: the this univers changed
 * @see endCondition()
 * @see tick()
 *
 * @param trans number of transitions to evalue in an tick(), if 0 the 
 * 	number of transition is unlimeted is the number of points at the 
 * 	start of the tick
 */
void cUnivers::start( unsigned long trans ){

	initUnivers();
	while ( !endCondition() )
	{
		iTime++;
		if ( trans==0 ) {
			//number of transitions is not limited
			tick();
		}else{
			tick(trans);
		}
		if( outComent ){
			//output comments
			outputStatistic();
		}
		if( (cutAfter) && ( (bTime+iTime) % cutAfter == 0 ) ){
			//cut univers
			cutUnivers( cutNearDimension, cutMaxClassRatio );
			if( outComent ){
				outputStatistic();
			}
		}
		if ( outStat ) if ( (bTime+iTime)%outStat == 0 ){
			printStatistic( *statFile );
		}
		if ( lOutUniversPartStatistic ) if ( (bTime+iTime)%lOutUniversPartStatistic == 0 ){
			evaluePartStatistic();
		}
		if ( outUniv ) if ( (bTime+iTime) % outUniv == 0 ){
			//output actual universe
			char univFile[1000];
			sprintf( univFile, "%s%s%li.txt", uFolder, bUName, bTime+(long)iTime );
			ofstream uFile( univFile );
			if (uFile ){
				printUnivers( uFile );
				uFile.close();
			}else {
				printf( "Problem opening the univers file\n" );
			}
		}
	}
}

/** init the enviroment of the univers;
 * crates directoris for statistics und other output;
 * for failed initialisations the bXXXChanged-Variable is true
 * @return 0 if all inits are OK; the number of faild initialisations is returned;
 */
int cUnivers::initUnivers(){

	int iFailed=0;
	
	nullTMPValues();
	
	//output dir for the universes
	if ( ( uFolder ) && ( outUniv ) ){
		cratePath(uFolder);
	}
	bUniversParameterChanged=false;
	
	//init statistics
	if ( bStatParameterChanged ){
		//close old file and open or reopen statistic-file
	
		bStatParameterChanged=false;
		if ( statFile ){//close old file
			statFile->close();
			delete statFile;
			statFile = NULL;
		}
		
		if ( outStat && statFileName ){
			//open or reopen statistic file
			bool bOpenExistingFile=false;
			
			if ( appendUnivers ){
				//try to reopen existing statistic-file
				bOpenExistingFile=checkPath(statFileName) ;
			}
				
			if ( bOpenExistingFile ){//reopen file
				statFile=new fstream(statFileName);
			}else{
				statFile=new fstream(statFileName,ios::out);
			}
			if ( statFile ){
				if( bOpenExistingFile && searchForLine( statFile, ((getTimeBase()/outStat)*outStat) , STATISTIC_ROWS ) ){
					//append after last writen line
					(*statFile)<<endl;
				}else{ 
					printStatisticHead( *statFile );
				}
			}else{//error occoured
				iFailed++;
				bStatParameterChanged=true;
				if(outComent){
					cout<<endl<<"Fehler beim Oeffnen der Statistik-Datei"<<endl;
				}
			}
		}
	}
	
	//init real-time-statistc
	if ( bRTimeParameterChanged ){
		//close old file and open or reopen real-time-file
	
		bRTimeParameterChanged=false;
		if ( rTimeFile ){//close old file
			rTimeFile->close();
			delete rTimeFile;
			rTimeFile = NULL;
		}
		
		if ( outRealTime && rTimeFileName ){
			//open or reopen real-time-file
			bool bOpenExistingFile=false;
			
			if ( appendUnivers ){
				//try to reopen existing real-time-file
				bOpenExistingFile=checkPath(rTimeFileName) ;
			}
				
			if ( bOpenExistingFile ){//reopen file
				rTimeFile=new fstream(rTimeFileName);
			}else{
				rTimeFile=new fstream(rTimeFileName,ios::out);
			}
			if ( rTimeFile ){
				if( bOpenExistingFile && searchForLine( rTimeFile, ((getTimeBase()/outRealTime)*outRealTime) , 11 ) ){
					//append after last writen line
					(*rTimeFile)<<endl;
				}else{ 
					printRealTimeStatisticHead();
				}
			}else{//error occoured
				iFailed++;
				bRTimeParameterChanged=true;
				if(outComent){
					cout<<endl<<"Fehler beim Oeffnen der Realzeitstatistik-Datei"<<endl;
				}
			}
		}
	}
	
	//init cut-statistc
	if ( bCutParameterChanged ){
		//close old file and open or reopen real-time-file
	
		bCutParameterChanged=false;
		if ( cutFile ){//close old file
			cutFile->close();
			delete cutFile;
			cutFile = NULL;
		}
		
		if ( outCutStatistic && cutFileName ){
			//open or reopen statistic file
			bool bOpenExistingFile=false;
			
			if ( appendUnivers ){
				//try to reopen existing statistic-file
				bOpenExistingFile=checkPath(cutFileName) ;
			}
				
			if ( bOpenExistingFile ){//reopen file
				cutFile=new fstream(cutFileName);
			}else{
				cutFile=new fstream(cutFileName,ios::out);
			}
			if ( cutFile ){
				if( bOpenExistingFile && searchForLine( cutFile, ((getTimeBase()/outCutStatistic)*outCutStatistic) , 6 ) ){
					//append after last writen line
					(*cutFile)<<endl;
				}else{ 
					printUniversPartsStatisticHead( *cutFile );
				}
			}else{//error occoured
				iFailed++;
				bCutParameterChanged=true;
				if(outComent)
				{
					cout<<endl<<"Fehler beim Oeffnen der cut-Statistik-Datei"<<endl;
				}
			}
		}
	}
	
	/*init univers part statistic*/
	if ( bUniversPartStatisticParameterChanged ){
		//close old file and open or reopen real-time-file
	
		bUniversPartStatisticParameterChanged=false;
		
		if ( lOutUniversPartStatistic && szUniversPartStatisticFileName ){
			//open or reopen statistic file
			bool bOpenExistingFile=false;
			
			if ( appendUnivers ){//try to reopen existing statistic-file
				bOpenExistingFile=checkPath(szUniversPartStatisticFileName) ;
			}
				
			if ( bOpenExistingFile ){//reopen file
				universPartStatisticFile=new fstream(szUniversPartStatisticFileName);
			}else{
				universPartStatisticFile=new fstream(szUniversPartStatisticFileName,ios::out);
			}
			if ( universPartStatisticFile ){
				if( bOpenExistingFile && searchForLine( cutFile, 
					((getTimeBase()/lOutUniversPartStatistic)*lOutUniversPartStatistic) , 6 ) ){
					//append after last writen line
					(*universPartStatisticFile)<<endl;
				}else{ 
					printUniversPartsStatisticHead( *universPartStatisticFile );
				}
			}else{//error occoured
				iFailed++;
				bUniversPartStatisticParameterChanged=true;
				if(outComent){
					cout<<endl<<"Fehler beim Oeffnen der univers-part-Statistik-Datei"<<endl;
				}
			}
		}
	}
	
	return iFailed;
}

/**
 * the equal realtion for cUnivers
 * @param univ the univers to compare this univers to
 * @return true if the univers has same points in the same amount, false else
 */
bool cUnivers::operator==( cUnivers &univ ){
#if DEBUG>1
	std::cout<<"comparing universes with sizes: "<<univers.size()<<" and "<<univ.univers.size()<<std::endl;
#endif
	//fast check: if the number of neibours don't have the same amount, the points are not equal
	if ( ( univers.size()!= univ.univers.size() ) ){
		return false;
	}
	//sort neibour points; if the points are sorted ther are easier to compare
	univers.sort( &cPoint::lower );
	univ.univers.sort( &cPoint::lower );
	
	//compare points
	if( !univers.empty() ){
		//same for poi because of fast check of neibour amount
		list<cPoint*>::iterator tItr1=univers.begin();
		list<cPoint*>::iterator tItr2=univ.univers.begin();
		for ( ; tItr1!=univers.end() && tItr2!=univ.univers.end() ; tItr1++, tItr2++ )
		{
#if DEBUG>1
			std::cout<<"comparing Points of the universes: "<<std::endl;
			std::cout<<"cPoint1 : "<<(*tItr1)->name<<std::endl;
			std::cout<<"cPoint2 : "<<(*tItr2)->name<<std::endl;
#endif
			if ( !((**tItr1)==(**tItr2)) ){
				//not equal neibour found
				return false;
			}
		}
	}
	return true;
}


/**
 * outputs this cPoint to the ostream;
 * first comes the name of this cPoint then a ";", the the names of positiv
 * neigbours (for each a ","), then a ";", the the names of negativ
 * neigbours (for each a ","), the a "." and a newline
 * @param tpoi the point to output
 *
 * @param ostream the stream wher to output the point to
 * @return this cPoint in the stream
 */
ostream& operator<<( ostream &ostream, cPoint &tpoi ){

	ostream<<tpoi.name<<";";
	for ( list<cPoint*>::iterator itr1=tpoi.pPoint.begin() ; itr1!=tpoi.pPoint.end() ; itr1++ ){
	
		ostream<<","<<(*itr1)->name;
	}
	ostream<<";";
	for ( list<cPoint*>::iterator itr1=tpoi.nPoint.begin() ; itr1!=tpoi.nPoint.end() ; itr1++ ){
	
		ostream<<","<<(*itr1)->name;
	}
	ostream<<"."<<endl;
	return ostream;
}





