Traveling Salesman Divide and Conquer C++ - c++

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

Related

Climbing the leaderboard on HackerRank

I know, there are a lot of questions like this, but I want to see other's solutions only after solving this (https://www.hackerrank.com/challenges/climbing-the-leaderboard/problem). Here's my code:
vector<int> climbingLeaderboard(vector<int> ranked, vector<int> player) {
vector<int> ranked_new; // the same ranked but without repeating numbers
vector<int> ans; // vector with places
// filling ranked_new
for (int i = 1; i < ranked.size(); i++)
{ if (ranked[i] != ranked[i - 1]) ranked_new.push_back(ranked[i]); }
ranked_new.insert(ranked_new.begin(), ranked[0]);
int left = 0, right = ranked_new.size() - 1, mid;
bool flag;
// binary searching for place for every Alice's result
for (int i = 0; i < player.size(); i++)
{
flag = false; left = 0; right = ranked_new.size() - 1;
while (!(flag))
{
if (player[i] >= ranked_new[0]) { flag = true; ans.push_back(0); }
else if (player[i] <= ranked_new[ranked_new.size() - 1]) { flag = true; ans.push_back(ranked_new.size()); }
else
{
mid = (left + right) / 2;
if (left >= right) { flag = true; ans.push_back(left); }
else if (player[i] > ranked_new[mid]) { right = mid - 1; }
else { left = mid + 1; }
}
}
}
// increasing every ans element by one
for(int i = 0; i < ans.size(); i++) { ans[i]++; }
return ans;
}
It passed 0, 5, 8 and 11 tests. In tests which it didn't pass repeats one error. For example, in test 1:
88
88
87
85
84
84
83
82
but my code returns
88
88
88
85
84
84
82
82
This is the only bug, I think it's somewhere in binary search but I still can't understand how to fix it. Please can you give me a hint?
EDIT: here are my attempts
In controversial situations (like player[i] == ranked_new[some_index]) program disbehaves (for example in test 1 when it gives 88 88 88 instead of 88 88 87). So I thought I should edit the string
if (left >= right) { flag = true; ans.push_back(left); }
with this code
if (left >= right)
{
if (player[i] > left) {flag = true; ans.push_back(left - 1);}
else if (player[i] < left) {flag = true; ans.push_back(left + 1);}
else {flag = true; ans.push_back(left);
}
But I was wrong and it didn't work. Sample test case output: 6 4 2 1. My output: 6 3 1 1 (I tried to change left with right, swap them, swapped + and -, changed numbers but it works only if it pushes back "left" in any case). I have chosen 1 case when it outputs 6 5 3 1, changed code, set left to 1, etc. to decrement numbers between 6 and 1 but it still didn't work on the same tests. I thought about it for 1,5 days and then came to stackoverflow

Partition Frisbees C++

We have a set F of n frisbee's in 2D. We want to partition F into two subsets F1, and F2 so that no two frisbee's intersect in each respective subset. Our function takes in input as so: (x_j, y_j) is the centre of the j-th frisbee, and rad_j is the radius of the j-th frisbee. The output should be s_0 s_1 ... s_n-1, where s_j = 1 if the j-th frisbee is in F1 and s_i = 2 if the j-th frisbee is in F2. If you cannot partition F, just return 0. Ideally, the algo should be computed in O(n^2) time.
I figured that I should use some type type of matrix representation of this like graph, but then I don't think I need need to construct a graph, but I think I BFS/DFS would be useful, but I'm stuck on how exactly to do this elegantly in O(n^2). I am coding this in C++ by the way.
You were on a right track with a graph search. Here's a C++11, O(V^2), depth first search solution that uses O(V+E) space.
The DFS itself is O(V+E) in time, but generating the adjacency lists is O(V^2) the obvious way.
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
struct Frisbee
{
double x;
double y;
double radius;
};
int dfs(const vector< vector<int> > &adj, vector<int> &p, int last_ind, int curr_ind)
{
if (p[curr_ind]) // node already painted
{
if (p[last_ind] == p[curr_ind]) // painted same color as neighbor -> failure
return 0;
return 1; // painting is compatible
}
// node not yet painted
p[curr_ind] = (1 == p[last_ind] ? 2 : 1); // paint opposite color as neighbor
for (int j = 0; j < adj[curr_ind].size(); ++j)
if (!dfs(adj, p, curr_ind, adj[curr_ind][j])) // dfs on neighbors
return 0;
return 1;
}
int partition(const vector<Frisbee> &F, vector<int> &p)
{
// compute adjacency lists
vector< vector<int> > adj(F.size());
p.resize(F.size());
for (int i = 0; i < F.size(); ++i)
{
p[i] = 0;
for (int j = i + 1; j < F.size(); ++j)
{
double dist = sqrt((F[i].x - F[j].x) * (F[i].x - F[j].x) + (F[i].y - F[j].y) * (F[i].y - F[j].y));
if (dist < F[i].radius + F[j].radius)
{
adj[i].push_back(j);
adj[j].push_back(i);
}
}
}
// find starting points for dfs
for (int i = 0; i < F.size(); ++i)
if (0 == p[i]) // node i not yet painted
{
p[i] = 1; // arbitrarily choose initial color
for (int j = 0; j < adj[i].size(); ++j)
if (!dfs(adj, p, i, adj[i][j])) // dfs on neighbors
return 0;
}
return 1;
}
int main(int argc, char **argv)
{
vector<Frisbee> F = { { 1.0, 1.0, 1.0 }, { 2.0, 2.0, 1.0 }, { -1.0, -1.0, 1.0 }, { -2.0, -2.0, 1.0 }, { 5.0, 5.0, 1.0 }, { -5.0, 5.0, 1.0 } };
vector<int> p;
if (partition(F, p))
{
for (size_t i = 0; i < F.size(); ++i)
cout << p[i] << " ";
cout << endl;
}
else
cout << "No partition possible!" << endl;
F.push_back({ 1.5, 1.5, 1.0 }); // add a 3-way intersection
if (partition(F, p))
{
for (size_t i = 0; i < F.size(); ++i)
cout << p[i] << " ";
cout << endl;
}
else
cout << "No partition possible!" << endl;
return 0;
}
Here's the output (of two partitions on slightly different sets of Frisbee's):
1 2 1 2 1 1
No partition possible!
Shouldn't you just do a stacked for-loop and use the distance formula? i.e. two intersect if the distance between their centres is smaller than the sum of their radii.
After that, you've state-exploded it and then you can proceed to just do loop inclusion/exclusion (i.e. include everything and get rid of all invalid ones and then include as many valid ones etc.)
You can build a graph where an edge means "touches". Then you can use a bipartition algorithm on that graph. Boost.Graph contains one.
http://www.boost.org/doc/libs/1_57_0/libs/graph/doc/is_bipartite.html
The algorithm is O(V+E), i.e. worst case O(V^2) if all discs touch each other (although there's a good chance it will abort early in that case).
Building the graph naively is O(V^2), since you have to check each disc against all others, although you might be able to optimize the common case by building a geographical quad tree to sort the discs first.

Shortest Distance to Point

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();
}

