Algorithm Help for Directed Graph List - c++

I have an assignment for my class where we are attempting to find the best (cheapest) path to a destination. The description is as follows:
Each tech has a name, a cost to buy that tech, a boolean saying whether or not the player has the tech already, and a list of 0 to N techs that are available for purchase when the player buys this tech. There are three categories of tech in Tactigo: Social, Military, and Science. Each of the three starts with a basic tech that the player must purchase before purchasing more advanced techs. These basic techs are special because they are always available for purchase.
Looking at the diagram, you will note that a few techs are unlocked by multiple techs. Remember that techs are unlocked as soon as ANY tech unlocks them. In other words, you need either "Being Nice to Animals" OR "Being a Dick to People" in order to buy "Attack Animal Training". You don't need both, just one. Your task is to find the cheapest way to get any given technology. The player might own any set of techs already, so you must account for that. For example, if the player already owns "Being Nice to People" and wants to find the cheapest way to get "Making Friends", the path returned should just be "Making Friends". They don't need to purchase anything else.
The Graph looks as follows:
I originally thought of doing a depth-first-search on each of the 3 categories while calculating the cost of each path taken. My Code for this function is as follows:
//---------------------------------------------------------------------------------------------------------------------
// This function finds the best path to the tech we want.
// * goalTech: The index of the tech we're looking for. Call GetTechByIndex() to get the actual Tech instance.
// * bestPath: The best path to the goal tech. This is an array sorted in the order of the best path from the
// start to the goal. This is an output variable; it's what you need to populate with this function.
//---------------------------------------------------------------------------------------------------------------------
void TechTree::FindBestPath(int goalTech, Path& bestPath)
{
//First ensure that best path is cleared out
bestPath.clear();
//Get Tech Instance for this Goal Tech
const Tech* pGoalTech = GetTechByIndex(goalTech);
//make sure we get a valid tech
assert(pGoalTech != nullptr);
//Check first if user already has this unlocked.
if (pGoalTech->HasTech())
{
//just return
return;
}
//Check if the goal tech is one of the three starting techs.
if (pGoalTech == GetBasicSocialTech()|| pGoalTech == GetBasicScienceTech() || pGoalTech == GetBasicMilitaryTech())
{
//now we know that one of the basic techs are the goal, so we just add one of those to the path
if (pGoalTech == GetBasicSocialTech())
bestPath.push_back(GetBasicSocialTech());
else if (pGoalTech == GetBasicMilitaryTech())
bestPath.push_back(GetBasicMilitaryTech());
else
bestPath.push_back(GetBasicScienceTech());
return; //now return
}
//my process will be as follows.
//1. Since all the edges are directed we need to traverse down three different graphs: Social (starting at index 0), Military (starting at index 4) and Science (starting at index 8)
//2. I am going to perform a depth-first search starting at Social and then moving down to Military and then Science.
//3. As I am performing a depth-first I am going to keep track of a path and its respective cost, if a search gets to the goal I will make sure to register that and then move onto the next graph.
//4. When there are no more paths to search I send the lowest cost one back.
///start with social at index 0
const Tech* pStartSocialTech = GetBasicSocialTech();
std::pair<int, std::vector<const Tech*>> bestCurrentPath;
//get starting cost for this category before we move into neighbors,
// if player already has this tech we set this to zero if not we get the cost of buying into this category
int startingCost = pStartSocialTech->HasTech() ? 0 : pStartSocialTech->GetCost();
/*pStartSocialNeighbors = get all neighbors for starting point at social
while (destination is not found AND there are more neighbors to pStartSocialNeighbors)
{
DFS(neighbor, dest) //if this finds the destination we store a path and its cost, otherwise it doesnt do anything and we move on to next basic tree
}
//do the same thing for military and science...
*/
}
I have a lot of comments on it but I am just wondering if this is the best route to take. Other options are Dijkstras or A* but I don't know how you would traverse the path of this directed graph. I am not looking for a direct answer since this is a homework assignment but I am looking for some guidance.
Thanks!

Going from the target to source using Dijkstras, you need to modify the stop condition if you want to stop before searching all paths. I don't see any heuristic for A* in this case.
Adding a node with a path to all known techs
You can now use Dijkstras / Bellman-Ford.
Using A* has the problem you need to find a heuristic that works. You could use depth times min cost of all edges. that requires you to already have traversed the graph to assign depth.

Related

calculating distance between vehicles and setting speed so the distances remain the same e.g 5 meters

