예제 #1
0
std::string get_root_uuid() {
  using tchar_str = std::basic_string<TCHAR>;
  string uuid;
  TCHAR buf[max_drive_name];      // temporary buffer for volume name
  tchar_str drive = TEXT("c:\\"); // string "template" for drive specifier
  // walk through legal drive letters, skipping floppies
  for (TCHAR i = TEXT('c'); i < TEXT('z'); i++) {
    // Stamp the drive for the appropriate letter.
    drive[0] = i;
    if (GetVolumeNameForVolumeMountPoint(drive.c_str(), buf, max_drive_name)) {
      tchar_str drive_name = buf;
      auto first = drive_name.find(TEXT("Volume{"));
      if (first != std::string::npos) {
        first += 7;
        auto last = drive_name.find(TEXT("}"), first);
        if (last != std::string::npos && last > first) {
          mv(uuid, drive_name.substr(first, last - first));
          // UUIDs are formatted as 8-4-4-4-12 hex digits groups
          auto cpy = uuid;
          replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
          // discard invalid UUID
          if (cpy != uuid_format)
            uuid.clear();
          else
            return uuid; // return first valid UUID we get
        }
      }
    }
  }
  return uuid;
}
예제 #2
0
std::string get_root_uuid() {
  string uuid;
  ifstream fs;
  fs.open("/etc/fstab", std::ios_base::in);
  columns_iterator end;
  auto i = find_if(columns_iterator{&fs}, end, [](const vector<string>& cols) {
    return cols.size() == 6 && cols[1] == "/";
  });
  if (i != end) {
    uuid = move((*i)[0]);
    const char cstr[] = {"UUID="};
    auto slen = sizeof(cstr) - 1;
    if (uuid.compare(0, slen, cstr) == 0) {
      uuid.erase(0, slen);
    }
    // UUIDs are formatted as 8-4-4-4-12 hex digits groups
    auto cpy = uuid;
    replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
    // discard invalid UUID
    if (cpy != uuid_format) {
      uuid.clear();
    }
    // "\\?\Volume{5ec70abf-058c-11e1-bdda-806e6f6e6963}\"
  }
  return uuid;
}
예제 #3
0
void pure_numeric_algo(){
    cout<<endl<<"pure_numeric_algo :"<<endl;
    int ia[11] = {0, 1, 2, 3, 4, 5, 6,6,6, 7, 8 };
    vector<int> iv(ia,ia+11);	vector<int> iv2(ia+6,ia+8);	vector<int>::iterator itr;
    itr = adjacent_find(iv.begin(),iv.end(), equal_to<int>());	//找到相邻元素相等的第一个元素
    cout<<"adjacent_find: "<<*itr<<endl;
    cout<<"count: "<<count(iv.begin(),iv.end(), 6)<<endl;	//找到元素值等于6的个数
    cout<<"count_if: "<<count_if(iv.begin(),iv.end(), bind2nd(less<int>() , 7))<<endl;		//找到小于7的元素个数
    itr = find(iv.begin(),iv.end(), 4);				//找到元素等于4的第一个元素位置
    cout<<"find: "<<*itr<<endl;
    itr = find_if(iv.begin(),iv.end(), bind2nd(greater<int>() , 2));				//找到元素大于2的第一个元素位置
    cout<<"find_if: "<<*itr<<endl;
    itr = find_end(iv.begin(),iv.end(), iv2.begin(),iv2.end());				//找到iv序列中最后子序列匹配出现的位置
    cout<<"find_end: "<<*(itr+3)<<endl;
    itr = find_first_of(iv.begin(),iv.end(), iv2.begin(),iv2.end());			//找到iv序列中最先子序列匹配出现的位置
    cout<<"find_end: "<<*(itr+3)<<endl;
    remove(iv.begin(),iv.end(), 6);				//删除元素,向前移,但是容器size不变,后面会剩余数据
    cout<<"remove: "<<iv<<endl;
    vector<int> iv3(12,-1);
    remove_copy(iv.begin(),iv.end(), iv3.begin(), 6);	//删除元素,将数据拷贝到新容器,后面会剩余数据
    cout<<"remove_copy: "<<iv3<<endl;
    remove_if(iv.begin(),iv.end(), bind2nd(less<int>(), 6));	//删除小于6的元素,后面会剩余数据
    cout<<"remove_if: "<<iv<<endl;
    remove_copy_if(iv.begin(),iv.end(), iv3.begin(), bind2nd(less<int>(), 7));		//删除小于7的元素,并拷贝到新容器
    cout<<"remove_copy_if: "<<iv3<<endl;
    replace(iv.begin(),iv.end(), 6, 3);			//将所有元素值为6的改为3
    cout<<"replace: "<<iv<<endl;
    replace_copy(iv.begin(),iv.end(),iv3.begin(), 3, 5);			//将所有元素值为3的改为5,结果保存在新容器中
    cout<<"replace_copy: "<<iv3<<endl;
    replace_if(iv.begin(),iv.end(), bind2nd(less<int>(),5), 2);			//将所有元素值小于5的改为2
    cout<<"replace_if: "<<iv<<endl;
    replace_copy_if(iv.begin(),iv.end(),iv3.begin(), bind2nd(equal_to<int>(),8), 9);			//将所有元素值为8的改为9,结果保存在新容器中
    cout<<"replace_copy_if: "<<iv3<<endl;
    reverse(iv.begin(),iv.end());			cout<<"reverse: "<<iv<<endl;		//反转
    reverse_copy(iv.begin(),iv.end(),iv3.begin());		cout<<"reverse_copy: "<<iv3<<endl;	//反转,结果保存在新容器
    rotate(iv.begin(),iv.begin() + 4, iv.end());	cout<<"rotate: "<<iv<<endl;			//互换元素
    rotate_copy(iv.begin(),iv.begin() + 5,iv.end(),iv3.begin());		cout<<"rotate_copy: "<<iv3<<endl;	//互换元素,结果保存在新容器
    int ia2[] = {2, 8};		vector<int> iv4(ia2,ia2+2);
    cout<<"search:  "<<*search(iv.begin(),iv.end(),iv4.begin(),iv4.end())<<endl;		//查找子序列出现的第一次出现地点
    swap_ranges(iv4.begin(),iv4.end(),iv.begin());				//按区域交换
    cout<<"swap_ranges:  "<<iv<<endl<<iv4<<endl;
    transform(iv.begin(),iv.end(),iv.begin(),bind2nd(minus<int>(), 2));		//所有元素减2
    cout<<"transform:  "<<iv<<endl;
    transform(iv4.begin(),iv4.end(),iv.begin(),iv4.begin(),plus<int>());		//区间对应元素相加
    cout<<"transform:  "<<iv4<<endl;
    /************************************************************************/
    vector<int> iv5(ia,ia+11);	vector<int> iv6(ia+4,ia+8);	vector<int> iv7(15);
    cout<<"max_element:  "<<*max_element(iv5.begin(), iv5.end())<<endl;		//最大元素游标
    cout<<"min_element:  "<<*min_element(iv5.begin(), iv5.end())<<endl;
    cout<<"includes:  "<<includes(iv5.begin(),iv5.end(),iv6.begin(),iv6.end())<<endl;	//iv6中元素是不是都在iv5中,这两个必须排过序
    merge(iv5.begin(),iv5.end(),iv6.begin(),iv6.end(),iv7.begin());	//两个排序号的容器合并
    cout<<"merge:  "<<iv7<<endl;
    partition(iv7.begin(),iv7.end(),bind2nd(equal_to<int>(), 5));	//满足条件的放在左边,不满足条件的放在右边
    cout<<"partition:  "<<iv7<<endl;
    unique(iv5.begin(),iv5.end());				//去重,重复的元素放在后面
    cout<<"unique:  "<<iv5<<endl;
    unique_copy(iv5.begin(),iv5.end(),iv7.begin());				//去重,结果保存在新容器
    cout<<"unique_copy:  "<<iv7<<endl;
}
예제 #4
0
 typename util::detail::algorithm_result<
     ExPolicy, typename traits::range_traits<Rng>::iterator_type
 >::type
 replace_if(ExPolicy && policy, Rng && rng, F && f, T const& new_value,
     Proj && proj = Proj())
 {
     return replace_if(std::forward<ExPolicy>(policy),
         boost::begin(rng), boost::end(rng),
         std::forward<F>(f), new_value, std::forward<Proj>(proj));
 }
