Exemplo n.º 1
0
	void printNice(boost::test_tools::predicate_result& res,
		const intvector& s, const intvector& diff)
	{
		const char *c = CLR_YELLOW;
		res.message() << c;
		for (int i = 0; i < s.size(); i++) {
			if ((i > 0) && (i % 16 == 0)) {
				res.message() << CLR_NORM << "\n" << std::setfill('0') << std::setw(3)
					<< std::hex << i << ": " << c;
			}
			if ((i >= diff.size()) || (s[i] != diff[i])) {
				if (c != CLR_MAG) {
					c = CLR_MAG;
					res.message() << CLR_MAG;
				}
			} else {
				if (c != CLR_YELLOW) {
					c = CLR_YELLOW;
					res.message() << CLR_YELLOW;
				}
			}
			res.message() << "\\x" << std::setfill('0') << std::setw(2)
				<< std::hex << s[i];
		}
		return;
	}
void SpacePartitioner::markVerCMNL( float param[ 4 ],	 floatvector& ssver, intvector& overlist, intvector& vermark)
{	
	int vernum = overlist.size();

	for( int i = 0; i < vernum; i ++ )
	{
		int veri = overlist[ i ];
		
		if( vermark[ i ] == 0 )	//already marked on, it must be on common edge
		{			
			continue;
		}

		float val = MyMath::dotProduct( param, &ssver[ veri * 3 ]);
		val = val - param[ 3 ] ;

		if( MyMath::isEqualInToler( val, 0,  TOLERANCE_THREE ) )
		{
			vermark[ i ] = 0;
		}
		else if( val > 0 )
			vermark[ i ] = 1;
		else
			vermark[ i  ] = -1;		
	}
}
Exemplo n.º 3
0
	boost::test_tools::predicate_result is_equal(const intvector& expected)
	{
		if (this->result.size() != expected.size()) {
			boost::test_tools::predicate_result res(false);
			this->print_wrong(res, expected, this->result);
			return res;
		}
		intvector::iterator i = this->result.begin();
		for (intvector::const_iterator o = expected.begin(); o != expected.end();
			o++, i++
		) {
			if (*i != *o) {
				boost::test_tools::predicate_result res(false);
				this->print_wrong(res, expected, this->result);
				return res;
			}
		}
		return true;
	}