I am using veins 5.0 and i am trying to calculate the distance between the vehicles and setting their speed. I want to calculate it every second and i want to do it by sending wsm messages.My goal is to have for example 5 vehicles, each vehicle will communicate with the front vehicle and get its position with the intention of calculating their distance and keep it static. I am new to this and i don't know how to approach it.
I tried to do something like this on handlePositionUpdate
void TraCIDemo11p::handlePositionUpdate(cObject* obj)
{
DemoBaseApplLayer::handlePositionUpdate(obj);
// stopped for for at least 10s?
if (x<simTime()){
TraCIDemo11pMessage* wsm1 = new TraCIDemo11pMessage();
populateWSM(wsm1);
wsm1->setPosition(mobility->getPositionAt(simTime()));
wsm1->setSpeed(mobility->getSpeed());
if (dataOnSch) {
startService(Channel::sch2, 42, "Traffic Information Service");
message to self to send later
scheduleAt(computeAsynchronousSendingTime(1,ChannelType::service), wsm1);
}
else {
sendDown(wsm1);
}
}
You are describing what is, effectively, a platooning application. You might want to base your source code on Plexe, the platooning extension to Veins. It already comes with state-of-the-art distance controllers like PATH or Ploeg. More information can be found on http://plexe.car2x.org/

Is there is a way to get the associated MN's to an access point?

I'm using INET and want to simulate a scenario that consist of three Access Points (AP)and one Mobile Node (MN), may each AP has other associated MNs on its range, what I want is : while the MN (in my scenario) move around and get beacons from the APs, before association with APs can I get the number of other MNs that associated with each AP? I explored many source codes and I found MACaddressTable and something like that stalist in ieee80211MgmtAP ,are they useful for me? and use them as total Number of associated MNs,
then How can I evaluate the length of stalist? or MACaddressTable?
else I must put a counter to count that at on AP side and emit it through beacon frame? if so please give me some guides or shortcuts
regards ....
In IEEE 802.11 AP does not send information about the number of associated stations. Therefore in order to broadcast this information you have to introduce your own modification/extension into IEEE 802.11 protocols, for example a new field in beacon frame.
In INET model AP stores own stations in staList map. To locally calculate the current number of associated station you can use the following code:
STAList::const_iterator it;
int assocSta = 0;
for (it = staList.begin(); it != staList.end(); ++it) {
if (it->second.status == ASSOCIATED)
assocSta++;
}
If you want modify standard beacon frame, firstly, you have to assume where exactly you want to add a new field in beacon frame, e.g. after which existing field, as well as what size this filed should have. Then:
add a new filed (for example int noOfAssociatedStas;) in class Ieee80211BeaconFrameBody in file Ieee80211MgmtFrames.msg and correct length in Ieee80211BeaconFrame definition
in Ieee80211Serializer.cc after else if (dynamic_cast<const Ieee80211BeaconFrame *>(pkt)) add serialization of a new field, for example:
unsigned int numSta = Frame->getBody().getNoOfAssociatedStas();
b.writeByte(numSta); // assuming that the new field is 1 byte length
in Ieee80211Serializer.cc in deserialize add deserialization of a new field, after case 0x80: //ST_BEACON for example:
unsigned int numSta = b.readByte();
Please note that the place of adding the new filed (second bullet) must exactly match the place of reading it (third bullet).

Battleships game - keeping track of ships

I've searched my best on here in order to find the answer to my question but there's either no results or I'm not searching the right thing, but anyway...
The battleships game I need to create has to have: 1 Aircraft Carrier of length 5, 2 battleships of length 4, 3 destroyers of length 3 and 4 submarines of length 2.
I have a ship class which holds data such as the id, name, x, y and direction.
I then have a board class which then needs to instantiate all these ships. I'm doing this by making a vector of type Ship and pushing ship objects onto that.
However each ship objects needs to store all the x and y values of that ship and I'm stuck on how to do that. I wanted to post code but it's non functional and looks messy at the moment which is probably not beneficial to anyone. However if necessary I can write the skeleton again and post it up here.
Thanks in advance.
If you have x, y and direction then the points of the ship can be calculated from it's size
Each ship could just have a vector<Point> inside. Checking for hit could be then:
Point guess;
for (auto& ship : ships) {
for (auto& point : ship.points) {
if (point == guess)
// hit
}
}
That would make sense if you are aiming for a version where you need to hit the ship once in each of its parts.
The inner loop can also be easily changed to std::find, making it arguably more clear.

Am I violating an OOP design guideline here? Couple of interesting design pickles

I'm designing a new power-up system for a game I'm creating. It's a side scroller, the power ups appear as circular objects and the player has to touch / move through them to pick up their power. The power up then becomes activated, and deactivates itself a few seconds later. Each power-up has its own duration defined. For simplicity's sake the power ups are spawned (placed on the screen) every X seconds.
I created a PowerUpManager, a singleton whose job is to decide when to create new power ups and then where to place them.
I then created the Powerup base class, and a class that inherits from that base class for every new Powerup. Every Power-up can be in one of three states: Disabled, placed on the screen, and picked up by the player. If the player did not pick up the power up but moved on, the power up will exit the screen and should go back from the placed state to the disabled state, so it can be placed again.
One of the requirements (that I) put in place is that there should be minimal code changes when I code up a new Power up class. The best I could do was one piece of code: The PowerUpManager's constructor, where you must add the new power-up to the to the container that holds all power-ups:
PowerupManager::PowerupManager()
{
available = {
new PowerupSpeed(),
new PowerupAltWeapon(),
...
};
}
The PowerUpManager, in more details (Question is coming up!):
Holds a vector of pointers to PowerUp (The base class) called available. This is the initial container that holds one copy of each power up in the game.
To handle the different states, it has a couple of lists: One that holds pointers to currently placed power ups, and another list that holds pointers to currently active power ups.
It also has a method that gets called every game tick that decides if and where to place a new power up and clean up power ups that weren't picked up. Finally it has a method that gets called when the player runs into a power up, that activates the power up (Moves it from the placed to the active list, and calls the power up's activate method).
Finally, once you understand the full picture, the question:
I needed a way for client code to ask if a particular power-up is currently active. For example: The player has a weapon, but there is a power up that replaces that weapon temporarily. Where I poll for input and recognize that the player wants to fire his weapon, I need to call the correct fire method - The alternative weapon power up fire method, and not the regular weapon fire method.
I thought of this particular demand for a while and came up with this:
template <typename T>
T* isActivated() // Returns a pointer to the derived Powerup if it exists in the activated list, or nullptr if it doesn't
{
for(Powerup *i : active) // Active is a list of currently active power ups
{
T *result = dynamic_cast<T*>(i);
if(result)
return result;
}
return nullptr;
}
So client code looks like this:
PowerUpAltWeapon *weapon = powerUpManager->isActivated<PowerUpAltWeapon>();
if(weapon)
...
I thought the solution is elegant and kind of neat, but essentially what it is is trying to convert a base type to a derived type. If that doesn't work, you try the next derived type... A long chain of if / else if, it's just disguised in a loop. Does this violate the guideline that I just described? Not casting a base type to all of its derived types in a long chain of if / else if until you get a hit? Is there another solution?
A secondary question is: Is there a way to get rid of the need to construct all the different power ups in the PowerupManager constructor? That is currently the only place you need to make a change if you want to introduce a new power up. If I can get rid of that, that'd be interesting...
This is based on your design, but if it was me I choose an ID for each PowerUp and a set of IDs in the client, and each time a user posses a PowerUp that ID will be added to its set and ... you know the rest. Using this technique I can do fast look up for every PowerUp and avoid dynamic_cast:
std::set<PowerUp::ID> my_powerUps;
template< class T > bool isActivated() {
return my_powerUps.find( T::id() ) != my_powerUps.end();
}
And about your second question, I have a similar program that load some plugins instead of PowerUp, I have a pure virtual base class that contain all methods that required by that plugin and implement it in shared modules and then at startup I load them from an specific folder. For example each shared module contain a create_object that return a plugin* (in your case PowerUp* of course) and then I iterate the folder, load modules and call create_object to create my plugins from them and register them in my plugin_manager