예제 #5
0
int main()
{
	int new_value = 0;
		
	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
	vector< int, allocator > vec( ia, ia+10 );
        ostream_iterator< int >  ofile( cout, " " );

        cout << "original element sequence:\n";
        copy( ia, ia+10, ofile ); cout << '\n';

	replace_if( &ia[0], &ia[10], 
		    bind2nd(less<int>(),10), new_value );
		
        cout << "sequence after applying replace_if < 10 with 0:\n";
        copy( ia, ia+10, ofile ); cout << '\n';

	replace_if( vec.begin(), vec.end(), EvenValue(), new_value );

        cout << "sequence after applying replace_if even with 0:\n";
        copy( vec.begin(), vec.end(), ofile ); cout << '\n';
}
예제 #6
0
int algorithms()
{
  vector<Person> people{ { "John", 27 }, { "Chris", 24 }, { "Ann", 31 } };

  auto print_all = [&]()
  {
    cout << people.size() << " persons:" << endl;
    for_each(begin(people), end(people), [](const Person& p) { cout << p << endl; });
  };
  print_all();

  // find out who is oldest
  auto oldest = *max_element(people.begin(), people.end(),
    [](const Person& a, const Person& b)
  {
    return a.name < b.name;
  });
  cout << oldest.name << " is the oldest" << endl;
  
  // let's find john
  auto john = find_if(people.begin(), people.end(), [](const Person& p)
  {
    return p.name == string("John"); // change to Jill
  });
  if (john != people.end())
    cout << "Found " << john->name << " who is " << john->age << endl;

  // number of people younger than 
  auto youngerThan30 = count_if(people.begin(), people.end(),
    [](const Person& p) {return p.age < 30; });
  cout << "Found " << youngerThan30 << " people younger than 30." << endl;

  // sort by age
  sort(people.begin(), people.end(), 
    [](const Person& a, const Person& b)
  {
    return a.age < b.age;
  });
  cout << "People sorted by age:" << endl;
  print_all();

  // replace john with jill
  Person jill{ "Jill", 44 };
  replace_if(people.begin(), people.end(),
    [](const Person& p) -> bool { return p.name == "John"; },
    jill);
  print_all();

  getchar();
  return 0;
}
예제 #7
0
int main ()
{
  vector <int> v1 (10);
  int i;
  for (i = 0; i < v1.size (); i++)
  {
    v1[i] = i % 5;
    cout << v1[i] << ' ';
  }
  cout << endl;
  replace_if (v1.begin (), v1.end (), odd, 42);
  for (i = 0; i < v1.size (); i++)
    cout << v1[i] << ' ';
  cout << endl;
  return 0;
}
예제 #8
0
void WordSearch::read_words(const string &file_name)
{
    ifstream txt (file_name); /* file is aumatically open */

    string one_line;

    int line = 1;
    string prev = "";

    while (getline(txt, one_line)) {
        /* change to lowercase */
        transform(one_line.begin(), one_line.end(), one_line.begin(), ::tolower);

        /* replace non-alpha with a space */
        replace_if (one_line.begin(), one_line.end(),
        	[] (const char c) {
        	return !isalpha(c);
        }, ' ');
        istringstream tokens{one_line};
        string word;
        while (tokens >> word) {
            if (word.length() < 3) continue;
            if (ignored_words.find(word) == ignored_words.end()) {

                wordCount++;
                lengthMap[word.length()].insert(word);
		wordFrequency[word]++;
		wordFileMap[word].insert(file_name);

		if (prev != "") {
			predictWord[prev][word]++;
		}
                prev = word;

            }
        }
        line++;
    }
    txt.close(); /* close the file */

	for (auto iter = wordFrequency.begin(); iter != wordFrequency.end();iter++){
		leastFrequent[iter->second].insert(iter->first);
	}
}
예제 #9
0
std::string get_root_uuid() {
    char          buf[1024] = {0};
    struct ifconf ifc = {0};
    struct ifreq *ifr = NULL;
    int           sck = 0;
    int           nInterfaces = 0;

    // Get a socket handle.
    sck = socket(AF_INET, SOCK_DGRAM, 0);
    if(sck < 0) {
        perror("socket");
        return "";
    }

    // Query available interfaces.
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
        perror("ioctl(SIOCGIFCONF)");
        return "";
    }

    vector<string> hw_addresses;
    auto ctoi = [](char c) -> unsigned {
        return static_cast<unsigned char>(c);
    };
    // Iterate through the list of interfaces.
    ifr = ifc.ifc_req;
    nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
    for(int i = 0; i < nInterfaces; i++) {
        struct ifreq *item = &ifr[i];
        // Get the MAC address
        if(ioctl(sck, SIOCGIFHWADDR, item) < 0) {
            perror("ioctl(SIOCGIFHWADDR)");
            return "";
        }
        std::ostringstream oss;
        oss << hex;
        oss.width(2);
        oss << ctoi(item->ifr_hwaddr.sa_data[0]);
        for (size_t i = 1; i < 6; ++i) {
            oss << ":";
            oss.width(2);
            oss << ctoi(item->ifr_hwaddr.sa_data[i]);
        }
        auto addr = oss.str();
        if (addr != "00:00:00:00:00:00") {
            hw_addresses.push_back(std::move(addr));
        }
    }
    string uuid;
    ifstream fs;
    fs.open("/etc/fstab", ios_base::in);
    columns_iterator end;
    auto i = find_if(columns_iterator{&fs}, end, [](const vector<string>& cols) {
        return cols.size() == 6 && cols[1] == "/";
    });
    if (i != end) {
        uuid = move((*i)[0]);
        const char cstr[] = { "UUID=" };
        auto slen = sizeof(cstr) - 1;
        if (uuid.compare(0, slen, cstr) == 0) uuid.erase(0, slen);
        // UUIDs are formatted as 8-4-4-4-12 hex digits groups
        auto cpy = uuid;
        replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
        // discard invalid UUID
        if (cpy != "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF") uuid.clear();
    }
    return uuid;
}
예제 #10
0
		std::string VirtualShapeVirtualTable::GetTableName( const boost::filesystem::path& path )
		{
			string out(change_extension(path, string()).file_string());
			replace_if(out.begin(), out.end(), is_any_of(" \\:/()-+"), '_');
			return "shapefile_" + out;
		}
