I am reading some coordinates from a file and trying to assign them cell values (0-2) by diving them into a 3x3 grid. For some values the code is assigning negative cell values like for x=268 or x=269. Where am I going wrong?
I have file output.txt as follows with :
76 62
77 62
78 62
79 62
81 62
83 62
86 62
etc
The code to assign cells:
int x_points[99];
int y_points[99];
int i=0;
int x,y;
int max_x, max_y;
int min_x, min_y;
while(out.good())
{
out>>x;
out>>y;
if(i==0)
{
max_x=x;
min_x=x;
min_y=y;
max_y=y;
}
else if (x>max_x)
{
max_x=x;
}
else
if(x < min_x)
{
min_x=x;
}
else if (y>max_y)
{
max_y=y;
}
else
if(y < min_y)
{
min_y=y;
}
x_points[i]=x;
y_points[i]=y;
i++;
}
for(i=0; i<99; i++)
cout<<x_points[i]<<","<<y_points[i]<<"\n";
int cells_x[99];
int cells_y[99];
float x_width;
float y_width;
int divide = 3;
//To find out the cells. Divide it by 20
x_width=(max_x-min_x)/divide;
y_width=(max_y-min_y)/divide;
cout<<"\nx_width:"<<x_width;
cout<<"y_width:"<<y_width<<"\n";
int x1;
int y1;
for(i=0; i<99; i++)
{
x1=x_points[i]-min_x;
y1=y_points[i]-min_y;
for(int j=0; j<divide; j++)
{
if(j*x_width<=x1 && x1<((j+1)*x_width))
cells_x[i]=j;
if(j*y_width<=y1 && y1<((j+1)*y_width))
cells_y[i]=j;
}
cout<<cells_x[i]<<" "<<i<<" "<<cells_y[i]<<"\n";
}
The first problem I see is where you try to find the maximum and minimum values of x and y:
if(i==0)
{
max_x=x;
min_x=x;
min_y=y;
max_y=y;
}
else if (x>max_x)
{
max_x=x;
}
else if(x < min_x)
{
min_x=x;
}
else if (y>max_y) /* <-- This should not have an else! */
{
max_y=y;
}
else if(y < min_y)
{
min_y=y;
}
As written, it prevents the analysis of y values when an x is a new max or min. This will cause issues with the rest of your program, since max_y and min_y don't actually contain the max and min.
Next up is calculating the x_width and y_width:
x_width=(max_x-min_x)/divide; // should be x_width=(max_x-min_x + 1)/divide;
y_width=(max_y-min_y)/divide; // y_width=(max_y-min_y + 1)/divide;
If max_x = 8, and min_x = 0, your code would result in x_width = 8/3, or about 2.6666666666666666666666666666667. But 0-8 can be split up into 3 groups of 3. Adding 1 corrects this by calculating the number of points, not the length of the line.
It also prevents you from having a width of 0, which would happen if max_x == min_x. A width of 0 causes trouble in the next section:
for(int j=0; j<divide; j++)
{
/* an x_width of 0 will cause this to never evaluate to true */
/* x1 cannot ever be >= to 0 AND < 0 */
if(j*x_width<=x1 && x1<((j+1)*x_width))
cells_x[i]=j;
if(j*y_width<=y1 && y1<((j+1)*y_width))
cells_y[i]=j;
}
if x_width is zero, then you will never assign a value to cells_x[i], meaning it will still be set to its initialization value, which could be a negative number.
Related
Just started using cLion as an ide for c++. Am attempting to run this block of code where it reads a csv file and stores the values in a 189 x 141 2d vector. It then iterates through 5 for loops. Everything was running smoothly until I included the 5 nested for loops; at this point I was seeing the "Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)" message upon executing. I have seen an answer to a similar question claiming that it is the result of a lack of memory on my computer. Would this be the case?
When the first 3 for loops have ib0, ib1, ib2 iterate from 0 to 100, it would of course mean that there are over 26 billion iterations in total. However, when I reduce this range to 0 to 1, I still receive the message.
For reproducibility, I just have the ROB vector be 189 x 141 random values.
EDIT: If anyone runs this code, let me know how long it takes?
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
double innerarrayval;
vector<vector<double>> ROB;
vector<double> innerarray;
for(int x=0;x<189;x++) {
innerarray.clear();
for (int y = 0; y < 141; y++) {
innerarrayval = rand() % 1000;
innerarray.push_back(innerarrayval);
}
ROB.push_back(innerarray);
}
double b0,b1,b2;
int nnb;
double chisquared, amean, content, sumpart, sumpartsquared,chisquaredNDOF,chimin;
double b0mem, b1mem, b2mem;
chimin = 1000.0;
for(int ib0 = 0; ib0 < 101; ib0++)
{
b0 = 15.0 + 0.1 * (ib0 - 1);
for(int ib1 = 0; ib1 < 101; ib1++)
{
b1 = -0.002 * (ib1 - 1);
for(int ib2 = 0; ib2 < 101; ib2++)
{
b2 = 0.002 * (ib2 - 1);
nnb = 0;
chisquared = 0;
amean = 0;
for(int i = 0; i <= 189; i++)
{
for(int j = 0; j <= 141; j++)
{
if((i >= 50 and i <= 116) and (j >= 42 and j <= 112))
{
continue;
}
else
{
content = ROB[i][j];
if(content == 0)
{
content = 1;
}
amean = amean + content;
sumpart = (content - b0 - (b1 * i) - (b2 * j))/sqrt(content);
sumpartsquared = pow(sumpart, 2);
chisquared = chisquared + sumpartsquared;
nnb = nnb + 1;
}
}
}
chisquaredNDOF = chisquared/double(nnb);
amean = amean/double(nnb);
if(chisquaredNDOF < chimin)
{
chimin = chisquaredNDOF;
b0mem = b0;
b1mem = b1;
b2mem = b2;
}
}
}
}
cout<<"chi squared: "<<chimin<<"\n";
cout<<"b0: "<<b0mem<<"\n";
cout<<"b1: "<<b1mem<<"\n";
cout<<"b2: "<<b2mem<<"\n";
cout<<"mean: "<<amean<<"\n";
return 0;
}
for(int x=0;x<189;x++) {
innerarray.clear();
for (int y = 0; y < 141; y++) {
innerarrayval = rand() % 1000;
innerarray.push_back(innerarrayval);
}
ROB.push_back(innerarray);
}
This part of the initialization loops carefully, and gingerly, initialized the two-dimensional ROB vector. As noted by each for loop's limit, the valid indexes for the first dimension is 0-188, and the 2nd dimension is 0-140.
This is correct. In C++ array/vector indexes start with 0, so for your expected result of a "189 x 141 2d vector", the first index's values range 0-188, and the 2nd one's range is 0-140.
If you proceed further in your code, to the part that reads the two-dimensional matrix:
for(int i = 0; i <= 189; i++)
{
for(int j = 0; j <= 141; j++)
{
And because this uses <=, this will attempt to access values in ROB whose first dimension's index range is 0-189 and the 2nd dimension's index range is 0-141.
The out of bounds access results in undefined behavior, and your likely crash.
You should use this obvious bug as an excellent opportunity for you to learn how to use your debugger. If you used your debugger to run this program, the debugger would've stopped at the point of the crash. If you then used your debugger to inspect the values of all variables, I would expect that the out-of-range values for i or j would be very visible, making the bug clear.
I was trying this problem - Minimum Cost Path.
I have solved the problem using Dijkstra's Shortest Path Algorithm. But when i tried this using recursion+memoisation i.e. using dynamic programming, i got stuck and could not debug my code. I need help as to where my code is wrong!!
I am really glad for the help.
#include<bits/stdc++.h>
using namespace std;
int n;
int a[105][105], dp[105][105];
int dfs(int x, int y){
if(x < 0 || y < 0 || x >= n || y >= n){
return INT_MAX;
}
if(x == 0 && y== 0){
return a[0][0];
}
if(dp[x][y] != -1){
return dp[x][y];
}
dp[x][y] = a[x][y] + min(dfs(x-1, y), min(dfs(x, y-1), min(dfs(x+1, y), dfs(x, y+1))));
return dp[x][y];
}
int main(){
int tt;
cin >> tt;
while(tt--){
int n;
cin >> n;
for(int i = 0 ; i < n; i++){
for(int j = 0; j < n; j++){
cin >> a[i][j];
dp[i][j] = -1;
}
}
cout << dfs(n-1, n-1) << endl;
}
return 0;
}
Example:
Input:
2
5
31 100 65 12 18 10 13 47 157 6 100 113 174 11 33 88 124 41 20 140 99 32 111 41 20
2
42 93 7 14
Output:
327
63
I am getting 2147483647 as the output for both the cases, which is the value of INT_MAX.
The global variable n that dfs looks at is always zero (by static initialization), it's never assigned a value. When main calls, say, dfs(4, 4), the function immediately returns INT_MAX due to 4 >= 0 check.
Once you fix this simple issue, you'll discover that your program crashes due to stack overflow. You see, dfs(4, 4) calls dfs(3, 4), which in turn calls dfs(4, 4), which calls dfs(3, 4), which ...
This is not really a dynamic programming problem. It's a "shortest path in a graph" problem, suitable for, say, Dijkstra or A* algorithms.
I am trying to implement the Divide and Conquer Algorithm to solve the Traveling Salesman problem.
I divided the problem into smaller parts, but I have no idea what to do next.
Here is my code:
struct coordinate
{
float x;
float y;
};
vector<coordinate> coordinates; //Please assume it is filled with random coordinates
void DivideAndConquer(int divide)
{
vector<vector<coordinate>> routes;
vector<coordinate> empty;
int check = 0;
for (int i = 0; i < coordinates.size(); i++)
{
if (i == divide * check)
{
check++;
routes.push_back(empty);
}
routes[check - 1].push_back(coordinates[i]);
}
//What now?
}
I also implemented methods to calculate distance:
float Distance(coordinate first, coordinate second)
{
return sqrt(pow(second.x - first.x, 2) + pow(second.y - first.y, 2) * 1.0);
}
float RouteDistance(vector<coordinate> route, bool returnBack)
{
float totalDistance = 0;
for (int i = 1; i < route.size(); i++)
{
totalDistance += Distance(route[i-1], route[i]);
}
if (returnBack) totalDistance += Distance(route[0], route[route.size() - 1]);
return totalDistance;
}
I wrote Brute Force algorithm as well, which I believe can be used in divide and conquer.
It simply returns to most optimal route of given coordinate vector.
vector<coordinate> BruteForce(vector<coordinate> route)
{
vector<int> turn;
for (int i = 0; i < route.size(); i++) turn.push_back(i);
int currentBestDistance = RouteDistance(route, true);
vector<coordinate> currentBestRoute = route;
do
{
vector<coordinate> newRoute;
int newRouteDistance;
for (int e : turn)
{
newRoute.push_back(route[e]);
}
newRouteDistance = RouteDistance(newRoute, false);
if (newRouteDistance < currentBestDistance)
{
currentBestRoute = newRoute;
currentBestDistance = newRouteDistance;
}
} while (next_permutation(turn.begin(), turn.end()));
return currentBestRoute;
}
In DivideAndConquer it currently divides the coordinates vector into sub vectors size of the "divide" parameter we call the function with.
For example, let's assume this is our coordinates:
10 20
23 54
98 123
55 72
16 82
And we call "DivideAndConquer(2)"
result:
10 20
23 54
98 123
55 72
16 82
I am having trouble with implementing Dijkstra algorithm.
I have the following variables initialized :
enum GraphLimit300 {MAX_NODES = 50};
typedef unsigned int Element300;
Element300 adjacencyMatrix[MAX_NODES][MAX_NODES];
Element300 distanceArray[MAX_NODES];
bool visitedSet[MAX_NODES];
int numberNodes;
Here is my current implementation of the algorithm:
int startNode;
int visited;
unsigned int smallest = UINT_MAX;
do
{
startNode = getStartNode300();
setVisitedSet300();
smallest = UINT_MAX;
visitedSet[startNode] = true;
for (int i = 0; i < numberNodes; i++)
{
distanceArray[i] = adjacencyMatrix[startNode][i];
}
for (int i = 0; i < numberNodes - 1; i++)
{
for (int v = 0; v < numberNodes; v++)
{
if (visitedSet[v] == false)
{
if (distanceArray[v] < smallest)
{
smallest = distanceArray[v];
visited = v;
}
}
}
visitedSet[visited] = true;
for (int w = 0; w < numberNodes; w++)
{
if (visitedSet[w] == false)
{
distanceArray[w] = min(distanceArray[w], distanceArray[visited] + adjacencyMatrix[visited][w]);
}
}
}
On this particular for loop where it should do the certain math to find the min between values at a certain index where the nodes are false and store the min in that index. What I found is that after it chooses the smallest value in distaceArray and set it to true(which is 3 if I start at 1 using the data file below, Which is correct.).
for (int w = 0; w < numberNodes; w++)
{
if (visitedSet[w] == false)
{
distanceArray[w] = min(distanceArray[w], distanceArray[visited] + adjacencyMatrix[visited][w]);
}
}
It uses the nodes '0' and '2' as of this particular iteration is the nodes that are false. And does the math for times and stores them in the wrong array.
I am using this data set that stores the numbers in adjacencyMatrix correctly.
0 5 10 4294967295
4294967295 0 4294967295 3
4294967295 7 0 4294967295
4294967295 4294967295 4 0
The correct output is:
Distance[0] =4294967295
Distance[1] =0 //Which is the node that I choose to start with
Distance[2] =7
Distance[3] =3
What I am getting is:
Distance[0] =3
Distance[1] =0
Distance[2] =3
Distance[3] =3
I have done this process by hand to confirm that the correct output that I should be getting is true and it IS.
Updated if:
if (visitedSet[w] == false && adjacencyMatrix[visited][w] != UINT_MAX)
{
distanceArray[w] = min(distanceArray[w], distanceArray[visited] + adjacencyMatrix[visited][w]);
}
The problem here is again, the fact that you shall only consider edges which exist, that is adjacencyMatrix[visited][w]!=UINT_MAX.
If you don't exclude these edges, distanceArray[visited] + adjacencyMatrix[visited][w] will overflow and the min() will not return the result that you expect.
You can solve this by changing this line:
if (visitedSet[w] == false && adjacencyMatrix[visited][w]!=UINT_MAX )
Edit:
There is indeed another problem hidden in your nested for loops. The first inner for loop looks each time for the shortest subpath to expland. Unfortuantely, you didn't reset smallest, so that it starts with the smalest value of the previous iteration.
Update the looping as follows and you'll get your explected result:
for (int i = 0; i < numberNodes - 1; i++)
{
smallest = UINT_MAX; // !!!!!!!!!!!!!!!!!!!!!!!
for (int v = 0; v < numberNodes; v++)
{
...
}
...
}
I have 2 vectors, one (vector1 of structs (Point)) is filled with X amount of points and another (vector2 of structs (PrimeTemplate)) is filled with Y amount of points. I want to find all values below a threshold and I feel like my code just doesn't do that. For now I'll just ignore if one point maps to more than 1 other. What am I missing? I only generate a few points and I know I should be getting more.
struct Template{
int tempX;
int tempY;
};
struct PrimeTemplate{
double tempX;
double tempY;
};
int matches = 0;
for (int outerLoop = 0; outerLoop < vector1 .size(); outerLoop++)
{
for (int innerLoop = 0; innerLoop < vector2.size(); innerLoop++)
{
double tempEuclidianX = std::pow(abs(vector1 [outerLoop].tempX - vector2[innerLoop].tempX), 2.0);
double tempEuclidianY = std::pow(abs(vector1 [outerLoop].tempY - vector2[innerLoop].tempY), 2.0);
double Euclidian = sqrt(tempEuclidianX + tempEuclidianY);
if (Euclidian <= 5) //less than threshold
{
matches++;
}
}
}
Sample input from a file would look like this (two different files, random numbers) (no worries about getting data, it's all there)
245 21
452 54
124 68
485 78
111 29
97 75
78 113
300 124
411 101
What is wrong with your code is that you use abs() before squaring.
It isn't necessary to take the absolute value at all before squaring, of course, but if you are going to then you want to use fabs, as just abs takes and returns an integer. This extra rounding off might be why are not getting the right answer.
This was the method I used for calculating the shortest distances between a pair. It loops through a text file and loads up the vectors you see. Turned out the issue with the points was in my implementation before this code which was some the normalization of Biometric points.
for (int outerLoop = 0; outerLoop < Tvector.size(); outerLoop++)
{
for (int innerLoop = 0; innerLoop < QPrimeVector.size(); innerLoop++)
{
double tempEuclidianX = std::pow((QPrimeVector[innerLoop].tempX - Tvector[outerLoop].tempX), 2.0);
double tempEuclidianY = std::pow((QPrimeVector[innerLoop].tempY - Tvector[outerLoop].tempY), 2.0);
double Euclidian = sqrt(tempEuclidianX + tempEuclidianY);
if (Euclidian <= THRESHOLD) //less than threshold and not taken already
{
if (Euclidian < minEuclidian)
{
minEuclidian = Euclidian;
if (!Tvector[outerLoop].marked)
{
matched = innerLoop;
}
}
}
if (matched != -1)
{
matches++;
}
matched = -1;
minEuclidian = 10;
}
if (matches > masterMatchCount)
{
masterMatchCount = matches;
deltaThetaMaster = deltaTheta;
deltaXMaster = deltaX;
deltaYMaster = deltaY;
}
}
for (int reset = 0; reset < Tvector.size(); reset++)
{
Tvector[reset].marked = false; //reset all the matches
}
QPrimeVector.clear();
}