c++ sort object vector [duplicate] - c++

This question already has answers here:
Sorting a vector of custom objects
(14 answers)
Closed 9 years ago.
I've a question regarding sorting of object in a vector
my object consists of x,y and civ. so I would like to know how do I sort the value of the civ in an descending order but at the same time retaining the value of x and y attached to it..
original
X: 4 Y: 5 CIV: 10
X: 3 Y: 2 CIV: 30
X: 3 Y: 3 CIV: 05
sorted
X: 3 Y: 2 CIV: 30
X: 4 Y: 5 CIV: 10
X: 3 Y: 3 CIV: 05
missionplan.cpp
for(int j=0; j < 5; j++)
{
for(int i = j; i < topfive.size(); i++)
{
if(topfive[i].getcivIndex() < topfive[i].getcivIndex)
{
topfive[i].swap(topfive[i]);
}
}
pointtwoD = topfive.at(i);//display all data starting from the first index
pointtwoD.displayPointdata();
}

You have a misktake in your code.
if(topfive[i].getcivIndex() < topfive[i].getcivIndex) //The second i should be j
{
topfive[i].swap(topfive[i]); // which should be topfive[j].swap(topfive[i])
}

Related

how to calculate multiset of elements given probability on each element?

let say I have a total number
tN = 12
and a set of elements
elem = [1,2,3,4]
and a prob for each element to be taken
prob = [0.0, 0.5, 0.75, 0.25]
i need to get a random multiset of these elements, such as
the taken elements reflects the prob
the sum of each elem is tN
with the example above, here's some possible outcome:
3 3 2 4
2 3 2 3 2
3 4 2 3
2 2 3 3 2
3 2 3 2 2
at the moment, maxtN will be 64, and elements the one above (1,2,3,4).
is this a Knapsack problem? how would you easily resolve it? both "on the fly" or "pre-calculate" approch will be allowed (or at least, depends by the computation time). I'm doing it for a c++ app.
Mission: don't need to have exactly the % in the final seq. Just to give more possibility to an elements to be in the final seq due to its higher prob. In few words: in the example, i prefer get seq with more 3-2 rather than 4, and no 1.
Here's an attempt to select elements with its prob, on 10 takes:
Randomizer randomizer;
int tN = 12;
std::vector<int> elem = {2, 3, 4};
std::vector<float> prob = {0.5f, 0.75f, 0.25f};
float probSum = std::accumulate(begin(prob), end(prob), 0.0f, std::plus<float>());
std::vector<float> probScaled;
for (size_t i = 0; i < prob.size(); i++)
{
probScaled.push_back((i == 0 ? 0.0f : probScaled[i - 1]) + (prob[i] / probSum));
}
for (size_t r = 0; r < 10; r++)
{
float rnd = randomizer.getRandomValue();
int index = 0;
for (size_t i = 0; i < probScaled.size(); i++)
{
if (rnd < probScaled[i])
{
index = i;
break;
}
}
std::cout << elem[index] << std::endl;
}
which gives, for example, this choice:
3
3
2
2
4
2
2
4
3
3
Now i just need to build a multiset which sum up to tN. Any tips?

Matrix multiplying method gives out additional column filled with zeros

I wrote a method that multiplies matrices. It works fine, but gives additional column of zeros. The result of multiplying is correct. Here is the code of method:
Matrix Matrix::multiplyMatrix(Matrix second)
{
vector<vector<double> > sum(vec.size(), vector<double> (vec[0].size()));
if (vec[0].size()!=second.vec.size())
{
throw "Dimensions are not correct";
}
else
{
for (int i=0; i<vec.size(); i++)
{
for (int j=0; j<second.vec[0].size(); j++)
{
sum[i][j]=0;
for (int k=0; k<vec[0].size(); k++)
{
sum[i][j]+=vec[i][k]*second.vec[k][j];
}
}
}
Matrix out(vec.size(), vec[0].size());
out.vec=sum;
return out;
}
}
From main:
Matrix A("A.txt",3,4);
Matrix B("B.txt",4,3);
auto C=A.multiplyMatrix(B);
C.write("C.txt");
Matrices:
A:
2 3 4 4
1 2 4 6
1 1 0 1
and
B:
1 2 3
5 6 7
9 1 5
4 5 5
Instead of 3x3 matrix it gives:
69 46 67 0
71 48 67 0
10 13 15 0
Do you know what is the problem?
Thanks
Your matrix named "out" has the wrong dimensions, also, int the first line of your code, the sum has wrong dimensions too.
the first line should change to:
vector<vector<double> > sum(vec.size(), vector<double> (second.vec[0].size()));
the definition of out should change to:
Matrix out(vec.size(), second.vec[0].size());