예제 #11
0
//-----------------------------------------------------------
void Punct_stream::transform()
{
	replace_if(str.begin() , str.end() ,  
        [] (const char& c) { return ispunct(c) ;},' ');
    vs.push_back(str);
}
예제 #12
0
Container replace_elems(const T& source, const T& dest, const Container& xs)
{
    return replace_if(bind_1st_of_2(is_equal<T>, source), dest, xs);
}
예제 #13
0
void NNFitnessFcn(int nVars, int nPopSize, double* pPop, double* pScore)
{
	Matrix pop(nPopSize, nVars, pPop);
	pop = !pop;
	Matrix score(nPopSize, 1);
	Matrix chrom, ch_sc, diff;
	Matrix mean = pop.vMean();
	bool bBad;
	//bounds penalty coefs
	Matrix bpc = pnna->ga_.opt_.initRange.GetRows(1) - pnna->ga_.opt_.initRange.GetRows(0);
	bpc *= 0.1;
	transform(bpc.begin(), bpc.end(), bpc.begin(), bind1st(divides<double>(), 1));
	//calc scores
	for(ulong i=0; i<score.size(); ++i) {
		chrom = pop.GetColumns(i);
		bBad = false;
		//score[i] = 0;
		/*
		for(ulong j=0; j<chrom.size(); ++j) {
			if(chrom[j] < pnna->_ga.opt_.initRange(0, j) || chrom[j] > pnna->_ga.opt_.initRange(1, j)) {
				score[i] = 1;
				bBad = true;
				break;
			}
		}
		*/
		if(pnna->opt_.normInp)
			chrom /= pnna->state_.max_ch_r;
		if(pnna->opt_.usePCA)
			chrom <<= pnna->netPCA_->Sim(chrom - pnna->state_.inpMean);

		if(pnna->opt_.netType == matrix_nn)
			ch_sc = pnna->net_.Sim(chrom);
		else
			ch_sc = pnn->sim(chrom);

		//if(bBad || pnna->opt_.pred_ratio <= 0) continue;
		if(pnna->opt_.pred_ratio > 0 && ch_sc[0] < pnna->state_.n_cur_min)
			ch_sc[0] += pow((pnna->state_.n_cur_min - ch_sc[0])/pnna->state_.pred_r, 4);

		score[i] = ch_sc[0];

		//check bounds
		if(1 == 1) {
			chrom <<= !chrom;
			diff <<= chrom - pnna->ga_.opt_.initRange.GetRows(0);
			replace_if(diff.begin(), diff.end(), bind2nd(greater<double>(), 0), 0);
			//multiply by penalty coefs
			diff *= bpc;
			score[i] += abs(score[i])*diff.Mul(diff).Sum();
			//score[i] -= abs(score[i])*diff.Sum();

			diff <<= pnna->ga_.opt_.initRange.GetRows(1) - chrom;
			replace_if(diff.begin(), diff.end(), bind2nd(greater<double>(), 0), 0);
			//multiply by penalty coefs
			diff *= bpc;
			score[i] += abs(score[i])*diff.Mul(diff).Sum();
			//score[i] -= abs(score[i])*diff.Sum();
		}
	}
	//score = pnna->GetRealData(score);
	memcpy(pScore, score.GetBuffer(), score.raw_size());
}
예제 #14
0
파일: solver.cpp 프로젝트: richoux/Wall-in
  double Solver::solve( double timeout )
  {
    chrono::duration<double,milli> elapsedTime;
    chrono::duration<double,milli> elapsedTimeTour;
    chrono::duration<double,milli> postprocessGap(0);
    chrono::time_point<chrono::system_clock> start;
    chrono::time_point<chrono::system_clock> startTour;
    start = chrono::system_clock::now();

    // to time simulateCost and cost functions
    chrono::duration<double,milli> timeSimCost(0);
    chrono::time_point<chrono::system_clock> startSimCost; 

#ifndef NDEBUG
    chrono::duration<double,milli> toverlap(0), tbuildable(0), tnoholes(0), tstt(0);
    chrono::time_point<chrono::system_clock> soverlap, sbuildable, snoholes, sstt; 
#endif

    int sizeGrid = grid.getNberRows() * grid.getNberCols() + 1; // + 1 for the "position -1" outside the grid
    vector< vector< double > >  vecConstraintsCosts( vecConstraints.size() );
    vector< double >		vecGlobalCosts( sizeGrid );
    vector< vector< double > >  vecVarSimCosts( sizeGrid );
    objective->initHelper( sizeGrid );

    bestCost = numeric_limits<int>::max();
    double beforePostProc = bestCost;
    double bestGlobalCost = numeric_limits<int>::max();
    double globalCost;
    double currentCost;
    double estimatedCost;
    double bestEstimatedCost;
    int    bestPosition;

    vector<int> worstBuildings;
    double worstVariableCost;
    int worstBuildingId;
    int sizeWall;

    shared_ptr<Building> oldBuilding;
    vector<int> possiblePositions;
    vector<double> varSimCost( vecBuildings.size() );
    vector<double> bestSimCost( vecBuildings.size() );

    int tour = 0;
    int iterations = 0;

    do // optimization loop
    {
      startTour = chrono::system_clock::now();
      ++tour;
      globalCost = numeric_limits<int>::max();
      bestEstimatedCost = numeric_limits<int>::max();
      sizeWall  = numeric_limits<int>::max();
      std::fill( varSimCost.begin(), varSimCost.end(), 0. );
      std::fill( bestSimCost.begin(), bestSimCost.end(), 0. );
      std::fill( vecConstraintsCosts.begin(), vecConstraintsCosts.end(), vector<double>( vecBuildings.size(), 0. ) );
      std::fill( vecVarSimCosts.begin(), vecVarSimCosts.end(), vector<double>( vecBuildings.size(), 0. ) );
      std::fill( variableCost.begin(), variableCost.end(), 0. );
      std::fill( tabuList.begin(), tabuList.end(), 0 );

      do // solving loop 
      {
	++iterations;

	if( globalCost == numeric_limits<int>::max() )
	{
	  currentCost = 0.;

	  for( auto c : vecConstraints )
	    currentCost += c->cost( variableCost );

	  if( currentCost < globalCost )
	    globalCost = currentCost;
	  else
	  {
	    reset();
	    continue;
	  }
	}

	// make sure there is at least one untabu variable
	bool freeVariables = false;

	// Update tabu list
	for( int i = 0; i < tabuList.size(); ++i )
	{
	  if( tabuList[i] <= 1 )
	  {
	    tabuList[i] = 0;
	    if( !freeVariables )
	      freeVariables = true;      
	  }
	  else
	    --tabuList[i];
	}

	// Here, we look at neighbor configurations with the lowest cost.
	worstBuildings.clear();
	worstVariableCost = 0;
	for( int i = 0; i < variableCost.size(); ++i )
	{
	  if( !freeVariables || tabuList[i] == 0 )
	  {
	    if( worstVariableCost < variableCost[i] )
	    {
	      worstVariableCost = variableCost[i];
	      worstBuildings.clear();
	      worstBuildings.push_back( i );
	    }
	    else 
	      if( worstVariableCost == variableCost[i] )
		worstBuildings.push_back( i );	  
	  }
	}
      
	// can apply some heuristics here, according to the objective function
	worstBuildingId = objective->heuristicVariable( worstBuildings, vecBuildings, grid );
	oldBuilding = vecBuildings[ worstBuildingId ];
      
	// get possible positions for oldBuilding.
	possiblePositions = grid.possiblePos( *oldBuilding );

	// time simulateCost
	startSimCost = chrono::system_clock::now();

	// variable simulated costs
	fill( bestSimCost.begin(), bestSimCost.end(), 0. );

#ifndef NDEBUG
	soverlap = chrono::system_clock::now();
	vecConstraintsCosts[0] = vecConstraints[0]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts, objective );
	toverlap += chrono::system_clock::now() - soverlap;

	sbuildable = chrono::system_clock::now();
	vecConstraintsCosts[1] = vecConstraints[1]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts );
	tbuildable += chrono::system_clock::now() - sbuildable;

	snoholes = chrono::system_clock::now();
	vecConstraintsCosts[2] = vecConstraints[2]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts );
	tnoholes += chrono::system_clock::now() - snoholes;

	sstt = chrono::system_clock::now();
	vecConstraintsCosts[3] = vecConstraints[3]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts );
	tstt += chrono::system_clock::now() - sstt;