Shortest path in a grid between two points. With a catch

I have this problem where I have to find the shortest path in an NxM grid from point A (always top left) to point B (always bottom right) by only moving right or down. Sounds easy, eh? Well here's the catch: I can only move the number shown on the tile I'm sitting on at the moment. Let me illustrate:
2 5 1 2
9 2 5 3
3 3 1 1
4 8 2 7
In this 4x4 grid the shortest path would take 3 steps, walking from top left 2 nodes down to 3, and from there 3 nodes right to 1, and then 1 node down to the goal.
[2] 5 1 2
9 2 5 3
[3] 3 1 [1]
4 8 2 [7]
If not for the shortest path, I could also be taking this route:
[2] 5 [1][2]
9 2 5 3
3 3 1 [1]
4 8 2 [7]
That would unfortunately take a whopping 4 steps, and thus, is not in my interest.
That should clear things out a bit. Now about the input.
The user inputs the grid as follows:
5 4 // height and width
2 5 2 2 //
2 2 7 3 // the
3 1 2 2 // grid
4 8 2 7 //
1 1 1 1 //
Homework
I have thought this through, but cannot come to a better solution than to simplify the inputted grid into an unweighed (or negative-weight) graph and run something like dijkstra or A* (or something along those lines) on it. Well... this is the part where I get lost. I implemented something to begin with (or something to throw to thrash right away). It's got nothing to do with dijkstra or A* or anything; just straight-forward breadth-first search.
The Code
#include <iostream>
#include <vector>
struct Point;
typedef std::vector<int> vector_1D;
typedef std::vector< std::vector<int> > vector_2D;
typedef std::vector<Point> vector_point;
struct Point {
int y, x;
vector_point Parents;
Point(int yPos = 0, int xPos = 0) : y(yPos), x(xPos) { }
void operator << (const Point& point) { this->Parents.push_back(point); }
};
struct grid_t {
int height, width;
vector_2D tiles;
grid_t() // construct the grid
{
std::cin >> height >> width; // input grid height & width
tiles.resize(height, vector_1D(width, 0)); // initialize grid tiles
for(int i = 0; i < height; i++) //
for(int j = 0; j < width; j++) // input each tile one at a time
std::cin >> tiles[i][j]; // by looping through the grid
}
};
void go_find_it(grid_t &grid)
{
vector_point openList, closedList;
Point previous_node; // the point is initialized as (y = 0, x = 0) if not told otherwise
openList.push_back(previous_node); // (0, 0) is the first point we want to consult, of course
do
{
closedList.push_back(openList.back()); // the tile we are at is good and checked. mark it so.
openList.pop_back(); // we don't need this guy no more
int y = closedList.back().y; // now we'll actually
int x = closedList.back().x; // move to the new point
int jump = grid.tiles[y][x]; // 'jump' is the number shown on the tile we're standing on.
if(y + jump < grid.height) // if we're not going out of bounds
{
openList.push_back(Point(y+jump, x)); //
openList.back() << Point(y, x); // push in the point we're at right now, since it's the parent node
}
if(x + jump < grid.width) // if we're not going out of bounds
{
openList.push_back(Point(y, x+jump)); // push in the new promising point
openList.back() << Point(y, x); // push in the point we're at right now, since it's the parent node
}
}
while(openList.size() > 0); // when there are no new tiles to check, break out and return
}
int main()
{
grid_t grid; // initialize grid
go_find_it(grid); // basically a brute-force get-it-all-algorithm
return 0;
}
I should probably also point out that the running time cannot exceed 1 second, and the maximum grid height and width is 1000. All of the tiles are also numbers from 1 to 1000.
Thanks.
Edited Code
#include <iostream>
#include <vector>
struct Point;
typedef std::vector<int> vector_1D;
typedef std::vector< std::vector<int> > vector_2D;
typedef std::vector<Point> vector_point;
struct Point {
int y, x, depth;
vector_point Parents;
Point(int yPos = 0, int xPos = 0, int dDepth = 0) : y(yPos), x(xPos), depth(dDepth) { }
void operator << (const Point& point) { this->Parents.push_back(point); }
};
struct grid_t {
int height, width;
vector_2D tiles;
grid_t() // construct the grid
{
std::cin >> height >> width; // input grid height & width
tiles.resize(height, vector_1D(width, 0)); // initialize grid tiles
for(int i = 0; i < height; i++) //
for(int j = 0; j < width; j++) // input each tile one at a time
std::cin >> tiles[i][j]; // by looping through the grid
}
};
int go_find_it(grid_t &grid)
{
vector_point openList, closedList;
Point previous_node(0, 0, 0); // the point is initialized as (y = 0, x = 0, depth = 0) if not told otherwise
openList.push_back(previous_node); // (0, 0) is the first point we want to consult, of course
int min_path = 1000000;
do
{
closedList.push_back(openList[0]); // the tile we are at is good and checked. mark it so.
openList.erase(openList.begin()); // we don't need this guy no more
int y = closedList.back().y; // now we'll actually move to the new point
int x = closedList.back().x; //
int depth = closedList.back().depth; // the new depth
if(y == grid.height-1 && x == grid.width-1) return depth; // the first path is the shortest one. return it
int jump = grid.tiles[y][x]; // 'jump' is the number shown on the tile we're standing on.
if(y + jump < grid.height) // if we're not going out of bounds
{
openList.push_back(Point(y+jump, x, depth+1)); //
openList.back() << Point(y, x); // push in the point we're at right now, since it's the parent node
}
if(x + jump < grid.width) // if we're not going out of bounds
{
openList.push_back(Point(y, x+jump, depth+1)); // push in the new promising point
openList.back() << Point(y, x); // push in the point we're at right now, since it's the parent node
}
}
while(openList.size() > 0); // when there are no new tiles to check, break out and return false
return 0;
}
int main()
{
grid_t grid; // initialize grid
int min_path = go_find_it(grid); // basically a brute-force get-it-all-algorithm
std::cout << min_path << std::endl;
//system("pause");
return 0;
}
The program now prints the correct answer. Now I have to optimize (run time is way too big). Any hints on this one? Optimizing is the one thing I suck at.
The Answer
In the end the solution appeared to consist of little code. The less the better, as I like it. Thanks to Dejan Jovanović for the beautiful solution
#include <iostream>
#include <vector>
#include <algorithm>
struct grid_t {
int height, width;
std::vector< std::vector<int> > tiles;
std::vector< std::vector<int> > distance;
grid_t() // construct the grid
{
std::cin >> height >> width; // input grid height & width
tiles.resize(height, std::vector<int>(width, 0)); // initialize grid tiles
distance.resize(height, std::vector<int>(width, 1000000)); // initialize grid tiles
for(int i = 0; i < height; i++) //
for(int j = 0; j < width; j++) // input each tile one at a time
std::cin >> tiles[i][j]; // by looping through the grid
}
};
int main()
{
grid_t grid; // initialize grid
grid.distance[0][0] = 0;
for(int i = 0; i < grid.height; i++) {
for(int j = 0; j < grid.width; j++) {
if(grid.distance[i][j] < 1000000) {
int d = grid.tiles[i][j];
if (i + d < grid.height) {
grid.distance[i+d][j] = std::min(grid.distance[i][j] + 1, grid.distance[i+d][j]);
}
if (j + d < grid.width) {
grid.distance[i][j+d] = std::min(grid.distance[i][j] + 1, grid.distance[i][j+d]);
}
}
}
}
if(grid.distance[grid.height-1][grid.width-1] == 1000000) grid.distance[grid.height-1][grid.width-1] = 0;
std::cout << grid.distance[grid.height-1][grid.width-1] << std::endl;
//system("pause");
return 0;
}
There is need to construct the graph, this can easily be solved with dynamic programming using one scan over the matrix.
You can set the distance matrix D[i,j] to +inf at the start, with D[0,0] = 0. While traversing the matrix you just do
if (D[i,j] < +inf) {
int d = a[i, j];
if (i + d < M) {
D[i + d, j] = min(D[i,j] + 1, D[i + d, j]);
}
if (j + d < N) {
D[i, j + d] = min(D[i,j] + 1, D[i, j + d]);
}
}
The final minimal distance is in D[M -1, N-1]. If you wish to reconstruct the path you can keep a separate matrix that marks where the shortest path came from.
You're overthinking it. :) Run a Breadth-First Search. The solution space is a binary tree, where each node branches into "right" or "down". From current point, generate the down point and right point, stuff their coordinates into a queue, repeat until at finish.
Without checking, something like this:
queue = [{ x: 0, y: 0, path: [] }] # seed queue with starting point
p = nil
do
raise NoSolutionException if p.empty? # solution space exhausted
p = queue.pop # get next state from the back of the queue
break if p.x == MAX_X - 1 && p.y == MAX_Y - 1 # we found final state
l = grid[p.x][p.y] # leap length
# add right state to the front of the queue
queue.unshift({x: p.x + l, y: p.y, path: p.path + [p] }) if p.x + l <= MAX_X
# add down state to the front of the queue
queue.unshift({x: p.x, y: p.y + l, path: p.path + [p] }) if p.y + l <= MAX_Y
end
puts p.path
Uglifying into C++ left as exercise for the reader :p
Build an unweighted directed graph:
There are NxM vertices. In what follows, vertex v corresponds to grid square v.
There is an arc from vertex u to v iff you can jump from grid square u to square v in a single move.
Now apply a shortest path algorithm from the top-right vertex to the bottom-left.
Finally, observe that you don't actually need to build the graph. You can simply implement the shortest path algoritm in terms of the original grid.
Start off with a brute force approach to get it to work, then optimize from there. The brute force is straight-forward: run it recursively. Take your two moves, recurse on those, and so on. Collect all the valid answers and retain the minimum. If the run time is too long, then you can optimize by a variety of means. For instance, some of the moves may be invalid (because they exceed a dimension of the grid) and can be eliminated, and so on. Keep optimizing until a worst case input runs at the desired speed.
Having said that, the performance requirements only make sense if you are using the same system and inputs, and even then there are some caveats. Big O notation is a much better way of analyzing the performance, plus it can point you to an algorithm and eliminate the need for profiling.

assign cell to coordinates in a 3 by 3 grid

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.