find adjacent vertical elements in a grid

I'm having trouble figuring out the thought process behind grabbing adjacent vertical elements in a grid. Say I have a 5x5 grid:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
I want to find all adjacent horizontal and vertical adjacent elements and place them into an array. The size of the array is given by the possible number of walls between each element (not counting the outside) e.g.
1 | 2 | 3
--- --- ---
4 | 5 | 6
A graph of 2x3 has 7 walls so the array would look like
1 2
2 3
4 5
5 6 //end of horizontal walls
1 4 //beginning of vertical walls
2 5
3 6
now I've figured out how to find all horizontal walls given rows and cols, where walls is the array I will be storing the result in:
//find all horizontal walls in grid
//2-d array to store the element between the wall (0 1) (1 2)
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols-1; c++){
int s = r > 0 ? -1*r : 0; //after first row always write over last space
walls[r*rows+c+s][0] = r*rows+c;
walls[r*rows+c+s][1] = r*rows+c+1;
}
}
but I'm just getting lost on figuring out how to determine all vertical walls, in a grid of 5x5 for example the vertical walls would be
0 5
5 10
10 15
15 20
1 6
6 11
etc...
here's what I'm currently trying:
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
//just print the values at the moment, setting walls properly is easy
std::cout << r*rows+c*cols << " " << r*rows+c*cols+5 << std::endl;
}
}
only problem is this does not reset after the first column to 1, instead it continues on like:
0 5
5 10
10 15
15 20
20 25 //nope, should be 1 6
and suggestions? pseudo-code is much appreciated I would prefer an explanation over code
Ok, just figured out the solution so I'll post all I did:
the problem I had was rows did not recent back to 1 when the inner for loop left and started again, this was because I was still multiplying r by rows, this was actually a really simple fix:
r*rows+c*cols << " " << r*rows+c*cols+5 <<
becomes
r+c*cols << " " << r+c*cols+5 <<
I also was running the inner for loop one too many times so, changing
c < cols should become c < cols-1 and now my output is:
0 5
5 10
10 15
15 20
1 6
6 11
11 17
etc...

Why does my multidimensional vector only push_back 0 index?

I having a problem using push_back(), I can't figure out why only the first cols vector is just pushed over and over again.
Input
10 9 10 3 100 8 7 10 73 9 10 5 9 87 -1 8 3 7 10 92 6 10 6 83 9 11 8 8 77 -1 10 10 10 10 100 10 10 10 100 10 10 10 10 100 -1 DONE
C++
(...)
size = numbers.size();
counter = 0;
square = ceil(sqrt(size));
vector < vector <int> > rows;
vector<int> cols;
do {
for (int i = 0; i < square; ++i) {
cols.push_back(numbers[counter]);
cout << cols[i] << " ";
++counter;
}
rows.push_back(cols);
cout << endl;
} while (counter <= size);
(...)
Undesirable Output
0: 10 9 10 3 100 8 7
1: 10 9 10 3 100 8 7
2: 10 9 10 3 100 8 7
3: 10 9 10 3 100 8 7
4: 10 9 10 3 100 8 7
5: 10 9 10 3 100 8 7
6: 10 9 10 3 100 8 7
rows[1][2] should be 73, not 9. Where have I gone wrong?
You never reset cols. Instead you just keep adding on to it. I think you are printing rows out with magic number indices, which is why you do not spot the added portion. Either declare a temporary cols inside the loop or call clear after each push_back().
awesomeyi found your main problem. But your code has other issues too.
There is a buffer overflow. For example if size == 4 then square == 2
and we get:
after iter #1: counter == 2; continue since 2 <= 4
after iter #2: counter == 4; continue since 4 <= 4
iter #3: reads numbers[4] and numbers[5] - oops!
The loop condition should be:
while (counter + square <= size);
we need to make sure that the next iteration will complete without overflowing the vector. It would be smart to use .at() for vector access so that if you did make a miscalculation, then the error will behave nicely instead of going screwball.
The loop (minus the output) could actually be written as:
for (size_t counter = 0; counter + square <= size; counter += square )
{
std::vector<int> cols( numbers.begin() + counter, numbers.begin() + counter + square );
rows.push_back(cols);
}