#else
	vecConstraintsCosts[0] = vecConstraints[0]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts, objective );
	for( int i = 1; i < vecConstraints.size(); ++i )
	  vecConstraintsCosts[i] = vecConstraints[i]->simulateCost( *oldBuilding, possiblePositions, sizeGrid, vecVarSimCosts );
#endif

	fill( vecGlobalCosts.begin(), vecGlobalCosts.end(), 0. );

	// sum all numbers in the vector vecConstraintsCosts[i] and put it into vecGlobalCosts[i] 
	for( auto v : vecConstraintsCosts )
	  transform( vecGlobalCosts.begin(), 
		     vecGlobalCosts.end(), 
		     v.begin(), 
		     vecGlobalCosts.begin(), 
		     plus<double>() );

	// replace all negative numbers by the max value for double
	replace_if( vecGlobalCosts.begin(), 
		    vecGlobalCosts.end(), 
		    bind( less<double>(), placeholders::_1, 0. ), 
		    numeric_limits<int>::max() );

	// look for the first smallest cost, according to objective heuristic
	int b = objective->heuristicValue( vecGlobalCosts, bestEstimatedCost, bestPosition, grid);
	bestSimCost = vecVarSimCosts[ b ];

	timeSimCost += chrono::system_clock::now() - startSimCost;

	currentCost = bestEstimatedCost;

	if( bestEstimatedCost < globalCost )
	{
	  globalCost = bestEstimatedCost;

	  if( globalCost < bestGlobalCost )
	    bestGlobalCost = globalCost;

	  variableCost = bestSimCost;
	  move( oldBuilding, bestPosition );
	}
	else // local minima
	  tabuList[ worstBuildingId ] = TABU;

	elapsedTimeTour = chrono::system_clock::now() - startTour;
      } while( globalCost != 0. && elapsedTimeTour.count() < timeout );

      // remove useless buildings
      if( globalCost == 0 )
      {
	bool change;
	double cost;
	NoHoles nh( vecBuildings, grid );

	// remove all unreachable buildings from the starting building out of the grid
	set< shared_ptr<Building> > visited = getNecessaryBuildings();
	for( auto b : vecBuildings )
	  if( visited.find( b ) == visited.end() )
	  {
	    grid.clear( *b );
	    b->setPos( -1 );
	  }

	// clean wall from unnecessary buildings.
	do
	{
	  for( auto b : vecBuildings )
	    if( ! grid.isStartingOrTargetTile( b->getId() ) )
	    {
	      change = false;
	      if( b->isOnGrid() )
	      {
		cost = 0.;
		fill( varSimCost.begin(), varSimCost.end(), 0. );
	      
		cost = nh.simulateCost( *b, -1, varSimCost );
	      
		if( cost == 0. )
		{
		  grid.clear( *b );
		  b->setPos( -1 );
		  nh.update( grid );
		  change = true;
		}	  
	      }
	    }
	} while( change );

	double objectiveCost = objective->cost( vecBuildings, grid );
	int currentSizeWall = countBuildings( vecBuildings );

	if( objectiveCost < bestCost || ( objectiveCost == bestCost && currentSizeWall < sizeWall ) )
	{
	  sizeWall = currentSizeWall;
	  bestCost = objectiveCost;
	  for( int i = 0; i < vecBuildings.size(); ++i )
	    bestSolution[i] = vecBuildings[i]->getPosition();
	}
      }
      reset();
      elapsedTime = chrono::system_clock::now() - start;
    }
    while( ( objective->getName().compare("none") != 0 || loops == 0 )  && ( elapsedTime.count() < OPT_TIME )//|| ( elapsedTime.count() >= OPT_TIME && bestGlobalCost != 0 && elapsedTime.count() < 10 * OPT_TIME ) ) 
	   || ( objective->getName().compare("none") == 0 && elapsedTime.count() < timeout * loops ) );

    clearAllInGrid( vecBuildings, grid );

    for( int i = 0; i < vecBuildings.size(); ++i )
      vecBuildings[i]->setPos( bestSolution[i] );
    
    addAllInGrid( vecBuildings, grid );

    // For gap objective, try now to decrease the number of gaps.
    if( ( objective->getName().compare("gap") == 0 || objective->getName().compare("techtree") == 0 ) && bestGlobalCost == 0 )
    {
      //objective.reset( new GapObj("gap") );
      std::fill( tabuList.begin(), tabuList.end(), 0 );
        
      for( auto v : vecBuildings )
	buildingSameSize.insert( make_pair( v->getSurface(), v ) );

      vector<int> goodVar;
      shared_ptr<Building> toSwap;
      bool mustSwap;

      chrono::time_point<chrono::system_clock> startPostprocess = chrono::system_clock::now(); 
    
      bestCost = objective->cost( vecBuildings, grid );
      double currentCost = bestCost;
      beforePostProc = bestCost;

      while( (postprocessGap = chrono::system_clock::now() - startPostprocess).count() < static_cast<int>( ceil(OPT_TIME / 100) ) && bestCost > 0 )
      {
	goodVar.clear();

	for( int i = 0; i < tabuList.size(); ++i )
	{
	  if( tabuList[i] <= 1 )
	    tabuList[i] = 0;
	  else
	    --tabuList[i];
	}

	for( int i = 0; i < vecBuildings.size(); ++i )
	{
	  if( tabuList[i] == 0 )
	    goodVar.push_back( i );
	}

	if( goodVar.empty() )
	  for( int i = 0; i < vecBuildings.size(); ++i )
	    goodVar.push_back( i );	

	int index = objective->heuristicVariable( goodVar, vecBuildings, grid );
	oldBuilding = vecBuildings[ index ];
	auto surface = buildingSameSize.equal_range( oldBuilding->getSurface() );
	
	for( auto it = surface.first; it != surface.second; ++it )
	{
	  mustSwap = false;
	  if( it->second->getId() != oldBuilding->getId() )
	  {
	    grid.swap( *it->second, *oldBuilding );
	    
	    currentCost = objective->cost( vecBuildings, grid );
	    if( currentCost < bestCost )
	    {
	      bestCost = currentCost;
	      toSwap = it->second;
	      mustSwap = true;
	    }

	    grid.swap( *it->second, *oldBuilding );
	  }
	  
	  if( mustSwap )
	    grid.swap( *toSwap, *oldBuilding );
	}

	tabuList[ index ] = 2;//std::max(2, static_cast<int>( ceil(TABU / 2) ) );
      }
    }
 
    cout << "Grids:" << grid << endl;

    if( objective->getName().compare("none") == 0 )
      cout << "SATISFACTION run: try to find a sound wall only!" << endl;
    else
      cout << "OPTIMIZATION run with objective " << objective->getName() << endl;
      
    cout << "Elapsed time: " << elapsedTime.count() << endl
	 << "Global cost: " << bestGlobalCost << endl
	 << "Number of tours: " << tour << endl
	 << "Number of iterations: " << iterations << endl;

    if( objective->getName().compare("none") == 0 )
    {
      if( bestGlobalCost == 0 )
      {
	BuildingObj bObj("building");
	GapObj gObj("gap");
	TechTreeObj tObj("techtree");
	
	cout << "Opt Cost if the objective was building: " << bObj.cost( vecBuildings, grid ) << endl
	     << "Opt Cost if the objective was gap: \t" << gObj.cost( vecBuildings, grid ) << endl
	     << "Opt Cost if the objective was techtree: " << tObj.cost( vecBuildings, grid ) << endl;
      }
    }
    else
    {
      cout << "Optimization cost: " << bestCost << endl
	   << "Opt Cost BEFORE post-processing: " << beforePostProc << endl;
    }

    if( objective->getName().compare("gap") == 0 || objective->getName().compare("techtree") == 0 )
      cout << "Post-processing time: " << postprocessGap.count() << endl; 

#ifndef NDEBUG
    cout << endl << "Elapsed time to simulate cost: " << timeSimCost.count() << endl
	 << "Overlap: " << toverlap.count() << endl
	 << "Buildable: " << tbuildable.count() << endl
	 << "NoHoles: " << tnoholes.count() << endl
	 << "STT: " << tstt.count() << endl;

    updateConstraints( vecConstraints, grid );

    // print cost for each constraint
    for( auto c : vecConstraints )
    {
      fill( varSimCost.begin(), varSimCost.end(), 0. );
      cout << "Cost of " << typeid(*c).name() << ": " << c->cost( varSimCost ) << " [";

      for( auto v : varSimCost )
	cout << " " << v;

      cout << " ]" << endl;
    }      
    
    cout << endl;
#endif

    if( objective->getName().compare("none") == 0 )
      return bestGlobalCost;
    else
      return bestCost;
  }