void ContourHandler::writePlaneCtr
(int planei, floatvector& ctrvers,intvector& vermark,intvector& ctredges   )
{
	char numstr[ 10 ] ;
	itoa( planei + 1, numstr, 10 );
	char fname[ 80 ] ;
	strcpy( fname,  "mmdebug/plane");
	strcat( fname, numstr );
	strcat( fname, ".txt");

	FILE* fout = fopen( fname, "w");

	fprintf(fout, "{");

	//vertex
	fprintf(fout, "{");
	int vernum = ctrvers.size() / 3;
	for( int i = 0; i < vernum; i ++ )
	{
		fprintf(fout, "{%f,%f,%f}", ctrvers[ i*3 ], 
			ctrvers[ 3*i + 1], ctrvers[ 3* i + 2 ]);
		if( i != vernum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "},{");
	}

	//edge
	int edgenum = ctredges.size()/4;
	for( int i = 0; i < edgenum; i ++ )
	{
		fprintf(fout, "{{%d,%d},{%d,%d}}",
			ctredges[ 4*i] + 1, ctredges[ 4*i + 1 ] + 1,
			ctredges[ 4*i + 2 ], ctredges[ 4*i + 3 ]);
		if( i != edgenum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "},{");
	}
	
	//vertex mark
	for( int i = 0; i < vernum; i ++)
	{	
		fprintf(fout, "%d", vermark[ i ]);
		if( i != vernum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "}}");
	}

	fclose( fout );
}
void ContourHandler::writeOneContourOut
(floatvector & ctrvers,
 intvector& ctredges,
 int* ctrvermark,
 intvector interptind,
 int becut,
 int tocut,
 floatvector& param
 )
{
	char fname[ 1024 ];
	strcpy( fname, "mmdebug/becut_");
	char numstr[ 10 ];
	itoa( becut, numstr, 10 );
	strcat(fname, numstr);
	strcat( fname, "_tocut_");
	itoa( tocut, numstr, 10 );
	strcat( fname, numstr);
	strcat( fname, ".txt");

    FILE* fout= fopen( fname, "w")	;
   	
	//write out the vertices
	int vernum = ctrvers.size()/3;
	fprintf(fout, "{{");
	for( int i = 0; i < vernum; i ++ )
	{
		fprintf(fout, "{%f,%f,%f}", ctrvers[ 3*i ], ctrvers[ 3* i + 1], ctrvers[ 3*i + 2]);
		if( i !=vernum - 1)
			fprintf(fout, ",");
		else
			fprintf(fout, "},{");
	}

	//write out the edges
	int edgenum = ctredges.size() /4;
	for( int i = 0; i < edgenum; i ++ )
	{
		fprintf(fout, "{%d,%d}", ctredges[ 4*i ], ctredges[ 4*i + 1]) ;
		if( i != edgenum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "},{");
	}

	//write out the marks
	for( int i = 0; i < vernum; i ++ )
	{
		fprintf(fout, "%d", ctrvermark[ i ]);
		if( i != vernum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "},{");
	}

	//write out the intersection index
	int interptsize = interptind.size();
	for( int i = 0 ;i < interptsize; i++ )
	{
		fprintf(fout, "%d", interptind[ i ]);
		if( i != interptsize - 1 )
			fprintf(fout,",");
		else
			fprintf(fout ,"},{");
	}

	int planenum = param.size()/4;
	for( int i = 0; i < planenum; i ++ )
	{
		fprintf(fout, "{%f,%f,%f,%f}", param[ 4*i ], param[ 4*i+ 1],
			param[ 4*i + 2], param[ 4*i + 3]);
		if( i != planenum - 1 )
			fprintf(fout, ",");
		else
			fprintf(fout, "}}");
	}
	fclose( fout  );
}
void Ctr2SufManager::sortFace(intvector& meshFace,intvector& regface,int*& sregface)
{
	//////////////////////////////////////////////////////////////////////////
//	cout<<"safe 1"<<endl;
	//////////////////////////////////////////////////////////////////////////
	int facen = regface.size();
	if( facen == 1 )
	{
		sregface[ 0 ] = regface[ 0 ];
		return;
	}
	int* vfi[ 3 ];
	for( int i = 0; i < 3; i ++ )
		vfi[ i ] = new int[ facen + 1 ];
	for(int i = 0; i < 3; i ++ )
	{
		for( int j = 0;j <= facen; j ++)
		{
			vfi[ i ][ j ] = -1;
		}
	}

	for( int i = 0; i < facen; i++ )
	{
		int v1 = meshFace[ 5*regface[ i ] ] ;	//first vertex of the edge
		int v2 = meshFace[ 5*regface[ i ] + 1];	//second vertex of the edge
		//find the position for the edge for v1.
		for( int j = 0; j <= facen; j ++ )
		{
			if( vfi[ 0 ][ j ] == -1 )
			{
				vfi[ 0 ][ j ] = v1;	//the vertex index
				vfi[ 1 ][ j ] = i;	//index of the edge starting from this vertex
				break;
			}
			if( vfi[ 0 ][ j ] == v1 )
			{
				vfi[ 1 ][ j ] = i;
				break;
			}
		}
		for( int j= 0; j <= facen; j ++ )
		{
			if( vfi [ 0 ][ j ] == -1 )
			{
				vfi[ 0 ][ j ] = v2;
				vfi[ 2 ][ j ] = i;
				break;
			}
			if( vfi[ 0 ][ j ] == v2 )
			{
				vfi[ 2 ][ j ] = i;
				break;
			}
		}
	}

	//////////////////////////////////////////////////////////////////////////
	//cout<<"safe 2"<<endl;
	//////////////////////////////////////////////////////////////////////////

	//find the starting face
	int startfi = -1;
	int* nexti = new int[ facen ];
	for( int i = 0; i <= facen; i++ )
	{
		if( vfi[ 2 ][ i ] == -1 )	//only one edge, whose head is this vertex
		{
			startfi = vfi[ 1 ][ i ];	//the starting face
			continue;
		}
		nexti[ vfi[ 2 ][ i ]] = vfi[ 1 ][ i ];
	}

////////////////////////////////////////////////////////////////////////
	//cout all the first two vertices of the faces
	//cout the two 3 rows vfi
	//cout<<"face composition........."<<endl;
	//for( int i = 0; i < facen; i++ )
	//{
	//	int v1 = meshFace[ 5*regface[ i ] ] ;	//first vertex of the edge
	//	int v2 = meshFace[ 5*regface[ i ] + 1];	//second vertex of the edge
	//	cout<<"("<<v1<<","<<v2<<")  ";
	//}
	//cout<<endl;
	//cout<<"pre next table..............."<<endl;
	//for( int i = 0; i <= facen; i ++ )
	//{
	//	cout<<vfi[ 0 ][ i ]<<"   ";
	//}
	//cout<<endl;
	//for( int i = 0; i <= facen; i ++ )
	//{
	//	cout<<vfi[ 1 ][ i ]<<"   ";
	//}
	//cout<<endl;
	//for( int i = 0; i <= facen; i ++ )
	//	cout<<vfi[ 2 ][ i ]<<"   ";
	//cout<<endl;

	//cout<<"next for every face........................"<<endl;
	//for( int i = 0; i < facen; i ++ )
	//{
	//	cout<<nexti[ i ]<<"   ";
	//}
	//cout<<endl;
	//cout<<"start fi: "<<startfi<<endl;
	////////////////////////////////////////////////////////////////////////
	sregface[ 0 ] = regface[ startfi ];
	int curfi = startfi;
	for( int i = 1; i < facen; i ++ )
	{
		curfi = nexti[ curfi ];
		sregface[ i ] = regface[ curfi ];
	}

	//////////////////////////////////////////////////////////////////////////	
	/*cout<<"sorted face list........"<<endl;
	for( int i = 0; i < facen; i ++ )
	{
		cout<<sregface[ i ]<<"  ";
	}
	cout<<endl;*/
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	//cout<<"safe 3"<<endl;
	//////////////////////////////////////////////////////////////////////////

	for( int i = 0; i < 3; i ++ )
		delete []vfi[ i ];

	//////////////////////////////////////////////////////////////////////////
//	cout<<"safe 4"<<endl;
	//////////////////////////////////////////////////////////////////////////
}
void Triangulation::triangulate( floatvector& ver2d,
	 vector<intvector>& cycles,
	 intvector& tri_vec	//resulting triangles
	 )
{
	bool getone = false;
	int veri[ 6 ] = {0,0,0,1,0,2};
	intvector::iterator iter;
	vector<intvector>::iterator iter2;

	int cyclehead = cycles[ 0 ][ 0 ];

	//////////////////////////////////////////////////////////////////////////
	/*cout<<"cyclehead:"<<cyclehead<<endl;
	cout<<"cyclehead is:"<<cyclehead<<" cycles number:"<<cycles.size()<<endl;

	for( int i= 0; i < cycles.size(); i++ )
	{
		for( int j = 0;j < cycles[ i ].size(); j ++ )
		{
			cout<<cycles[ i ][ j ]<<", ";
		}
		cout<<endl;
	}*/
	//////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////
	int tcount = 0;
	int tind = 1;
//	writeVerCycle( ver2d, cycles, tind, tind);
	//////////////////////////////////////////////////////////////////////////
	while( cycles[ 0 ].size() != 2 )
	{
		//only one cycle, and it is a triangle!
		if( (cycles.size() == 1) &&(cycles[ 0 ].size() == 3))
		{
			tri_vec.push_back( cycles[ 0 ][ 0 ]);
			tri_vec.push_back( cycles[ 0 ][ 1 ]);
			tri_vec.push_back( cycles[ 0 ][ 2 ]);
			break;
		}

		tcount ++;
		if( tcount == 500000)
		{
		//	cout<<"in not normal exit!"<<endl;
		//	writeVerCycle( ver2d, cycles, 100,100);
			cout<<"Unable to triangulate the current region! Exit anyway! Region information is in vercycle_100_100.txt! "<<endl;
			tri_vec.clear();
			writeVerCycle( ver2d, cycles, 100,100);
			//////////////////////////////////////////////////////////////////////////
			cout<<"cyclehead is:"<<cyclehead<<" cycles number:"<<cycles.size()<<endl;

			for(unsigned int i= 0; i < cycles.size(); i++ )
			{
				for(unsigned int j = 0;j < cycles[ i ].size(); j ++ )
				{
					cout<<cycles[ i ][ j ]<<", ";
				}
				cout<<endl;
			}
			//////////////////////////////////////////////////////////////////////////
			break;
		}
		//////////////////////////////////////////////////////////////////////////

		//////////////////////////////////////////////////////////////////////////
		//writeVerCycle( ver2d, cycles, 1000,1000);
		//////////////////////////////////////////////////////////////////////////
		getone = false;

		//case1 corner can be cut from current cycle
		veri[ 4 ] = 0;
		veri[ 5 ] = 2;
		if( checkTri(ver2d, cycles,veri) )	//ok, current triangle can be cut off!
		{
		//	getone = true;
            
			//remove the triangle from the cycles, and add it into trilist
			tri_vec.push_back( cycles[ veri[ 0 ]][ veri[ 1 ]] );
			tri_vec.push_back( cycles[ veri[ 2 ]][ veri[ 3 ]]);
			tri_vec.push_back( cycles[ veri[ 4 ]][ veri[ 5 ]]);
			
			iter = cycles[ 0 ].begin();
			iter ++;
			cycles[ 0 ].erase( iter );
			//////////////////////////////////////////////////////////////////////////
			tind ++;
//			writeVerCycle( ver2d, cycles, tind, tind);
			//////////////////////////////////////////////////////////////////////////
			cyclehead = cycles[ 0 ][ 0 ];
			continue;	//have already got one triangle, continue
		}

		//case1 not exists, case2 check two vertices of current cycle and one from another triangle
		int cyclenum = cycles.size();
		for( int i = 1; i < cyclenum; i ++ )
		{
	//		cout<<"checking cycle:"<<i<<endl;
			int vnum = cycles[ i ].size();
			for( int j = 0; j < vnum; j ++ )
			{
				veri[ 4 ] = i;
				veri[ 5 ] = j;
				if(	checkTri( ver2d, cycles, veri ))	//current triangle can be cut off
				{
					tri_vec.push_back( cycles[ veri[ 0 ]][ veri[ 1 ]] );
					tri_vec.push_back( cycles[ veri[ 2 ]][ veri[ 3 ]]);
					tri_vec.push_back( cycles[ veri[ 4 ]][ veri[ 5 ]]);

					//change the cycles
					cycles[ 0 ].push_back( cycles[ 0 ][ 0 ]);
					cyclehead = cycles[ 0 ][ 0 ] = cycles[ i ][ j ];
					for( int k = j; k < vnum; k ++ )
						cycles[ 0 ].push_back( cycles[ i ][ k ]);
					for( int k = 0; k < j ; k ++)
					{
						cycles[ 0 ].push_back( cycles[ i ][ k ]);
					}
					iter2 = cycles.begin();
					for( int k = 0; k < i; k++ )
						iter2 ++;					
					cycles.erase( iter2 );
                    getone = true;
					//////////////////////////////////////////////////////////////////////////
					//tind ++;
					//writeVerCycle( ver2d, cycles, tind, tind);
					//////////////////////////////////////////////////////////////////////////
					break;
				}
			}
			if( getone )
				break;
		}

		//otherwise, rotate current cycle
		if( getone )continue;	//has already found one triangle
        //rotate the current cycle
		int v0 = cycles[ 0 ][ 0 ];
		int vnum = cycles[ 0 ].size();
		for( int j = 1; j < vnum; j ++ )
		{
			cycles[ 0 ][ j - 1 ] = cycles[ 0 ][ j ];
		}
        cycles[ 0 ][ vnum - 1 ] = v0;
		//////////////////////////////////////////////////////////////////////////
		//tind ++;
		//writeVerCycle( ver2d, cycles, tind, tind);
		//////////////////////////////////////////////////////////////////////////
		//rotate one loop of the first cycle, still didn't find a good position to cut!
		if( cycles[ 0 ][ 0 ] == cyclehead )
		{
			//////////////////// //////////////////////////////////////////////////////
			/*
			*	This is added later
			*	Now it is only for one cycle region
			*  actually, it can be extended to multiple cycles.
			*  I do not care if two triangles overlap. if apply smoothing, everything will be puffed out
			*/
			if( cycles.size() == 1 )
			{
				int v1 = cycles[ 0 ][ 0 ];
				int vnum = cycles[ 0 ].size() -1;
				for( int i = 1; i < vnum; i ++ )
				{
					tri_vec.push_back( v1 );
					tri_vec.push_back( cycles[ 0][ i ] );
					tri_vec.push_back( cycles[ 0][ i + 1 ]);
				}
				return;
			}
		}
	}
}
    SatelliteProblemDomainGenerator(int n_sat, int n_inst_type, int n_ant_type, int n_gs, int n_tw)
    : num_satellites(n_sat)
    , num_ground_statiion(n_gs)
    , num_antenna_types(n_ant_type)
    , num_instrument_types(n_inst_type)
    , num_timewindows(n_tw)
    , instrument_max_on_time(80)
    , instrument_min_off_time(5)
    {
        if (num_antenna_types < 1)
            num_antenna_types = 1;
        if (num_instrument_types < 1)
            num_instrument_types = 1;

        srand(time(NULL));


        for (int i = 0; i < num_antenna_types; i++)
        {
            ant_rate.push_back(get_rand_num(2, 5));
            ant_bat_rate.push_back(get_rand_num(2, 5));
            ant_angular_speed.push_back(get_rand_num(5, 10));
            ant_gs_map.push_back(intvector(num_ground_statiion, 0));
            ant_sat_map.push_back(intvector(num_satellites, 0));

            antennaTotal.insert(antennaTotal.end(), i);
        }
        //std::cout << "Antenna Total Size = " << antennaTotal.size() << std::endl;
        for (int i = 0; i < num_instrument_types; i++)
        {
            inst_rate.push_back(get_rand_num(3, 8));
            inst_bat_rate.push_back(get_rand_num(3, 8));
            inst_angular_speed.push_back(get_rand_num(5, 10));
            inst_sat_map.push_back(intvector(num_satellites, 0));

            instrumentTotal.insert(instrumentTotal.end(), i);
        }

        for (int i = 0; i < num_satellites; i++)
        {
            sat_unit_recharge.push_back(get_rand_num(15, 20));
            sat_storage_total.push_back(get_rand_num(150, 200));
            sat_battery_total.push_back(get_rand_num(350, 500));

            satellite_sun_visibility.push_back(std::vector<intpair>());
            int start = get_rand_num(0, 100);
            int length = get_rand_num(20, 30);
            for (int j = 0; j < num_timewindows; j++)
            {
                satellite_sun_visibility[i].push_back(std::make_pair<int, int>(start, start + length));
                start = start + length + 40;
            }

            /*
             * Each Satellite must support at least 2 instrument types
             */
            int instrumentNumber = get_rand_num(1, num_instrument_types);
            intset instsize = instrumentTotal;
            while (instrumentNumber > 0)
            {
                int selected = get_rand_num(0, instsize.size() - 1);
                intset::iterator itr = instsize.begin();
                int count = 0;
                while (itr != instsize.end())
                {
                    if (count == selected)
                    {
                        inst_sat_map[*itr][i] = 1;
                        //std::cout << "Satellite " << i << " will have instrument " << *itr << " = " << inst_sat_map[*itr][i] << std::endl;
                        instsize.erase(itr);
                        instrumentNumber--;
                        break;
                    }
                    itr++;
                    count++;
                }

            }


            /*
             * Each Satellite must support at least 2 antenna types;
             */
            int antNumber = get_rand_num(1, num_antenna_types);
            intset antsize = antennaTotal;
            while (antNumber > 0)
            {
                int selected = get_rand_num(0, antsize.size() - 1);
                intset::iterator itr = antsize.begin();
                int count = 0;
                while (itr != antsize.end())
                {
                    if (count == selected)
                    {
                        ant_sat_map[*itr][i] = 1;
                        //std::cout << "Satellite " << i << " will have antenna " << *itr << " = " << ant_sat_map[*itr][i] << std::endl;
                        antsize.erase(itr);
                        antNumber--;
                        break;
                    }
                    itr++;
                    count++;
                }

            }


            satellite_groundstation_visibility.push_back(std::vector< std::vector<intpair> >());
            for (int j = 0; j < num_ground_statiion; j++)
            {
                satellite_groundstation_visibility[i].push_back(std::vector<intpair>());
                int start = get_rand_num(0, 100);
                int length = get_rand_num(20, 30);
                for (int k = 0; k < num_timewindows; k++)
                {
                    satellite_groundstation_visibility[i][j].push_back(std::make_pair<int, int>(start, start + length));
                    start = start + length + 60;
                }
            }
        }


        for (int i = 0; i < num_ground_statiion; i++)
        {
            gs_angular_distance.push_back(intvector());
            for (int j = 0; j < num_ground_statiion; j++)
            {
                gs_angular_distance[i].push_back(0);
                if (i != j)
                {
                    gs_angular_distance[i][j] = get_manhattan_dist(get_rand_num(0, 100), get_rand_num(0, 100), get_rand_num(0, 100), get_rand_num(0, 100));
                }
            }

            /*
             * Each Ground Station must support at least 1 antenna type
             */
            int antNumber = get_rand_num(1, num_antenna_types);
            intset antsize = antennaTotal;
            while (antNumber > 0)
            {
                int selected = get_rand_num(0, antsize.size() - 1);
                intset::iterator itr = antsize.begin();
                int count = 0;
                while (itr != antsize.end())
                {
                    if (count == selected)
                    {
                        ant_gs_map[*itr][i] = 1;
                        //std::cout << "Ground Station " << i << " will have antenna " << *itr << " = " << ant_gs_map[*itr][i] << std::endl;
                        antsize.erase(itr);
                        antNumber--;
                        break;
                    }
                    itr++;
                    count++;
                }

            }
        }

        domain_name << "Sat-" << n_sat << "-GS-" << n_gs << "-Inst-" << n_inst_type << "-Ant-" << n_ant_type;
    }
    SatelliteProblemInstanceGenerator(int id, int n_obs, SatelliteProblemDomainGenerator* domain)
    : instance_id(id)
    , num_observations(n_obs)
    , domain(domain)
    {
        //srand(time(NULL));
        //num_observations = get_rand_num()
        for (int i = 0; i < num_observations; i++)
        {
            observations_inst_map.push_back(intvector(domain->num_instrument_types, 0));

            /*
             * Each Observation must support at least 2 instrument types
             */
            int instrumentNumber = get_rand_num(1, std::min(domain->num_instrument_types, 2));
            intset instsize = domain->instrumentTotal;
            while (instrumentNumber > 0)
            {
                int selected = get_rand_num(0, instsize.size() - 1);
                intset::iterator itr = instsize.begin();
                int count = 0;
                while (itr != instsize.end())
                {
                    if (count == selected)
                    {
                        observations_inst_map[i][*itr] = 1;
                        //std::cout << "Observation " << i << " will have instrument " << *itr << " = " << observations_inst_map[i][*itr] << std::endl;
                        instsize.erase(itr);
                        instrumentNumber--;
                        break;
                    }
                    itr++;
                    count++;
                }

            }


            observation_size.push_back(get_rand_num(30, 50));

            //srand(time(NULL));
            //for (int i = 0; i < num_observations; i++)
            {
                observation_satellite_time_windows.push_back(std::vector< std::vector<intpair> >());
                for (int j = 0; j < domain->num_satellites; j++)
                {
                    observation_satellite_time_windows[i].push_back(std::vector<intpair>());
                    int start = get_rand_num(0, 100);
                    int length = get_rand_num(20, 30);
                    for (int k = 0; k < domain->num_timewindows; k++)
                    {
                        observation_satellite_time_windows[i][j].push_back(std::make_pair<int, int>(start, start + length));
                        start = start + length + 60;
                    }
                }
            }
            //srand(time(NULL));
            //for (int i = 0; i < num_observations; i++)
            {
                observations_angualr_distances.push_back(intvector());
                for (int j = 0; j < num_observations; j++)
                {
                    observations_angualr_distances[i].push_back(0);
                    if (i != j)
                    {
                        observations_angualr_distances[i][j] = get_manhattan_dist(get_rand_num(0, 100), get_rand_num(0, 100), get_rand_num(0, 100), get_rand_num(0, 100));
                    }
                }
            }
        }

        instance_name << "ID-" << instance_id << "-Observations-" << num_observations;
    }