Best tree/heap data structure for fixed set of nodes with changing values + need top 20 values?

I'm writing something like a game in C++ where I have a database table containing the current score for each user. I want to read that table into memory at the start of the game, quickly change each user's score while the game is being played in response to what each user does, and then when the game ends write the current scores back to the database. I also want to be able to find the 20 or so users with the highest scores. No users will be added or deleted during the short period when the game is being played. I haven't tried it yet, but updating the database might take too much time during the period when the game is being played.
Fixed set of users (might be 10,000 to 50,000 users)
Will map user IDs to their score and other user-specific information.
User IDs will be auto_increment values.
If the structure has a high memory overhead that's probably not an issue.
If the program crashes during gameplay it can just be re-started.
Greatly prefer something already available, such as open source/public domain code.
Quickly get a user's current score.
Quickly add to a user's current score (and return their current score)
Quickly get 20 users with highest score.
No deletes.
No inserts except when the structure is first created, and how long that takes isn't critical.
Getting the top 20 users will only happen every five or ten seconds, but getting/adding will happen much more frequently.
If not for the last, I could just create a memory block equal to sizeof(user) * max(user id) and put each user at user id * sizeof(user) for fast access. Should I do that plus some other structure for the Top 20 feature, or is there one structure that will handle all of this together?
Use a std::map. In the incredibly unlikely event that it ever shows up in your profiling, you could maybe think about changing to something more exotic. Memory overhead for 50k users will be around a megabyte or two.
I doubt that iterating over a map with 50k entries every 5-10 seconds, to find the top scores, will introduce significant overhead. If it does, though, either use a Boost multi-index container, or maintain a separate structure for the hi-scores (a heap, or just an array of pointers to the current top 20, in order). Just with an array / vector of 20, the code to increment a score might look something like this (assuming scores only go up, not down):
player.score += points;
if (player.score > hiscores[19]->score) {
hiscore_dirty = true;
}
And the code to get the hi-scores:
if (hiscore_dirty) {
recalculate_hiscores();
hiscore_dirty = false;
}
std::for_each(hiscores.begin(), hiscores.end(), do_something);
If your "auto-increment" and "no delete" policies are fixed forever (i.e. you will never delete users from the DB), and therefore user ids truly are a contiguous range from 0 to the limit, then you should just use a std::vector instead of a std::map.
You might be interested in Fibonacci Heap. This has O(1) (amortized) increaseKey and findMax.
For more info on Heap in general refer: Heap Data Structure, especially the table which compares different heaps.
An implementation of Fibonacci Heap can be found here which you can perhaps use/get inspired from: http://resnet.uoregon.edu/~gurney_j/jmpc/fib.html
First of all, given that you have a Key/Value scenario, you should probably use an Associative Container.
If you are using plain old C++ and do not have Boost available, follow Steve Jessops's suggestion and simply use a std::map, if you have either C++0x or Boost, you'd better use a hash_map or unordered_map: it just matches your requirements better (you don't need to order the players by id after all, you just want to find them quickly) and will probably be faster given the number of players.
For managing the top20 you have 2 choices:
You could use the Boost.MultiIndex library to create one unique container that both offers fast lookup on ID (using a hash map) and an ordered index on the score... however it's a bit of a waste to order all players when you only need 20 of them
You can simply manages a separate structure, like a vector of pointers to users, and each time you modify the score of a user check it should replace a user in the vector
The last solution, though simple, assumes that a player cannot lose points... it's much more difficult if that may happen.
class UsersCollection;
class User
{
public:
void incrementScore(size_t term);
private:
size_t mId;
size_t mScore;
UsersCollection& mCollection;
};
class UsersCollection
{
public:
static const size_t MNumberHiScores = 20;
static const size_t MNotAChampion = -1;
UsersCollection(DBConnection const&);
// returns either the position of the user in
// the hi scores vector or MNotAChampion
size_t insertUserInHiScores(User const& user);
private:
std::unordered_map<size_t, User> mUsers;
std::vector<User const*> mHiScores; // [1]
};
void User::incrementScore(size_t term)
{
mScore += term;
mCollection.insertUserInHiScores(*this);
}
struct UserSort: std::binary_function<User const*, User const*, bool>
{
bool operator()(User const* lhs, User const* rhs) const
{
return lhs->score() > rhs->score();
}
};
size_t UsersCollection::insertUserInHiScores(User const& user)
{
std::vector<User const*>::const_iterator it =
std::find(mHiScores.begin(), mHiScores.end(), &user);
if (it == mHiScores.end()) // not among the hiscores
{
mHiScores.push_back(&user);
}
std::sort(mHiScores.begin(), mHiScores.end(), UserSort());
if (mHiScores.size() > MNumberHiScores) // purge if too many users
{
User const* last = mHiScores.back();
mHiScores.pop_back();
if (&user == last) return MNotAChampion;
}
// return position in the vector in the [0, MNumberHiScores) range
return std::find(mHiScores.begin(), mHiScores.end(), &user)
- mHiScores.begin();
}
Note (1): using a set may seem a good idea however a set presumes that the elements do not change and it is not the case. It could work if we were very careful:
remove the user from the set before changing the score
putting the user back in once it has changed
optionally popping the last elements if there are too many of them