//Asegurar que si un trip finaliza en un hotel, el siguiente trip comienza en el mismo hotel// int hotel_final_hotel_inicial_trip(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int x2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int q, sum = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); x2 = dim_x(j, ph); y1 = dim_y(i, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si las variables i y j parten en hoteles y estan en el mismo trip (que no es el primero)// //Se procede a sumar todas las variables que ya fueron instanciadas (como hoteles de llegada)// if((x2 < (*instancia).hoteles+2) && x1 == x2 && trip1 == trip2 && trip1 > 0){ for(q = 0; q < ph; q++){ sum += (*variables)[trans3D_to_1D(q, x1, trip1-1, ph, ph)].valor; } //Si la suma es 1 y la variable j-esima quiere tomar un hotel, se retorna Falso// if(sum == 1){ if((*variables)[i].valor == 1 && k == 1){ return False; } //Si estoy en el penultimo de los hoteles, se procede a sumar de nuevo// if(ph-2 == y1){ sum = 0; for(q = 0; q < ph; q++){ sum += (*variables)[trans3D_to_1D(x1, q, trip1, ph, ph)].valor; } //Si la suma del valor de las variables es 0 y la variable j-esima no quiere // // tomar un hotel, se retorna Falso// //Falso porque al no haber hotel previamente instanciado, la variable j-esima deberia tomar un hotel// if(sum == 0 && k == 0){ return False; } } } else{ //Si la suma es 0 y la variable j-esima quiere tomar un hotel, se retorna Falso// //Falso porque al ser la suma 0, quiere decir que no existe hotel de llegada, por ende..// //..no puede haber hotel de salida// if(k == 1){ return False; } } } return True; }
//Asegura que cada vertice sea visitado a lo mas una vez (unicidad de los vertices)// int unicidad(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1; int x2; int ph = ((*instancia).puntos+(*instancia).hoteles); //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); x2 = dim_x(j, ph); //Si la coordenada x de la variable i-esima y j-esima es la misma, y la variable i-esima no comienza en un hotel// if(x2 == x1 && x1 > (*instancia).hoteles+1){ //Si el valor de la variable i-esima es 1 y la variable j-esima quiere tomar el mismo valor, retorna Falso// //Falso porque ya existe un vertice visitado, en este caso, x1// if((*variables)[i].valor == 1 && k == 1){ return False; } } return True; }
//Asegura que el comienzo del trip sea un hotel disponible// int hotel_inicial_trip(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int x2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int q, h, sum = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); x2 = dim_x(j, ph); y1 = dim_y(i, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si el comienzo de la variable i-esima y j-esima pertenece a alguno de los hoteles y // // ambas variables estan en el mismo trip// if((x1 < (*instancia).hoteles+2 && x2 < (*instancia).hoteles+2) && (trip1 == trip2)){ //Si la variable i-esima ya comienza en un hotel y la variable j-esima tambien quiere // //comenzar en un hotel, se retorna Falso// if((*variables)[trans3D_to_1D(x1, y1, trip1, ph, ph)].valor == 1 && k == 1){ return False; } //Si se esta en la ultima variable de los que pueden ser hoteles y el valor del dominio de // // la variable j-esima es 0. Se suman todos valores de los hoteles, si la suma no es 1 se retorna Falso// //Se retorna Falso porque quiere decir que no existe un hotel ya instanciado en el trip// if((*instancia).hoteles == x1 && y1 == (ph-1) && k == 0){ for(q = 0; q < (*instancia).hoteles+2; q++){ for(h = 0; h < ph; h++){ sum += (*variables)[trans3D_to_1D(q, h, trip1, ph, ph)].valor; } } if(sum == 1){ return True; } else{ return False; } } } return True; }
//Asegura que el tour parta desde un hotel (Hotel = 0)// int hotel_ini(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int x2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int q, sum = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); x2 = dim_x(j, ph); y1 = dim_y(i, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si la variable i-esima parte en un hotel inicial y la variable j-esima quiere // //.. partir en el hotel inicial, ambos en el trip 0, se retorna Falso// if((x1 == 0 && x1 == x2) && (trip1 == 0 && trip2 == 0)){ if((*variables)[i].valor == 1 && k == 1){ return False; } //Si se esta en la penultima posicion de las variables que pueden ser hoteles iniciales..// //..se suman todas las variables anteriores. Si la suma no es 1 se retorna Falso// //Falso porque quiere decir que no existe hotel inicial// //Asi se obliga a que tome el ultimo camino que comienza con el hotel inicial// if((ph - 2) == y1 && k == 0){ for(q = 0; q < ph; q++){ sum += (*variables)[trans3D_to_1D(x1, q, trip1, ph, ph)].valor; } if(sum == 1){ return True; } else{ return False; } } } return True; }
//Se limita el tiempo de cada trip// int tiempo_max(int i, int j, int k, variable **variables, datos_problema* instancia){ int trip1; int x2, y2, trip2; int trips, xs, ys; int w, index; int ph = ((*instancia).puntos+(*instancia).hoteles); double dist_rec = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x2 = dim_x(j, ph); y2 = dim_y(j, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si la variable i-esima y la variable j-esima estan en el mismo trip, y el valor de // // la variable j-esima quiere tomar 1// //Se suman todas las distancias de las variables i-esimas que tienen valor 1// if(trip1 == trip2 && k == 1){ for(index = 0; index <= i; index++){ trips = dim_z(index,ph); if(trips == trip1){ if((*variables)[index].valor == 1){ xs = dim_x(index,ph); ys = dim_y(index,ph); w = obtener_indice(xs,ys,ph); dist_rec += (*instancia).matriz_dist[w]; } } } w = obtener_indice(x2, y2, ph); dist_rec += (*instancia).matriz_dist[w]; //Si la distancia recorrida (incluyendo la variable j-esima), es mayor a la distancia maxima del trip, retorna Falso// if(dist_rec > (*instancia).dist_max_trip[trip1]){ return False; } } return True; }
//Asegura que el tour termina en un hotel dispobible// int hotel_final(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int y2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int q, sum = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); y1 = dim_y(i, ph); y2 = dim_y(j, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si se esta en el trip final, la variable i y j pertenecen al trip final y la componente "y" de i y j es un hotel final// if(((*instancia).num_trips-1 == trip1) && (trip1 == trip2) && (y1 == y2 && y1 == 1)){ //Si el recorrido de la variable i termina en el hotel final y la variable j-esima quiere terminar en el hotel final// // se retorna Falso// if((*variables)[i].valor == 1 && k == 1){ return False; } //Si se esta en la penultima variable de las que pueden ser hoteles finales (variable i-esima) y // //el valor del dominio de la variable j-esima es 0// //Se suman todas las variables hacia atras, si la suma no es 1, se retorna Falso// //Falso porque quiere decir que no existe un hotel final en el Tour// if((ph - 2) == x1 && k == 0){ for(q = 0; q < ph; q++){ sum += (*variables)[trans3D_to_1D(q, y1, trip1, ph, ph)].valor; } if(sum == 1){ return True; } else{ return False; } } } return True; }
//Asegurar que el final del trip sea un hotel disponible// int hotel_final_trip(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int y2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int h, q, sum = 0; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); y1 = dim_y(i, ph); y2 = dim_y(j, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Restriccion que funciona con la misma logica que la anterior// //Solo que ahora se chequea para un hotel final en el trip// if((y1 < (*instancia).hoteles+2 && y2 < (*instancia).hoteles+2) && (trip1 == trip2)){ if((*variables)[i].valor == 1 && k == 1){ return False; } if((*instancia).hoteles+1 == y1 && x1 == (ph-2) && k == 0){ for(q = 0; q < (*instancia).hoteles+2; q++){ for(h = 0; h < ph; h++){ sum += (*variables)[trans3D_to_1D(h, q, trip1, ph, ph)].valor; } } if(sum == 1){ return True; } else{ return False; } } } return True; }
size_t size() const { return dim_x() * dim_y() * dim_z(); }
void ParticleAroundWalls::phi_t(arr& phi, arr& J, uint t, const arr& x_bar){ uint T=get_T(), n=dim_x(), k=get_k(); //assert some dimensions CHECK(x_bar.d0==k+1,""); CHECK(x_bar.d1==n,""); CHECK(t<=T,""); //-- transition costs: append to phi if(k==1) phi = x_bar[1]-x_bar[0]; //penalize velocity if(k==2) phi = x_bar[2]-2.*x_bar[1]+x_bar[0]; //penalize acceleration if(k==3) phi = x_bar[3]-3.*x_bar[2]+3.*x_bar[1]-x_bar[0]; //penalize jerk //-- walls: append to phi //Note: here we append to phi ONLY in certain time slices: the dimensionality of phi may very with time slices; see dim_phi(uint t) double eps=.1, power=2.; if(!hardConstrained){ //-- wall costs for(uint i=0;i<n;i++){ //add barrier costs to each dimension if(t==T/4) phi.append(MT::ineqConstraintCost(i+1.-x_bar(k,i), eps, power)); //middle factor: ``greater than i'' if(t==T/2) phi.append(MT::ineqConstraintCost(x_bar(k,i)+i+1., eps, power)); //last factor: ``lower than -i'' if(t==3*T/4) phi.append(MT::ineqConstraintCost(i+1.-x_bar(k,i), eps, power)); //middle factor: ``greater than i'' if(t==T) phi.append(MT::ineqConstraintCost(x_bar(k,i)+i+1., eps, power)); //last factor: ``lower than -i'' } }else{ //-- wall constraints for(uint i=0;i<n;i++){ //add barrier costs to each dimension if(t==T/4) phi.append((i+1.-x_bar(k,i))); //middle factor: ``greater than i'' if(t==T/2) phi.append((x_bar(k,i)+i+1.)); //last factor: ``lower than -i'' if(t==3*T/4) phi.append((i+1.-x_bar(k,i))); //middle factor: ``greater than i'' if(t==T) phi.append((x_bar(k,i)+i+1.)); //last factor: ``lower than -i'' } } uint m=phi.N; CHECK(m==dim_phi(t),""); if(&J){ //we also need to return the Jacobian J.resize(m,k+1,n).setZero(); //-- transition costs for(uint i=0;i<n;i++){ if(k==1){ J(i,1,i) = 1.; J(i,0,i) = -1.; } if(k==2){ J(i,2,i) = 1.; J(i,1,i) = -2.; J(i,0,i) = 1.; } if(k==3){ J(i,3,i) = 1.; J(i,2,i) = -3.; J(i,1,i) = +3.; J(i,0,i) = -1.; } } //-- walls if(!hardConstrained){ for(uint i=0;i<n;i++){ if(t==T/4) J(n+i,k,i) = -MT::d_ineqConstraintCost(i+1.-x_bar(k,i), eps, power); if(t==T/2) J(n+i,k,i) = MT::d_ineqConstraintCost(x_bar(k,i)+i+1., eps, power); if(t==3*T/4) J(n+i,k,i) = -MT::d_ineqConstraintCost(i+1.-x_bar(k,i), eps, power); if(t==T) J(n+i,k,i) = MT::d_ineqConstraintCost(x_bar(k,i)+i+1., eps, power); } }else{ for(uint i=0;i<n;i++){ if(t==T/4) J(n+i,k,i) = -1.; if(t==T/2) J(n+i,k,i) = +1.; if(t==3*T/4) J(n+i,k,i) = -1.; if(t==T) J(n+i,k,i) = +1.; } } } }
uint ParticleAroundWalls::dim_g(uint t){ if(!hardConstrained) return 0; uint T=get_T(); if(t==T/2 || t==T/4 || t==3*T/4 || t==T) return dim_x(); return 0; }
uint ParticleAroundWalls::dim_phi(uint t){ uint T=get_T(); if(t==T/2 || t==T/4 || t==3*T/4 || t==T) return 2*dim_x(); return dim_x(); }
//Asegurar conectividad entre todos los nodos dentro de cada trip// int conectividad(int i, int j, int k, variable **variables, datos_problema* instancia){ int x1, y1, trip1; int x2, y2, trip2; int ph = ((*instancia).puntos+(*instancia).hoteles); int q; //Identificadores que nos permiten saber si la variable en cuestion se utiliza para llegar o para salir del POI u hotel// int flag_salgo_x = False, flag_llego_x = False, flag_salgo_y = False, flag_llego_y = False; //Identificador que nos permite saber si la variable a estudiar pertenece a las variables que llegan o a las que salen// int flag_pertenece; int sum_salgo_x = 0, sum_llega_x = 0, sum_salgo_y = 0, sum_llega_y = 0; int pos; //Se obtienen las componentes que se necesiten (x, y, z) de las variables i y j// x1 = dim_x(i, ph); x2 = dim_x(j, ph); y1 = dim_y(i, ph); y2 = dim_y(j, ph); trip1 = dim_z(i, ph); trip2 = dim_z(j, ph); //Si la variable j-esima parte en un POI, obtengo todas las variables que empiecen con la misma coordenada x que j// if(x2 > (*instancia).hoteles+1){ for(q = 0; q < ph; q++){ pos = trans3D_to_1D(x2, q, trip2, ph, ph); if(pos == j){ //Si la flag es 0, quiere decir que la variable j-esima esta "saliendo"// flag_pertenece = 0; } //Si las variables obtenidas anteriormente son menores o iguales a la variable i-esima// //sumo todos los que salen desde el x2 que han sido instanciados// if(pos <= i){ sum_salgo_x += (*variables)[pos].valor; } //reviso que todos los que salen del x2 y no han sido instanciados, puedan tomar el valor 1// else{ if(pos != j && (*variables)[pos].dominio[1] == NO_PROBLEM){ //True cuando pueden valer 1// flag_salgo_x = True; break; } } } for(q = 0; q < ph; q++){ pos = trans3D_to_1D(q, x2, trip2, ph, ph); if(pos == j){ //Si la flag es 1, quiere decir que la variable j-esima esta "llegando"// flag_pertenece = 1; } //Si las variables obtenidas anteriormente son menores o iguales a la variable i-esima// //sumo todos los que llegan al x2 que han sido instanciados// if(pos <= i){ sum_llega_x += (*variables)[pos].valor; } //reviso que todos los que llegan al x2 y no han sido instanciados, puedan tomar el valor 1// else{ if(pos != j && (*variables)[pos].dominio[1] == NO_PROBLEM){ flag_llego_x = True; break; } } } //Restricciones para cuando j sale (x2)// if(sum_salgo_x == 0 && sum_llega_x == 1 && k == 0 && flag_pertenece == 0 && flag_salgo_x == False){ return False; } else if(sum_salgo_x == 1 && sum_llega_x == 0 && k == 0 && flag_pertenece == 1 && flag_llego_x == False){ return False; } else if(sum_salgo_x == 1 && k == 1 & flag_pertenece == 0){ return False; } else if(sum_llega_x == 1 && k == 1 & flag_pertenece == 1){ return False; } if(sum_salgo_x == 0 && sum_llega_x == 0 && k == 1 && flag_pertenece == 0 && flag_llego_x == False){ return False; } if(sum_salgo_x == 0 && sum_llega_x == 0 && k == 1 && flag_pertenece == 1 && flag_salgo_x == False){ return False; } } //Si la variable j-esima es un POI, obtengo obtengo todas las variables que terminen con la misma coordenada y que j// if(y2 > (*instancia).hoteles+1){ for(q = 0; q < ph; q++){ pos = trans3D_to_1D(q, y2, trip2, ph, ph); if(pos == j){ //Si la flag es 0, quiere decir que la variable j-esima esta "llegando"// flag_pertenece = 0; } //Si las variables obtenidas anteriormente son menores o iguales a la variable i-esima// //sumo todos los que llegan al y2 que han sido instanciados// if(pos <= i){ sum_salgo_y += (*variables)[pos].valor; } //reviso que todos los que llegan al y2 y no han sido instanciados, puedan tomar el valor 1// else{ if(pos != j && (*variables)[pos].dominio[1] == NO_PROBLEM){ flag_salgo_y = True; break; } } } for(q = 0; q < ph; q++){ pos = trans3D_to_1D(y2, q, trip2, ph, ph); if(pos == j){ //Si la flag es 1, quiere decir que la variable j-esima esta "saliendo"// flag_pertenece = 1; } //Si las variables obtenidas anteriormente son menores o iguales a la variable i-esima// //sumo todos los que salen del y2 que han sido instanciados// if(pos <= i){ sum_llega_y += (*variables)[pos].valor; } //reviso que todos los que salen del y2 y no han sido instanciados, puedan tomar el valor 1// else{ if(pos != j && (*variables)[pos].dominio[1] == NO_PROBLEM){ flag_llego_y = True; break; } } } //restricciones para cuando j llega (y2)// if(sum_salgo_y == 0 && sum_llega_y == 1 && k == 0 && flag_pertenece == 0 && flag_salgo_y == False){ return False; } else if(sum_salgo_y == 1 && sum_llega_y == 0 && k == 0 && flag_pertenece == 1 && flag_llego_y == False){ return False; } else if(sum_salgo_y == 1 && k == 1 & flag_pertenece == 0){ return False; } else if(sum_llega_y == 1 && k == 1 & flag_pertenece == 1){ return False; } if(sum_salgo_y == 0 && sum_llega_y == 0 && k == 1 && flag_pertenece == 0 && flag_llego_y == False){ return False; } if(sum_salgo_y == 0 && sum_llega_y == 0 && k == 1 && flag_pertenece == 1 && flag_salgo_y == False){ return False; } } return True; }
void interpolator::fill_partitions(std::string const& datafilename, std::string symbolic_name_base, async_create_result_type future) { // Read required data from file. num_values_[dimension::ye] = extract_data_range(datafilename, "ye", minval_[dimension::ye], maxval_[dimension::ye], delta_[dimension::ye]); num_values_[dimension::temp] = extract_data_range(datafilename, "logtemp", minval_[dimension::temp], maxval_[dimension::temp], delta_[dimension::temp]); num_values_[dimension::rho] = extract_data_range(datafilename, "logrho", minval_[dimension::rho], maxval_[dimension::rho], delta_[dimension::rho]); // Wait for the partitions to be created. distributing_factory::result_type results = future.get(); distributing_factory::iterator_range_type parts = hpx::util::locality_results(results); for (hpx::naming::id_type id : parts) { std::cout << "Partition " << partitions_.size() << ": " << id << "\n"; partitions_.push_back(id); } // Initialize all attached partition objects. std::size_t num_localities = partitions_.size(); HPX_ASSERT(0 != num_localities); num_partitions_per_dim_ = static_cast<std::size_t>( std::exp(std::log(double(num_localities)) / 3)); std::size_t partition_size_x = num_values_[dimension::ye] / num_partitions_per_dim_; std::size_t last_partition_size_x = num_values_[dimension::ye] - partition_size_x * (num_partitions_per_dim_-1); std::size_t partition_size_y = num_values_[dimension::temp] / num_partitions_per_dim_; std::size_t last_partition_size_y = num_values_[dimension::temp] - partition_size_y * (num_partitions_per_dim_-1); std::size_t partition_size_z = num_values_[dimension::rho] / num_partitions_per_dim_; std::size_t last_partition_size_z = num_values_[dimension::rho] - partition_size_z * (num_partitions_per_dim_-1); dimension dim_x(num_values_[dimension::ye]); dimension dim_y(num_values_[dimension::temp]); dimension dim_z(num_values_[dimension::rho]); std::vector<hpx::lcos::future<void> > lazy_sync; for (std::size_t x = 0; x != num_partitions_per_dim_; ++x) { dim_x.offset_ = partition_size_x * x; if (x == num_partitions_per_dim_-1) dim_x.count_ = last_partition_size_x; else dim_x.count_ = partition_size_x; for (std::size_t y = 0; y != num_partitions_per_dim_; ++y) { dim_y.offset_ = partition_size_y * y; if (y == num_partitions_per_dim_-1) dim_y.count_ = last_partition_size_y; else dim_y.count_ = partition_size_y; for (std::size_t z = 0; z != num_partitions_per_dim_; ++z) { dim_z.offset_ = partition_size_z * z; if (z == num_partitions_per_dim_-1) dim_z.count_ = last_partition_size_z; else dim_z.count_ = partition_size_z; std::size_t index = x + (y + z * num_partitions_per_dim_) * num_partitions_per_dim_; HPX_ASSERT(index < partitions_.size()); lazy_sync.push_back(stubs::partition3d::init_async( partitions_[index], datafilename, dim_x, dim_y, dim_z)); } } } // Create the config object locally. hpx::naming::id_type config_id = hpx::find_locality(configuration::get_component_type()); cfg_ = configuration(config_id, datafilename, symbolic_name_base, num_localities); hpx::agas::register_name(symbolic_name_base, cfg_.get_id()); if (symbolic_name_base[symbolic_name_base.size() - 1] != '/') symbolic_name_base += "/"; std::size_t i = 0; // Register symbolic names of all involved components. for (hpx::naming::id_type const& id : partitions_) { hpx::agas::register_name( symbolic_name_base + std::to_string(i++), id); } // Wait for initialization to finish. hpx::wait_all(lazy_sync); }