void setV(stringstream& lineStream, NodeList& NList) { int nodeID; double voltage; if(!anyArgs(lineStream)) return; lineStream >> nodeID; if(!validNode(nodeID, lineStream)) return; lineStream >> voltage; if(lineStream.fail()) { cout << "Error: " << endl; return; } if(!endOfArgs(lineStream)) return; if(NList.findNode(nodeID) == NULL) NList.insertNode(nodeID); NList.findNode(nodeID) -> setVoltage(voltage); cout.setf(ios::fixed); cout.setf(ios::showpoint); cout << "Set: node " << nodeID << " to " << setprecision(2) << voltage << setprecision(6) << " Volts" << endl; cout.unsetf(ios::fixed); cout.unsetf(ios::showpoint); }
void unsetV(stringstream& lineStream, NodeList& NList) { int nodeID; if(!anyArgs(lineStream)) return; lineStream >> nodeID; if(!validNode(nodeID, lineStream)) return; if(!endOfArgs(lineStream)) return; if(NList.findNode(nodeID) == NULL) cout << "Error: node " << nodeID << " doesn't exist" << endl; else { NList.findNode(nodeID) -> unsetVoltage(); cout << "Unset: the solver will determine the voltage of node " << nodeID << endl; } }
void insertR(stringstream& lineStream, NodeList& NList) { string name; double resistance; int nodeID1, nodeID2; //Read in each argument one at a time and check for errors lineStream >> name; if(!anyArgs(lineStream)) return; if(name == "all") { cout << "Error: resistor name cannot be the keyword \"all\"" << endl; return; } lineStream >> resistance; if(!validResistance(resistance, lineStream)) return; lineStream >> nodeID1; if(!validNode(nodeID1, lineStream)) return; lineStream >> nodeID2; if(!validNode(nodeID2, lineStream)) return; if(nodeID1 == nodeID2) { cout << "Error: both terminals of resistor connect to node " << nodeID1 << endl; return; } //check if there are more arguments if(!endOfArgs(lineStream)) return; //VALID ARGUMENTS //check if nodes exist, if not create if(NList.findNode(nodeID1) == NULL) NList.insertNode(nodeID1); if(NList.findNode(nodeID2) == NULL) NList.insertNode(nodeID2); //check if resistor name already exists if(NList.findResistor(name) != NULL) { cout << "Error: resistor " << name << " already exists" << endl; return; } //if resistor doesnt exist int nodes[2] = {nodeID1, nodeID2}; NList.addResistor(name, resistance, nodes); cout.setf(ios::fixed); cout.setf(ios::showpoint); cout << "Inserted: resistor " << name << " " << setprecision(2) << resistance << " Ohms " << setprecision(6); cout.unsetf(ios::fixed); cout.unsetf(ios::showpoint); cout << nodeID1 << " -> " << nodeID2 << endl; return; }
// graph where s_i = {pos_D, pos_R, cost}, pointer to parents. // possible entries (diamond pushes) are added with wavefront // the shortest path till now is explored further (heap) // hash table to check if node exists bool Sokoban::findPath(){ printMap(map_); std::cout << "Init. finding paths..." << std::endl; // graph to store the tree of possibilities graph paths; // has a solution been found bool solution_found = false; // - make needed maps // heuristic map std::vector< std::vector<char> > heuristic_map = map_; wavefront(heuristic_map, goals_); // printMap(heuristic_map); // std::cout << std::endl; // deadlock map std::vector< std::vector<char> > deadlock_map = map_; deadlocks(deadlock_map); // printMap(deadlock_map); // the next child to consider (lowest cost) node * cheapest_leaf = nullptr; // node to add node nextnode(0, cheapest_leaf, heuristic_map); nextnode.setRobot(pos_t(robot_.x_, robot_.y_)); nextnode.setDiamonds(diamonds_); std::cout << "# of Diamonds: " << diamonds_.size() << std::endl; // add the initial position paths.createChild(nextnode); int lastCost = 0; std::cout << "Exploring paths..." << std::endl; // run this until the path is found or no paths can be taken int iterations = 0; // debug thing while(!solution_found && paths.getNextChild(cheapest_leaf)){ iterations++; // if(lastCost < cheapest_leaf->getCost() + cheapest_leaf->getHeuristic()){ // lastCost = cheapest_leaf->getCost() + cheapest_leaf->getHeuristic(); // std::cout << "current cost: " << lastCost << ", open-/closed-list size: " << paths.getOpenListSize() << " / " << paths.getClosedListSize() << std::endl; // } // check cheapest leaf if it is the solution solution_found = cheapest_leaf->compSolution(map_); if(!solution_found){ // generate the key for the element std::string key = cheapest_leaf->getKey(map_size_.x_); // check that this node has not already been found, if so, remove it bool unique_node = paths.nodeUnique(key); bool valid_node = false; std::vector< pos_t > * diamonds; if(unique_node){ paths.addChild(cheapest_leaf, key); // get diamonds pointer diamonds = cheapest_leaf->getDiamonds(); // check that the node is valid (all diamonds are in valid positions) valid_node = validNode(diamonds, deadlock_map); } else{ paths.deleteChild(cheapest_leaf); } std::vector< std::vector<char> > wf_map; if(unique_node && valid_node){ wf_map = map_; // make wf map for(int d = 0; d < diamonds->size(); d++){ int x = (*diamonds)[d].x_; int y = (*diamonds)[d].y_; wf_map[y][x] = MAP_DIAMOND; } // make wavefront from pos to see the distance to the diamonds std::vector< pos_t > robot_position = {*(cheapest_leaf->getRobotPos())}; wavefront(wf_map, robot_position); // find the diamonds that can be moved std::vector< node > moves; possibleMoves(wf_map, diamonds, moves, cheapest_leaf); // add the moves to the heap (does not take care of states being the same) for(int newChild = 0; newChild < moves.size(); newChild++){ // update heuristics first moves[newChild].updateHeuristic(heuristic_map); // add the child // paths.createChild(moves[newChild]); } paths.createChild(moves); } } else{ // return shortest path node * parent = cheapest_leaf->getParent(); node * child = cheapest_leaf; path_ = ""; while(parent != nullptr){ std::vector< pos_t > p_diamonds; std::vector< pos_t > c_diamonds; std::vector< std::vector<char> > wf_map; p_diamonds = *(parent->getDiamonds()); c_diamonds = *(child->getDiamonds()); // set diamonds to walls to generate wfamp to move with wf_map = map_; for(int d = 0; d < p_diamonds.size(); d++){ int x = (p_diamonds)[d].x_; int y = (p_diamonds)[d].y_; wf_map[y][x] = MAP_DIAMOND; } // robot pos pos_t p_position = *(parent->getRobotPos()); pos_t c_position = *(child->getRobotPos()); std::vector< pos_t > wf_start = {p_position}; wavefront(wf_map, wf_start); // find the diamond that was moved int p_d = 0; int c_d = 0; while(p_diamonds.size() != 1){ bool somethingremoved = false; c_d = 0; while(c_d < c_diamonds.size() && !somethingremoved){ if((p_diamonds)[p_d].y_ == (c_diamonds)[c_d].y_ &&(p_diamonds)[p_d].x_ == (c_diamonds)[c_d].x_){ // remove the diamond p_diamonds.erase(p_diamonds.begin() + p_d); c_diamonds.erase(c_diamonds.begin() + c_d); somethingremoved = true; } c_d++; } p_d++; if(p_d >= p_diamonds.size()){ p_d = 0; } } // adjust the start pos to be t push spot int x = (p_diamonds)[0].x_ - (c_diamonds)[0].x_; int y = (p_diamonds)[0].y_ - (c_diamonds)[0].y_; c_position.x_ += x; c_position.y_ += y; // find sub path std::string subpath = ""; findSubPath(subpath,wf_map, p_position, c_position); // add the final push if(x == 1 && y == 0){ subpath += "W"; } else if(x == -1 && y == 0){ subpath += "E"; } else if(x == 0 && y == 1){ subpath += "N"; } else if(x == 0 && y == -1){ subpath += "S"; } // add the path path_ = subpath + path_; // find new nodes child = parent; parent = child->getParent(); } std::cout << "Cheapest path length: " << cheapest_leaf->getCost() << std::endl; } } if(!paths.getNextChild(cheapest_leaf)){ std::cout << "No more possible paths left to explore.\n"; } std::cout << "# of iterations gone through: " << iterations << "\n"; std::cout << "# of elements in closed list: " << paths.getClosedListSize() << "\n"; std::cout << "# of elements in open list: " << paths.getOpenListSize() << "\n"; return solution_found; }