FloatType route_evaluation(GlobalGiftData g_data, const Route & r){ FloatType res = 0.0; int test_counter = 0; FloatType w = sleigh_base_weight; for (int i = 0; i < r.size(); ++i) { const auto & gift = g_data[r[i]]; w += gift.Weight(); ++test_counter; } auto w_limit = sleigh_weight_limit + sleigh_base_weight; // weight > then limit assert(w <= w_limit); res += w*Dist(north_pole, g_data[r[0]].Loc() ); test_counter = 0; int __size = r.size(); for (int i = 0; i < __size-1; ++i) { const auto & gift = g_data[r[i]]; const auto & gift_next = g_data[r[i+1]]; w -= gift.Weight(); res += w*Dist(gift.Loc(), gift_next.Loc()); ++test_counter; } w = sleigh_base_weight; res += w*Dist(north_pole, g_data[r[r.size()-1]].Loc() ); return res; }
RouteAccessException(const Route & r, IntType pos): pos(pos), r(r){ stringstream ss; ss << "route size == " << r.size() << " acess at pos == " << pos; s = ss.str(); }
int main() { // Estrutura List Route route; // Ler ponto de um arquivo std::ifstream ifs ("points.dat", std::ifstream::in); point aux(0,0); while (ifs >> aux.real() >> aux.imag()) { route.push_back(aux); } ifs.close(); // List teste // Algoritmo // Step 1: Calcular as poupanças sij=ci0+c0j-cij para i,j=1,...mn i!=j. Criar n rotas de veículos // (0,i,0) para i=1,...,n. Ordenar as economias num modo não crescente. int n=route.size(); double s[n][n-1]; point origin=*route.begin(); Route Aux; Subroute Sb; for (Route::iterator i=++route.begin(); i!=route.end(); ++i) { Aux.push_back(*i); Sb.push_back(Aux); for ( Route::iterator j=i; j!=route.end(); ++j) { if( i!=j) { s[i][j]( std::abs(*i-origin)+std::abs(origin-*j)-std::abs(*i-*j) ); } } Aux.clear(); } std::cout << Sb.size() << std::endl; s.sort(); for (std::list<double>::iterator i=s.begin(); i!=s.end(); ++i) std::cout << *i << std::endl; // Step 2: Iniciar do topo da lista de economias, executando o seguinte. Dada a economia sij, // determine se há duas rotas, uma contendo arco ou aresta (0,j) e a outra contendo o arco ou aresta // (i,0), que pode ser mescladas. Se então, combine essas duas rotas deletando (0,j) e (i,0) e // introduzindo (i,j). // Mesclar rotas for(Subroute::iterator I=Sb.end(); I!=Sb.begin(); --I) { } return 0; }
void plot_path_order(const Route& r, const char* filename) { std::ofstream os(filename); SvgWriter svg(r, os); std::vector<Point> sharedPoints; hsl_color hsl; rgb_color rgb; hsl.h = 0; hsl.s = 100; hsl.l = 50; float step = 360.0f / r.size(); for(const Path& path : r) { hsl.h = (hsl.h+step); if (hsl.h >= 360) { hsl.h = 1; } rgb = hsl_to_rgb(hsl); string strokergb = (boost::format("stroke:rgb(%u,%u,%u)") % round(rgb.r) % round(rgb.g) % round(rgb.b)).str(); svg.write(path, strokergb + ";stroke-width:10;fill:none;"); svg.write(path.front(), "stroke:rgb(255,0,0);stroke-width:40;"); svg.write(path.back(), "stroke:rgb(0,255,0);stroke-width:35;"); } uint32_t count = 0; for(const Path& path : r) { svg.write(path.front(), "stroke:rgb(255,0,0);stroke-width:40;"); svg.write(path.back(), "stroke:rgb(0,255,0);stroke-width:35;"); svg.write((boost::format("%d") % count).str(), path.front(), "font-size=\"50\" fill=\"black\""); svg.write((boost::format("%d") % count).str(), path.back(), "font-size=\"50\" fill=\"black\""); ++count; } for(const Point& p : sharedPoints) { svg.write(p, "stroke:rgb(255,0,0);stroke-width:10;fill:none"); } }
void chop(const Route& src, Route& sink, double maxLength) { for(SegmentPtr seg : segments(src)) { if(double len = seg->length() > maxLength) { Point lastPoint = seg->first; Point currentPoint; for(size_t i = 0; i < (len / maxLength); i++) { Segment newSeg; double t = i/(len/maxLength); currentPoint.x = seg->first.x * (1-t) + seg->second.x * t; currentPoint.y = seg->first.y * (1-t) + seg->second.y * t; append(sink, Segment(lastPoint, currentPoint)); lastPoint = currentPoint; } if(fmod(len, maxLength) > 0) { append(sink, Segment(lastPoint, seg->second)); } } else { append(sink, *seg); } } LOG_INFO_STR("chop"); LOG_DEBUG(sink.size()); }
void reduce(Route& src, Route& sink, double maxDistance) { if(maxDistance == 0) return; LOG_DEBUG(src.size()); typedef SegmentGraphImpl<boost::setS, boost::setS> UniqueSegmentGraph; UniqueSegmentGraph g; for(const SegmentPtr seg : segments(src)) { g.addSegment(*seg.get()); } std::map<Point, UniqueSegmentGraph::Vertex> index; BOOST_FOREACH(UniqueSegmentGraph::Vertex v, vertices(g)) { index[g[v]] = v; } for(Path& path : src) { Path singleBranch; Path simplified; Point last = path.front(); Point current; for(const SegmentPtr segPtr : segments(path)) { const Segment& seg = *segPtr.get(); concat(singleBranch,seg); if(last == seg.first) current = seg.second; else assert(false); last = current; if(boost::degree(index[current],g) > 2) { boost::geometry::simplify(singleBranch, simplified, maxDistance); if(!is_collapsed(singleBranch, simplified)) add(sink, simplified); else { Box b; boost::geometry::envelope(simplified, b); if(b.width() > maxDistance && b.height() > maxDistance) { add(sink, simplified); } } singleBranch.clear(); simplified.clear(); } } if (!singleBranch.empty()) { boost::geometry::simplify(singleBranch, simplified, maxDistance); if (!is_collapsed(singleBranch, simplified)) add(sink, simplified); else { Box b; boost::geometry::envelope(simplified, b); if(b.width() > maxDistance && b.height() > maxDistance) { add(sink, simplified); } } } singleBranch.clear(); simplified.clear(); } LOG_DEBUG(sink.size()); }
void firstSearchTest() { int aheads; int length; cin >> aheads >> length; vector<vector<int> > originalBoard(HEIGHT, vector<int>(WIDTH, 0)); while (true) { originalBoard = generateRandomBoard(); //inputBoard(originalBoard); debug(originalBoard); for (int l = 0; l <= aheads; l++) { vector<vector<int>> board = originalBoard; Route ansRoute; int evalMAX = -1; int size = 1 << 20; int row = 0, column = 0; for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { vector<vector<int>> tmpBoard = board; int evalNum; Route route = firstSearch_4(board, l, length, i, j, evalNum); //if ((i == 2 && j == 4) || (i == 2 && j == 1)) //{ // debug(tmpBoard); //} Route simpliFiedRoute; simplifyRoutePerfectly(route, i, j, simpliFiedRoute); //if ((i == 2 && j == 4) || (i == 2 && j == 1)) //{ // cout << endl; // cout << "debug:" << endl; // debug(board); // debug(tmpBoard); // cout << i << ", " << j << endl; // debug(route); // cout << "↓" << endl; // debug(simpliFiedRoute); // cout << evalNum << endl; // cout << endl; //} //Route simpliFiedRoute = route; if (evalMAX < evalNum) { ansRoute = simpliFiedRoute; evalMAX = evalNum; row = i; column = j; size = ansRoute.size(); } else if (evalMAX == evalNum && size < simpliFiedRoute.size()) { ansRoute = simpliFiedRoute; evalMAX = evalNum; row = i; column = j; size = ansRoute.size(); } } } //debug(ansRoute); //cout << row << ", " << column << endl; moveByRoute(board, ansRoute, row, column); //debug(board); int evalNum = evalProcess(board); cout << "Aheads: " << l << endl; cout << "Evaluation: " << evalNum << endl; evalNum += fillBoardRandom(board) * 100;//毎回ボード結果が変わるので平等でない cout << "RandomFilled: " << evalNum / 100 * 100 << endl; } string tmp; std::getline(cin, tmp); } }
Pathfinding::Route Pathfinding::getPath(Entity* entity, const Vector3& goal) { stringstream prettyInfo; Vector3 start = entity->getPosition(); double a = phantom::Util::getTime(); _layer.cleanPathfinding(); Route route; if(_showDebug) { cout << endl<< endl<< endl<< endl; } if(_visualize) { getGraphics().clear(); } // Goal space uses a "strict" heuristic. EG: we don't want to walk into a tree. Space* goalSpace = _layer.getSpaceAtUsingHeuristic(goal, entity); // There is no "space" available at the destination. The entity probably wants // to walk into a tree. Returns an empty route. if(goalSpace == nullptr) { if(_showDebug) { cout << "Goal vector is not a space." << endl; } return route; } // Start space, first try using a strict heuristic. EG: If we start near a tree // we don't want to walk into that tree. Space* startSpace = _layer.getSpaceAtUsingHeuristic(start, entity); // Ok, did we find a start space with the strict heuristic? If not, it probably // means that our entity is stuck in a tree. Proceed with a less strict // heuristic. In most cases this will let the entity "leave" the solid object // that it's currently stuck on. if(startSpace == nullptr) { startSpace = _layer.getSpaceAtUsingHeuristic(start); } // Ok, we really can't walk anywhere. This is a rather odd case. Most likely // the user tried to walk outside of the BSP tree, or you've just found a bug // in the BSP tree. if(startSpace == nullptr) { if(_showDebug) { cout << "Start vector is not a space." << endl; } route.push_back(Vector3(goal)); return route; } if(_showDebug) { cout << "Starting at: " << startSpace->getArea().toString(); cout << "Ending at : " << goalSpace->getArea().toString(); } if(_visualize) { Box3& m = startSpace->getArea(); getGraphics().beginPath().setFillStyle(Color(0, 0, 127, 20)) .rect(m.origin.x+4, m.origin.y+4, m.size.x-8, m.size.y-8) .fill(); Box3& n = goalSpace->getArea(); getGraphics().beginPath().setFillStyle(Color(0, 0, 127, 20)) .rect(n.origin.x+4, n.origin.y+4, n.size.x-8, n.size.y-8) .fill(); } priority_queue<Space*, vector<Space*>, CompareShapesAstar> open; startSpace->isInOpenList = true; open.push(startSpace); if(_showBasicDebug) { prettyInfo << "Pathfinding overhead: " << std::fixed << (phantom::Util::getTime() - a) << " seconds. "; } int spacesScanned = 0; const double startTime = phantom::Util::getTime(); int timeout = 0; while(true) { if(open.empty()) { if(_showBasicDebug || _showDebug) { cout << " Open list empty." << endl; double now = phantom::Util::getTime(); if(_showBasicDebug) { prettyInfo << "No route found, scanned "<< spacesScanned << " Tile(s) in " << std::fixed << (now - startTime) << " seconds."; } } break; } if(timeout++ > 10000) { cout << " I give up after " << timeout << " tries. " << endl; double now = phantom::Util::getTime(); cout << "A* scanned " << spacesScanned << " Tile(s) in " << std::fixed << (now - startTime) << " seconds. " << endl; break; } Space* current = open.top(); open.pop(); if(_visualize) { //cout << " - Testing: " << current->getArea().toString(); drawRect(current, Color(0, 127, 127, 10)); } if(current == goalSpace) { if(_showDebug) { cout << " **** found! This is a good sign. " << endl; } unfoldRoute(route, current, startSpace, entity); if(!route.empty()) { route.pop_front(); Vector3 lastpos = goal - entity->getBoundingBox().size * 0.5; // Replace the last way-point with our mouse click coordinates: if(route.empty()) { route.push_back(lastpos); } else { route.back() = lastpos; } } double now = phantom::Util::getTime(); if(_showBasicDebug) { prettyInfo << "Found route, A* scanned " << spacesScanned << " Tile(s) in " << std::fixed << (now - startTime) << " seconds. Waypoint(s): " << route.size() << "."; } break; } vector<Space*>& neighbours = _layer.getNeighbours(current, entity); if(_showDebug && neighbours.empty()) { cout << " No neighbours found." << endl; } for(size_t i = 0; i < neighbours.size(); ++i) { Space* testing = neighbours[i]; if(!testing->isInOpenList) { spacesScanned++; testing->astarParent = current; testing->isInOpenList = true; testing->g = current->g + Services::settings()->pathfinding_g_cost; testing->h = calculateHeuristic(goalSpace, testing); testing->h = testing->h * testing->h; open.push(testing); } } } if(_showBasicDebug) { //cout << prettyInfo.str() << endl; Console::log(prettyInfo.str()); } return route; }
/* * Clips segments agains a box */ void clip(Route& src, Route& sink, const Box& bounds) { LOG_DEBUG(src.size()); for (const SegmentPtr segPtr : segments(src)) { Segment& seg = *segPtr.get(); double width = bounds.width(); double height = bounds.height(); Segment leftBedBorder(Point(0, 0), Point(0, height - 1)); Segment bottomBedBorder(Point(0, height - 1), Point(width - 1, height - 1)); Segment rightBedBorder(Point(width - 1, height - 1), Point(width - 1, 0)); Segment topBedBorder(Point(width - 1, 0), Point(0, 0)); Point intersection; Segment clipped = seg; if (clipped.first.x < 0 || clipped.second.x < 0 || clipped.first.y < 0 || clipped.second.y < 0 || clipped.first.x > width - 1 || clipped.second.x > width - 1 || clipped.first.y > height - 1 || clipped.second.y > height - 1) { if (clipped.first.x < 0 || clipped.second.x < 0) { // out of bounds; if (clipped.first.x < 0 && clipped.second.x < 0) { continue; } if (intersects(clipped, leftBedBorder, intersection) == ALIGN_INTERSECT) { if (clipped.first.x >= clipped.second.x) clipped.second = clipped.first; clipped.first = intersection; intersection = Point(); } } if (clipped.first.y < 0 || clipped.second.y < 0) { if (clipped.first.y < 0 && clipped.second.y < 0) { continue; } if (intersects(clipped, topBedBorder, intersection) == ALIGN_INTERSECT) { if (clipped.first.y >= clipped.second.y) clipped.second = clipped.first; clipped.first = intersection; intersection = Point(); } } if (greater_than(clipped.first.x, width - 1) || greater_than(clipped.second.x, width - 1)) { if (greater_than(clipped.first.x, width - 1) && greater_than(clipped.second.x, width - 1)) { continue; } if (intersects(clipped, rightBedBorder, intersection) == ALIGN_INTERSECT) { if (clipped.first.x <= clipped.second.x) clipped.second = clipped.first; clipped.first = intersection; intersection = Point(); } } if (clipped.first.y > height - 1 || clipped.second.y > height - 1) { if (clipped.first.y > height - 1 && clipped.second.y > height - 1) { continue; } if (intersects(clipped, bottomBedBorder, intersection) == ALIGN_INTERSECT) { if (clipped.first.y <= clipped.second.y) clipped.second = clipped.first; clipped.first = intersection; } } } add(sink, clipped); } LOG_DEBUG(sink.size()); }