c++ after finding the path from an A* search, printing the path continually prints the same Nodes information

I have managed to produce an A* search using c++ (all though it can probably be done much more efficiently) it does it fact go from the start [x][y] to the goal[x][y] and terminates.
Th problem i am having is when i want to print this path in terms of which coordiantes were following i try to do this by following pointers to each Nodes parent and keep doing thing untill the pointer == NULL.
The problem is when i execute my print method it constantly prints the coordinates of the final state, rather than following the pointer to it's parent untill there is no parent (back at the root Node)
Node.h
class Node{
private:
int xCoord;
int yCoord;
int value;
double fCost;
double gCost;
double hCost;
Node* parent;
public:
Node();
Node(int x, int y, int value, int cost, Node* parent);
void setParent(Node* parent);
int getX();
int getY();
int getValue();
double getHCost();
double getFCost();
double getGCost();
Node* getParent();
void setHCost(double hCost);
};
struct NodeComparator {
bool operator()(Node& first, Node& second) {
return (first.getFCost() < second.getFCost());
}
};
Node.cpp
Node::Node(){
this->xCoord = 0;
this->yCoord = 0;
this->value = 0;
this->parent = NULL;
this->fCost = 0;
this->gCost = 0;
this->hCost = 0.0;
}
Node::Node(int _x, int _y, int _value, int cost, Node* parent){
this->xCoord = _x;
this->yCoord = _y;
this->value = _value;
this->gCost = cost;
this->parent = parent;
this->hCost = 0.0;
this->fCost = 0;
}
void Node::setParent(Node* par){
this->parent = par;
}
int Node::getX(){
return xCoord;
}
int Node::getY(){
return yCoord;
}
int Node::getValue(){
return value;
}
double Node::getGCost(){
return gCost;
}
double Node::getFCost(){
return gCost + hCost;
}
double Node::getHCost(){
return hCost;
}
Node* Node::getParent(){
return parent;
}
void Node::setHCost(double cost){
this->hCost = cost;
}
The main.cpp file where the actual search takes place:
int main(){
int map[20][20] = {{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,2},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0},
{0,0,3,0,0,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}};
using namespace std;
list<Node> openList;
vector<Node> closedList;
Node end;
Node start = initiateStart(map);
openList.push_front(start);
cout <<"Start index: x " << start.getX() << " y " <<start.getY() << endl;
while (!openList.empty()) {
Node best = openList.front();
openList.pop_front();
if(!checkInClosedList(closedList, best.getX(), best.getY())){
calcManhattanDistance(best, map);
if(best.getValue() == 3){
end = best;
cout <<"end index: x " << end.getX() << " y " <<end.getY() << endl;
checkPath(&end, map);
exit(1);
}
if(map[best.getX()][best.getY()-1] != 1 && best.getY() - 1 > -1){
if(placeInOpen(openList,best.getX(), best.getY() - 1)){
openList.push_front(generateLeftChild(best, map));
}
}
//to the right
if(map[best.getX()][best.getY()+1] != 1 && best.getY() + 1 < 20){
if(placeInOpen(openList,best.getX(), best.getY() + 1)){
openList.push_front(generateRightChild(best, map));
}
}
//above
if(map[best.getX()-1][best.getY()] != 1 && best.getX() - 1 > -1){
if(placeInOpen(openList,best.getX()-1, best.getY())){
openList.push_front(generateAboveChild(best, map));
}
}
//below
if(map[best.getX()+1][best.getY()] != 1 && best.getX() + 1 < 20){
if(placeInOpen(openList,best.getX()+1, best.getY())){
openList.push_front(generateBelowChild(best, map));
}
}
closedList.push_back(best);
}
openList.sort(NodeComparator());
}
return 0;
}
Node initiateStart(int m[20][20]){
Node start;
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
if(m[i][j] == 2){
start = Node(i, j, m[i][j], 0, NULL);
}
}
}
return start;
}
Node generateLeftChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX(), parent.getY() - 1, m[parent.getX()][parent.getY() - 1],
parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
Node generateRightChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() , parent.getY() + 1, m[parent.getX()][parent.getY() + 1],parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
Node generateAboveChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() - 1, parent.getY(), m[parent.getX() - 1][parent.getY()],
parent.getGCost() + 1, &parent);
std::cout << "parent for above child X: " << child.getParent()->getX() <<" Y: "
<< child.getParent()->getY() << std::endl;
calcManhattanDistance(child, m);
return child;
}
Node generateBelowChild(Node parent, int m[20][20]){
Node child;
child = Node(parent.getX() + 1, parent.getY(), m[parent.getX() + 1][parent.getY()],
parent.getGCost() + 1, &parent);
calcManhattanDistance(child, m);
return child;
}
void calcManhattanDistance(Node node, int m[20][20]){
int tempX;
int tempY;
double manhattanDistance;
int differenceX;
int differenceY;
//std::cout << "node x: " << node->getX() << " node y: " << node->getY() << std::endl;
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
if(m[i][j] == 3){
tempX = i;
tempY = j;
}
}
}
//sum of term difference, none of these can be negative hense the std::abs
differenceX = tempX - node.getX();
differenceY = tempY - node.getY();
manhattanDistance = std::abs(differenceX) + std::abs(differenceY);
//std::cout << "Manhattan distance: " << manhattanDistance << std::endl;
node.setHCost(manhattanDistance);
}
bool checkInClosedList(std::vector<Node>& v,int x, int y){
for (std::vector<Node>::iterator iter = v.begin(); iter != v.end(); ++iter) {
if(iter->getX() == x && iter->getY() == y){
return true;
}
}
return false;
}
bool placeInOpen(std::list<Node>& v,int x, int y){
for (std::list<Node>::iterator iter = v.begin(); iter != v.end(); ++iter) {
if(iter->getX() == x && iter->getY() == y){
return false;
}
}
return true;
}
void checkPath(Node *end, int m[20][20]){
int tempX, tempY;
Node *temp = end;
while(temp != NULL){
tempX = temp->getX();
tempY = temp->getY();
std:: cout << tempX << " " << tempY << std::endl;
temp = temp->getParent();
}
printMap(m);
}
void printMap(int m[20][20]){
std::cout << "printy mcprint" << std::endl;
for(int i = 0; i< 20; i++){
for(int j = 0; j< 20; j++){
std::cout << m[i][j];
}
std::cout<<std::endl;
}
}
Sorry for the large code dump, but i assume you will want to see everything just incase i am setting a parent wrong somewhere!
I added a print statement to test how i add the parents, you can see this in the generateAboveChild function, the program produce this output:
Start index: x 0 y 19
parent for above child X: 1 Y: 19
parent for above child X: 2 Y: 19
parent for above child X: 3 Y: 19
parent for above child X: 2 Y: 18
parent for above child X: 1 Y: 17
parent for above child X: 4 Y: 19
parent for above child X: 5 Y: 19
parent for above child X: 4 Y: 18
parent for above child X: 3 Y: 17
parent for above child X: 2 Y: 16
parent for above child X: 1 Y: 15
parent for above child X: 1 Y: 14
parent for above child X: 6 Y: 19
parent for above child X: 7 Y: 19
parent for above child X: 6 Y: 18
parent for above child X: 5 Y: 17
parent for above child X: 4 Y: 16
parent for above child X: 3 Y: 15
parent for above child X: 2 Y: 14
parent for above child X: 3 Y: 14
parent for above child X: 8 Y: 19
parent for above child X: 9 Y: 19
parent for above child X: 8 Y: 18
parent for above child X: 7 Y: 17
parent for above child X: 5 Y: 15
parent for above child X: 4 Y: 14
parent for above child X: 4 Y: 13
parent for above child X: 6 Y: 15
parent for above child X: 8 Y: 17
parent for above child X: 10 Y: 19
parent for above child X: 11 Y: 19
parent for above child X: 10 Y: 18
parent for above child X: 9 Y: 17
parent for above child X: 7 Y: 15
parent for above child X: 6 Y: 14
parent for above child X: 5 Y: 13
parent for above child X: 4 Y: 11
parent for above child X: 8 Y: 15
parent for above child X: 10 Y: 17
parent for above child X: 12 Y: 19
parent for above child X: 13 Y: 19
parent for above child X: 12 Y: 18
parent for above child X: 11 Y: 17
parent for above child X: 9 Y: 15
parent for above child X: 8 Y: 14
parent for above child X: 7 Y: 13
parent for above child X: 6 Y: 12
parent for above child X: 5 Y: 11
parent for above child X: 4 Y: 9
parent for above child X: 3 Y: 10
parent for above child X: 14 Y: 19
parent for above child X: 15 Y: 19
parent for above child X: 14 Y: 18
parent for above child X: 13 Y: 17
parent for above child X: 12 Y: 16
parent for above child X: 10 Y: 14
parent for above child X: 9 Y: 13
parent for above child X: 8 Y: 12
parent for above child X: 7 Y: 11
parent for above child X: 6 Y: 10
parent for above child X: 2 Y: 10
parent for above child X: 5 Y: 9
parent for above child X: 3 Y: 8
parent for above child X: 1 Y: 10
parent for above child X: 7 Y: 10
parent for above child X: 16 Y: 19
parent for above child X: 17 Y: 19
parent for above child X: 16 Y: 18
parent for above child X: 15 Y: 17
parent for above child X: 14 Y: 16
parent for above child X: 13 Y: 15
parent for above child X: 12 Y: 14
parent for above child X: 11 Y: 13
parent for above child X: 10 Y: 12
parent for above child X: 8 Y: 10
parent for above child X: 2 Y: 7
parent for above child X: 1 Y: 8
parent for above child X: 18 Y: 19
parent for above child X: 19 Y: 19
parent for above child X: 18 Y: 18
parent for above child X: 17 Y: 17
parent for above child X: 16 Y: 16
parent for above child X: 15 Y: 15
parent for above child X: 14 Y: 14
parent for above child X: 13 Y: 13
parent for above child X: 12 Y: 12
parent for above child X: 11 Y: 11
parent for above child X: 2 Y: 5
parent for above child X: 1 Y: 6
parent for above child X: 15 Y: 14
parent for above child X: 19 Y: 17
parent for above child X: 18 Y: 16
parent for above child X: 17 Y: 15
parent for above child X: 16 Y: 14
parent for above child X: 14 Y: 12
parent for above child X: 13 Y: 11
parent for above child X: 12 Y: 10
parent for above child X: 3 Y: 4
parent for above child X: 2 Y: 3
parent for above child X: 1 Y: 4
parent for above child X: 13 Y: 10
parent for above child X: 15 Y: 12
parent for above child X: 17 Y: 14
parent for above child X: 19 Y: 15
parent for above child X: 18 Y: 14
parent for above child X: 16 Y: 12
parent for above child X: 15 Y: 11
parent for above child X: 14 Y: 10
parent for above child X: 4 Y: 4
parent for above child X: 5 Y: 4
parent for above child X: 4 Y: 3
parent for above child X: 3 Y: 2
parent for above child X: 2 Y: 1
parent for above child X: 1 Y: 2
parent for above child X: 15 Y: 10
parent for above child X: 17 Y: 12
parent for above child X: 19 Y: 14
parent for above child X: 18 Y: 12
parent for above child X: 17 Y: 11
parent for above child X: 16 Y: 10
parent for above child X: 6 Y: 4
parent for above child X: 7 Y: 4
parent for above child X: 6 Y: 3
parent for above child X: 5 Y: 2
parent for above child X: 4 Y: 1
parent for above child X: 3 Y: 0
parent for above child X: 1 Y: 0
parent for above child X: 19 Y: 12
parent for above child X: 19 Y: 11
parent for above child X: 18 Y: 10
parent for above child X: 17 Y: 9
parent for above child X: 4 Y: 0
parent for above child X: 8 Y: 4
parent for above child X: 9 Y: 4
parent for above child X: 8 Y: 3
parent for above child X: 7 Y: 2
parent for above child X: 6 Y: 1
parent for above child X: 5 Y: 0
parent for above child X: 19 Y: 9
parent for above child X: 18 Y: 8
parent for above child X: 17 Y: 7
parent for above child X: 6 Y: 0
parent for above child X: 10 Y: 4
parent for above child X: 11 Y: 4
parent for above child X: 10 Y: 3
end index: x 9 y 2
But, when i uncomment the line which calls checkPath(&end, map);(this is near the top of main.cpp under the if conditon if(best.getValue() == 3) the i get this output: ( i have removed the cout print for the "parent for above child")
Start index: x 0 y 19
9 2
9 2
9 2
9 2
9 2
9 2
9 2
and these 9 2 prints continue forever, i assume the problem is in the printPath function ive tried debugging it but i cant see what i am doing wrong.
Cheers,
Chris.
I changed my implementation of how Node are handled and stored Node* rather than Node Objects in my list and vector as well as using the new keyword on creation. This resolved my problem my A* now works.