void SpacePartitioner::splitSubspaceCMNL
(
 int planei,
 int spacei,
 bool above,		//true - push the half one above the plane at the end, false- the one below at the end
 vector<intvector>& ssspace,  
 vector<intvector>& ssspace_planeside,
 vector<intvector>& ssface,
intvector& ssface_planeindex,
 intvector& facemark, intvector& faceval
 )
{
	//divide the faces in the subspace into two groups
	intvector abovefaces;	//the faces above the plane
	intvector abovefacesides;
	intvector belowfaces;	//the faces below the plane
	intvector belowfacesides;
	intvector interedges;	//intersection edge list

	int facenum = ssspace[ spacei ].size();
	for(int i = 0; i < facenum; i ++ )
	{
		int oldfacei = ssspace[ spacei ][ i ];
		int planeside = ssspace_planeside[ spacei ][ i ];
		switch( facemark[ i ] )
		{
		case FACE_INTER:	//faceval saves the below half face
			{
				abovefaces.push_back( oldfacei );
				abovefacesides.push_back( planeside );
				belowfaces.push_back( faceval[ i ]);
				belowfacesides.push_back( planeside );
                
				int faceedgenum = ssface[ oldfacei ].size();
				interedges.push_back( ssface[ oldfacei ][ faceedgenum - 1] );
			}
			break;
		case FACE_NOINTER:	//faceval saves 1/-1 above or below
			{
				if( faceval[ i ] == 1 )
				{
					abovefaces.push_back( oldfacei );
					abovefacesides.push_back( planeside );
				}
				else
				{
					belowfaces.push_back( oldfacei );
					belowfacesides.push_back( planeside );
				}
			}
			break;
		case FACE_TOUCH_ABOVE:	//faeeval saves the touch edge index
			{
				abovefaces.push_back( oldfacei );
				abovefacesides.push_back( planeside );
				interedges.push_back( faceval[ i ]);
			}			
			break;
		case FACE_TOUCH_BELOW:	
			{
				belowfaces.push_back( oldfacei);
				belowfacesides.push_back( planeside );

				//if this exists, there must exist another face, which is the case above
				//no need to do the following operation.
			//	interedges.push_back( faceval[ i ]);
			}
			break;
		}
	}

	//////////////////////////////////////////////////////////////////////////	
	if( interedges.size() == 0 )	//this should not have happened
	{
		cout<<"Wasn't able to find the intersection edges!"<<endl;
		intvector tvec;
		ssspace.push_back( tvec );
		return;
	}
	//////////////////////////////////////////////////////////////////////////

	//split current subspace into two	
	facenum = ssface.size();
	ssface.push_back( interedges );
	ssface_planeindex.push_back( planei );
	abovefaces.push_back( facenum );
	belowfaces.push_back( facenum );
	abovefacesides.push_back( 1 );
	belowfacesides.push_back ( 0 );

	if( above )
	{
		ssspace.push_back( abovefaces );
		//ssspace[ spacei ].clear();
		int belowfacenum = belowfaces.size();
		ssspace[ spacei ].resize( belowfacenum );		
        memcpy(&ssspace[ spacei ][ 0 ], &belowfaces[ 0 ], sizeof( int ) * belowfacenum );		

		ssspace_planeside.push_back( abovefacesides );
		//ssspace_planeside[ spacei ].clear();
		ssspace_planeside[ spacei ].resize( belowfacenum );
		memcpy(&ssspace_planeside[ spacei ][ 0 ], 
			&belowfacesides[ 0 ], sizeof(int) * belowfacenum );

	}
	else
	{
		ssspace.push_back( belowfaces );
		//ssspace[ spacei ].clear();
		int abovefacenum = abovefaces.size();
		ssspace[ spacei ].resize( abovefacenum );
		memcpy(&ssspace[ spacei ][ 0 ], &abovefaces[ 0 ], sizeof( int ) * abovefacenum );

		ssspace_planeside.push_back( belowfacesides );
		//ssspace_planeside[ spacei ].clear();
		ssspace_planeside[ spacei ].resize( abovefacenum );
		memcpy(&ssspace_planeside[ spacei ][ 0 ], 
			&abovefacesides[ 0 ], sizeof(int) * abovefacenum );
	}

	abovefaces.clear();
	belowfaces.clear();
	interedges.clear();
	abovefacesides.clear();
	belowfacesides.clear();
}
void SpacePartitioner::splitFaceCMNL
(
 //int planei,
 int spacei, vector<intvector>& ssspace, 
 vector<intvector>& ssface,	//all the faces
 intvector& ssface_planeindex,
 vector<intvector>& nssface,
 intvector& ssedge,
 intvector& oedgelist, 
 intvector& edgemark, intvector& edgeval,

 intvector& facemark, intvector& faceval
 )
{
	int ssfacenum = ssspace[ spacei ].size();
	int facenum = ssface.size();
	int ssedgenum = ssedge.size()/2;

	facemark.resize(ssfacenum );
	faceval.resize( ssfacenum );

	//go through the faces, split it when necessary
	for( int i = 0; i < ssfacenum; i ++ )
	{
		int facei = ssspace[ spacei ][ i ];
		
		int oldfaceedgenum = nssface[ i ].size();

		intvector aboveedges;
		intvector belowedges;
		intvector interpts;

		//if not -1, it is the index of the subspace edge on this face
		//which the plane crosses
		int touchface = -1;	
		int above = 0;	//1 - above, -1 - below, 0 - not decided
		//divide the edges of the face into two groups.
		for( int j = 0; j < oldfaceedgenum; j ++ )
		{
			int edgei = nssface[ i ][ j ];	//the new edge index, in oedgelist
			int oldedgei = ssface[ facei ][ j ];	//the old edge index in ssedge
			switch( edgemark[ edgei ])
			{
			case EDGE_INTERSECT:
				{
					aboveedges.push_back( oldedgei  );
					belowedges.push_back( edgeval[ edgei ]);

					interpts.push_back( ssedge[ 2*oldedgei + 1 ] );
				}
				break;
			case EDGE_NOINTERSECT:
				{
					if( edgeval[ edgei ] == 1 )
					{
						aboveedges.push_back( oldedgei );
						above = 1;
					}
					else
					{
						belowedges.push_back( oldedgei );
						above = -1;
					}
				}
				break;
			case EDGE_TOUCHEDGE:
				{
					touchface = oldedgei;	//one edge on the face is on the plane!
					break;
				}
				break;
			case EDGE_TOUCHONEVER_ABOVE:
				{
					interpts.push_back( ssedge[ 2*oldedgei + edgeval[ edgei ]]);
					aboveedges.push_back( oldedgei );
					above = 1;
				}
				break;
			case EDGE_TOUCHONEVER_BELOW:
				{
					interpts.push_back( ssedge[ 2*oldedgei + edgeval[ edgei ]]);
					belowedges.push_back( oldedgei );
					above = -1;
				}
				break;
			}
		}

		if( touchface != -1 )	//the plane crosses one edge on the face
		{
			if( above == 0)	//not decided yet, could only happen when the first 
				//edge is the one lying on the plane
			{
				int tedgei = nssface[ i ][ 1 ];
				if( edgemark[ tedgei ] == EDGE_TOUCHONEVER_ABOVE )
				{
					above = 1;
				}
				else if ( edgemark[ tedgei ] == EDGE_TOUCHONEVER_BELOW )
				{
					above = -1;
				}
				else
				{
					cout<<"EDGE_TOUCHONEVER_.... is expected!! "<<endl;
					above = 1;
				}
			}
			if( above == 1 )
				facemark[ i ] = FACE_TOUCH_ABOVE;
			else
				facemark[ i ] = FACE_TOUCH_BELOW;
			faceval[ i ] = touchface;	//the subspace edge it crosses
		}
		else if( interpts.size() <= 1 )	//the face doesn't intersect with the plane
		{
			facemark[ i ] = FACE_NOINTER;
			if( aboveedges.size() == 0 )	//below
			{
				faceval[ i ] = -1;	//below
			}
			else
				faceval[ i ] = 1;	//above
		}
		else	//intersect!
		{
			facemark[ i ] = FACE_INTER;
			faceval[ i ] = facenum;	//the position of the second half of the face

			//find the two intersection points
			int twointerpts[ 2 ];
			twointerpts[ 0 ] = interpts[ 0 ];
			if( interpts.size() >= 2)
			{
				for(unsigned int k = 1; k < interpts.size(); k ++)
				{
					if( interpts[ k ] != twointerpts[ 0 ])
					{
						twointerpts[ 1 ] = interpts[ k ];
						break;
					}
				}
			}

			//split the face
			//ssedge, ssface
			ssedge.push_back( twointerpts[ 0 ]);
			ssedge.push_back( twointerpts[ 1 ]);
			aboveedges.push_back( ssedgenum );
			belowedges.push_back ( ssedgenum );
			
			ssface.push_back( belowedges );
			ssface[ facei ].clear();
			ssface[ facei ].resize( aboveedges.size());
			memcpy( &ssface[ facei ][ 0 ], &aboveedges[ 0 ], sizeof( int ) * aboveedges.size());			

			ssface_planeindex.push_back( ssface_planeindex[ facei ] );

			ssedgenum ++;            
			facenum ++;
		}

		aboveedges.clear();
		belowedges.clear();
		interpts.clear();
	}

}
//split the edges
void SpacePartitioner::splitEdgeCMNL
(
 float param[ 4 ],		//parameter of the plane

 floatvector& ssver,		//vertices positions
 intvector& ssedge,			//the original edge list
 intvector& oedgelist,		//the edges in current subspace
 intvector& nssedge,		//the edges composed of new vertices index
 intvector& overlist,		//vertices that are in current subspace
 intvector& vermark,			//vertex mark of the vertices

 intvector& edgetype,		//mark the edge type of the old edge list
 intvector& edgeval			//mark the edge value of the old edge list
)
{	
	int ssvernum = ssver.size()/3;
	int ssedgenum = ssedge.size()/2;

	int oldvernum = overlist.size();	//before splitting, vertex number
	int oldedgenum = oedgelist.size();	//before splitting, edge number
	
	edgetype.resize( oldedgenum );
	edgeval.resize( oldedgenum );

	int nveris[ 2 ];
	int overis[ 2 ];
	int vermark1, vermark2;
	float interpt[ 3 ];
	for(int i = 0; i < oldedgenum; i ++ )
	{
		int edgei = oedgelist[ i ];

		nveris[ 0 ] = nssedge[ 2*i ];
		nveris[ 1 ] = nssedge[ 2*i + 1 ];

		//above the plane	1 & 1		
		//below the plane	-1 & -1
		//touch one vertex  0 & whatever or whatever & 0
		//edge on the plane	0 & 0
		//edge intersects with the plane 1 & -1
		vermark1 = vermark[ nveris[ 0 ]];
		vermark2 = vermark[ nveris[ 1 ]];

		if( vermark1 == 0 )
		{
			if( vermark2 == 0 )
			{
				edgetype[ i ] = EDGE_TOUCHEDGE;
				edgeval[ i ] = 0;				
			}
			else
			{
				if( vermark2 == 1 )
					edgetype[ i ] = EDGE_TOUCHONEVER_ABOVE;
				else
					 edgetype[ i ] = EDGE_TOUCHONEVER_BELOW;
				edgeval[ i ] = 0;
			}
			continue;
		}
		
		//the first vertex is not on the plane
		if( vermark2 == 0 )	//the second one is on, but the first one is not!
		{
			if( vermark1 == 1 )
				edgetype[ i ] = EDGE_TOUCHONEVER_ABOVE;
			else
				edgetype[ i ] = EDGE_TOUCHONEVER_BELOW;
			edgeval[ i ] = 1;			
			continue;
		}

		//both of them are not 0!
		if( vermark1 * vermark2 == 1 )	//the are of the same sign
		{
			edgetype[ i ] = EDGE_NOINTERSECT;	//no intersection
			edgeval[ i ] = vermark1;
			continue;
		}

		//edge and plane intersect
		//ssver, ssedge, edgetype, edgeval
		//if vermark1 = -1, change the sequence of the vertices in the edge
		if( vermark1 == - 1)
		{
			//change the vertices of the edge
			int tval = ssedge[ 2 * edgei  ];
			ssedge[ 2 *edgei ] = ssedge[ 2*edgei + 1 ];
			ssedge[ 2*edgei + 1 ] = tval;		
		}

		//compute the intersection point
		edgetype[ i ] = EDGE_INTERSECT;
		edgeval[ i ] = ssedgenum;

		overis[ 0 ] = overlist[ nveris [ 0 ]] ;
		overis[ 1 ] = overlist[ nveris[ 1 ]];
		float tvals[ 2 ] ;
		for( int j = 0; j < 2; j ++ )
		{
			tvals[ j ] = MyMath::dotProduct( param, &ssver[ 3*overis[ j ]]);
			tvals[ j ] = tvals[ j ] - param[ 3 ];
		}
		MyMath::getPtOnSeg(&ssver[ 3*overis[ 0 ]], &ssver[ 3*overis[ 1 ]], tvals[ 0 ]/(tvals[ 0 ] - tvals[1]),
			interpt);

		ssver.push_back( interpt[ 0 ]);
		ssver.push_back( interpt[ 1 ]);
		ssver.push_back( interpt[ 2 ]);

		ssedge.resize( 2*ssedgenum + 2);
        memcpy( &ssedge[ 2*ssedgenum ], &ssedge[ 2*edgei ], sizeof( int ) * 2);

		ssedge[ 2*edgei + 1 ] = ssvernum;
		ssedge[2*ssedgenum ] = ssvernum;

		ssvernum ++;
		ssedgenum ++;
	}
}
void SpacePartitioner::mapOneSubspaceCMNL
(  int spacei, intvector& ssedge,int& comnedge,
 vector<intvector>&ssface, vector<intvector>& ssspace,
 //reset the edges in the face, index starts from 0 and condensed
 vector<intvector>& nssface,  intvector& oedgelist,
 intvector& nssedge, intvector&overlist, //reset vertex in edgelist
	int& ncomnedge
 )
{
	//go through the face in the subspace
	int facenum = ssspace[ spacei ].size();
	nssface.resize( facenum );
	for( int i = 0; i < facenum; i ++ )
	{
		int facei = ssspace[ spacei ][ i ];
		int fedgenum = ssface[ facei ].size();
		nssface[ i ].resize( fedgenum );
		
		//set nssface
		for( int j = 0; j < fedgenum; j ++ )
		{
			int edgei = ssface[ facei ][ j ];
			
			//trying find in the oedgelist
			int oedgelistsize = oedgelist.size();
			bool findind = false;
			for(int k = 0; k < oedgelistsize; k ++ )
			{
				if( oedgelist[ k ] == edgei )
				{
					findind = true;
					nssface[ i ][ j ] = k;	//has already been found before
					break;
				}
			}
			if( !findind )	//an old edge hasn't been seen before
			{
				oedgelist.push_back( edgei );
				nssface[ i ][ j ] = oedgelistsize;
			}	
		}
	}

	//go through the edges in this subspace
	int oedgelistsize = oedgelist.size();
	nssedge.resize( oedgelistsize * 2 );

	for( int i = 0; i < oedgelistsize; i ++ )
	{
		int edgei = oedgelist[ i ];
		int vers[ 2 ] = {ssedge[ 2*edgei], ssedge[ 2*edgei + 1]};

		//go through the overlist to see if they are old vertice not 
		//seen before or not
		int overlistsize = overlist.size();
		for( int j = 0; j < 2; j ++ )	//for these two vertices
		{
			int veri = vers[ j ];
			bool found = false;
			for( int k = 0; k < overlistsize; k ++ )
			{
				if( overlist[ k ] == veri )
				{
					found = true;
					nssedge[ 2*i + j ] = k;
					break;
				}			
			}
			if( !found)
			{
				overlist.push_back( veri );
				nssedge[ 2*i + j ] = overlistsize;
				overlistsize ++;
			}
		}
	}

	//set the ncomnedge
	oedgelistsize = oedgelist.size();
	for( int i = 0; i < oedgelistsize; i ++ )
	{
		if (  oedgelist[ i ] == comnedge )
		{
			ncomnedge = i;
			break;
		}
	}
}