I have the adjacency matrix of a graph. I wish to calculate the number of hamiltonian paths.
I know the brute force approach tests all N! permutations. However, I am unable to code it, I tried searching but couldn't find a possible approach.
I was looking for help for the simple brute force approach.
Thanks.
See my implementation I just did:
Also check this Hamilton cycle implementation to get some insights how it's done.
#include <stdio.h>
#include <stdbool.h>
#define NUM_VERTICES 4
bool graph[NUM_VERTICES][NUM_VERTICES] = {
{0, 1, 0, 1},
{1, 0, 1, 1},
{0, 1, 0, 0},
{1, 1, 0, 0},
};
int parent[NUM_VERTICES];
bool fin_hp_r(int v, int n)
{
// If all vertices are connected
if (n == NUM_VERTICES)
return true;
// For all neighbours
for (int i = 0; i < NUM_VERTICES; ++i)
if (graph[v][i] && parent[i] == -1)
{
parent[i] = v;
if (fin_hp_r(i, n + 1))
return true;
parent[i] = -1;
}
return false;
}
bool find_hamilton_path()
{
memset(parent, -1, sizeof(int) * NUM_VERTICES);
for (int i = 0; i < NUM_VERTICES; ++i)
{
parent[i] = i;
if (fin_hp_r(i, 1))
return true;
parent[i] = -1;
}
}
int main(void) {
find_hamilton_path();
for (int i = 0; i < NUM_VERTICES; ++i)
printf ("%d -> %d\n", parent[i], i);
return 0;
}
And this one for counting number of all Hamilton paths:
#include <stdio.h>
#include <stdbool.h>
#define NUM_VERTICES 4
bool graph[NUM_VERTICES][NUM_VERTICES] = {
{0, 1, 0, 1},
{1, 0, 1, 1},
{0, 1, 0, 0},
{1, 1, 0, 0},
};
int parent[NUM_VERTICES];
long long cnt_fin_hp_r(int v, int n)
{
// If all vertices are connected
if (n == NUM_VERTICES)
return 1;
// For all neighbours
long long res = 0;
for (int i = 0; i < NUM_VERTICES; ++i)
if (graph[v][i] && parent[i] == -1)
{
parent[i] = v;
res += cnt_fin_hp_r(i, n + 1);
parent[i] = -1;
}
return res;
}
long long find_hamilton_path_number()
{
memset(parent, -1, sizeof(int) * NUM_VERTICES);
long long res = 0;
for (int i = 0; i < NUM_VERTICES; ++i)
{
parent[i] = i;
res += cnt_fin_hp_r(i, 1);
parent[i] = -1;
}
return res;
}
int main(void) {
printf("%lld\n", find_hamilton_path_number());
return 0;
}
This is a problem from an ongoing contest
https://www.codechef.com/JAN16/problems/SEAKAM
Related
I am trying to write a recursive code for the problem : Minimum number of jumps. Problem Link
This is the code that I have currently written. This code does not cover all the test cases. I wanted to know where I was going wrong with the code. I have made the recursive tree in my notebook for a sample array.
int solve(const int arr[], const int &n, int idx, int steps, bool &found){
if(arr[idx] == 0) return INT_MAX;
if(idx >= n - 1) {
found = true;
return steps;
}
int res = INT_MAX;
int lim = min(idx+arr[idx], n-1);
for(int i=1; i<=lim; i++) {
if(idx+i <= n) {
int ans = solve(arr, n, idx + i,steps + 1, found);
res = min(res, ans);
}
}
return res;
}
int minJumps(int arr[], int n){
bool found = false;
int res = solve(arr, n, 0, 0, found);
if(!found) return -1;
return res;
}
The code works for some cases like :
arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9};
but not for other arrays like:
arr[] = {1, 5, 4, 2, 0, 4, 0, 1, 1, 1, 3, 2, 1, 0, 3, 2, 1, 2, 0, 0, 1}
The expected output for this is -1, but my function returns 4.
I have spent over 4 hours trying to figure this out. I was thinking maybe some of you can help me.
I am NOT trying to get the solution to get accepted, I just want to first create a correct recursive code, which I can then memoize and then convert it to Dynamic Programming code.
UPDATE:
I may have fixed the code, can anyone please help me in verifying its correctness? I plan on converting this to DP code.
Here is the updated code:
int solve(const int arr[], const int &n, int idx, int steps){
if(idx <= n - 1 && arr[idx] == 0) return INT_MAX;
if(idx >= n - 1) return steps;
int res = INT_MAX;
for(int i=1; i<=arr[idx]; i++) {
if(idx+i <= n) {
int ans = solve(arr, n, idx + i,steps + 1);
res = min(res, ans);
}
}
return res;
}
int minJumps(int arr[], int n){
int res = solve(arr, n, 0, 0);
if(res == INT_MAX) return -1;
return res;
}
I am trying to decrement a number, which can be infinitely long and is represented in a vector, by 1. As a small example:
vector<int> v1 = {5, 0, 0, 0};
After subtracting one from the end, the result should be:
vector<int> v1 = {4, 9, 9, 9};
This is my current code:
int size = v1.size();
bool carry = false;
for (int i = size - 1; i > 0; i--) {
if (v1.at(i) == 0) {
v1.at(i) = 9;
if (v1.at(0) == 1) {
v1.at(0) = 0;
}
carry = true;
} else {
v1.at(i) -= 1;
carry = false;
}
}
if (carry == true && v1.at(0) == 0) {
v1.erase(v1.begin());
} else if (carry == true) {
v1.at(0) -= 1;
}
return v1;
When I test it, everything works fine, except numbers like 11119. They turn out to be 00019. Is there anything I could tweak?
It seems to me that you didn't think through the logic clearly.
Here's what needs to happen.
If the last number is 0, it needs to be changed to 9 and a carry has to be maintained.
Repeat until no carry needs to be maintained.
That logic is best implemented using a do - while loop. Here's what I came up with.
int size = v.size();
bool carry = true;
int i = size - 1;
do
{
if (v.at(i) == 0)
{
v.at(i) = 9;
}
else
{
v.at(i)--;
carry = false;
}
--i;
}
while ( carry == true && i >= 0);
Here's a complete program
#include <iostream>
#include <vector>
void test(std::vector<int> v)
{
int size = v.size();
bool carry = true;
int i = size - 1;
do
{
if (v.at(i) == 0)
{
v.at(i) = 9;
}
else
{
v.at(i)--;
carry = false;
}
--i;
}
while ( carry == true && i >= 0);
for ( auto item : v )
{
std::cout << item << " ";
}
std::cout << std::endl;
}
int main()
{
test({1, 1, 1, 1, 9});
test({5, 0, 0, 0, 0});
}
and its output
1 1 1 1 8
4 9 9 9 9
See it working at https://ideone.com/lxs1vz.
A subtraction as you tried to do, could be done like this:
#include <iterator>
std::vector<int> v1 = {5, 0, 0, 0};
for (std::vector<int>::reverse_iterator i = v1.rbegin(); i != v1.rend(); i++) {
*i -= 1;
if (*i < 0) {
*i = 9;
}
else {
break;
}
}
My code returns 3 even though everything seems to be right. It previously returned 255, and i re-arranged it a bit, and now it returns 3. It also says "terminate called after throwing an instance of 'std::bad_alloc'".
I looked it up on Google but I can't find any solution. Any idea why this happens?
#include <iostream>
#include <vector>
using namespace std;
std::vector<int> calculeazaPunctul(double pct[]) {
double pctfinal[2];
double xv = pct[0];
double yv = pct[1];
double zv = pct[2];
double res = .02;
double xk = 1;
double yk = 1;
double zk = -2;
cout << "h" << endl;
double zp = 0;
double xp = xv - ((xv - xk) * (zv - zp));
xp = xp / (((zv - zk != 0) ? (zv - zk) : 0.0001));
double yp = yv - ((yv - yk) * (zv - zp));
yp = yp / (((zv - zk != 0) ? (zv - zk) : 0.0001));
return {(int)((res * 2 * (xp * 50 + 100))), (int)((res * (yp * 50 + 100)))};
}
int main()
{
double puncte[8][3] = {{1, 0, -1},
{1, 0, 1},
{-1, 0, 1},
{-1, 0, -1},
{1, 1, -1},
{1, 1, 1},
{-1, 1, 1},
{-1, 1, -1}};
std::vector<std::vector<int> > pcteFinal;
pcteFinal.resize(8);
for (int i = 0; i < 8; i++) {
pcteFinal[i] = calculeazaPunctul(puncte[i]);
}
std::vector<std::vector<char> > image;
image.resize(10);
for (int y = 0; y < 10; y++) {
std::vector<char> row;
image[y] = row;
for (int x = 0; x < 20; x++) {
image[y].push_back('.');
}
}
for (int i = 0; i < 8; i++) {
if (pcteFinal[i][0] < 20 && pcteFinal[i][0] >= 0)
{
if (pcteFinal[i][1] < 10 && pcteFinal[i][0] >= 0)
{
image[pcteFinal[i][0]][pcteFinal[i][1]] = '#';
}
}
}
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 20; x++) {
cout << image[y][x];
}
cout << endl;
}
return 0;
}
So here is the function that does the sobel process:
void sobelOperator(int& x, int& y)
{
ImageType image;
for(int i = 0; i<x; i++)
{
for(int j = 0; j<y; j++)
{
//constants
const int MATRIX_MAX = 3;
const int PIXEL_MAX = 255;
//value for the new cell calculation
int GXpixel = 0, GYpixel = 0, Gpixel = 0;
//Sobel Horizontal Mask or matrix for the Kx convolution
const int sobelKxFilterMatrix[3][3] = {{1, 0, -1}, {2, 0, -2}, {1, 0, -1}};
//Sobel Vertical Mask or matrix for the Ky convolution
const int sobelKyFilterMatrix[3][3] = {{1, 2, 1}, {0, 0, 0}, {-1, -2, -1}};
//for addressing into filter array and into picture
int iFilter, jFilter;
int iPic, jPic;
//Loop to iterate over picture and filter window to perform sobel operation
for(iFilter = 0, iPic =- 1; iFilter < MATRIX_MAX && iPic >= 1; iFilter++, iPic++)
{
for(jFilter = 0, jPic =-1; jFilter < MATRIX_MAX && jPic >= 1; jFilter++, jPic++)
{
int val;
image.getPixelVal(x+iPic, y+jPic, val);
GXpixel += (val * sobelKxFilterMatrix[iFilter][jFilter]);
GYpixel += (val * sobelKyFilterMatrix[iFilter][jFilter]);
}
}
//check for pixel saturation
if(GXpixel > PIXEL_MAX){GXpixel = PIXEL_MAX;}
if(GYpixel > PIXEL_MAX){GYpixel = PIXEL_MAX;}
//normalize pixel
Gpixel = static_cast<int>(sqrt(pow(static_cast<double>(GXpixel), 2.0) + pow(static_cast<double>(GYpixel), 2.0)));
image.setPixelVal(i, j, Gpixel);
}
}
}
I have a c++ code for sobel operator on pgm image, my code compiles but fails to give me the required results. Can anyone tell me what is wrong?
This part
for(iFilter = 0, iPic =- 1; iFilter < MATRIX_MAX && iPic >= 1; iFilter++, iPic++)
looks wrong.
You assign -1 to iPic and then test if iPic >= 1. That will always be false.
I need to write recursive function in c++ that finds largest area of number '1' in 2d array that contains only 1 or 0.
Example:
int Arr[5][8] =
{
{ 0, 0, 0, 0, 1, 1, 0, 0, },
{ 1, 0, 0, 1, 1, 1, 0, 0, },
{ 1, 1, 0, 1, 0, 1, 1, 0, },
{ 0, 0, 0, 1, 1, 1, 1, 0, },
{ 0, 1, 1, 0, 0, 0, 0, 0, },
};
Visual example: http://s23.postimg.org/yabwp6h23/find_largest.png
Largest area of this array is 12, second largest is 3 and third largest is 2.
I was thinking to do this with something similar to flood fill algorithm, but just can't figure out how.
bool visited[5][8];
int i,j;
// variables for the area:
int current_area = 0, max_area = 0;
int Arr[5][8]={ // type your map of values here
}
// functions
void prepare_visited_map() {
for(i=0;i<5;i++) {
for(j=0;j<8;j++) visited[i][j] = false;
}
}
// recursive function to calculate the area around (x,y)
void calculate_largest_area(int x, int y) {
if(visited[x][y]) return;
// check if out of boundaries
if(x<0 || y<0 || x>=5 || y>=8) return;
// check if the cell is 0
if(!Arr[x][y]) {
visited[x][y] = true;
return;
}
// found a propper cell, proceed
current_area++;
visited[x][y] = true;
// call recursive function for the adjacent cells (north, east, south, west)
calculate_largest_area(x,y-1);
calculate_largest_area(x+1,y);
calculate_largest_area(x,y+1);
calculate_largest_area(x-1,y);
// by the end of the recursion current_area will hold the area around the initial cell
}
// main procedure where the above functions are used
int mian() {
// calculate the sorrounding area of each cell, and pick up the largest of all results
for(i=0;i<5;i++) {
for(j=0;j<8;j++) {
prepare_visited_map();
calculate_largest_area(i,j);
if(current_area > max_area) max_area = current_area;
}
}
printf("Max area is %d",max_area");
}
Hope this was helpful :)
I was thinking to do this with something similar to flood fill algorithm
I think that's a pretty good way to do it. Apply flood fill to any 1, counting the ones and replacing them with zeros.
Repeat until the grid consists entirely of zeroes.
The following will print out the sizes of the connected components in no particular order:
#include <iostream>
constexpr int N = 5;
constexpr int M = 8;
int arr[N][M] =
{
{ 0, 0, 0, 0, 1, 1, 0, 0, },
{ 1, 0, 0, 1, 1, 1, 0, 0, },
{ 1, 1, 0, 1, 0, 1, 1, 0, },
{ 0, 0, 0, 1, 1, 1, 1, 0, },
{ 0, 1, 1, 0, 0, 0, 0, 0, },
};
int fill(int arr[N][M], int r, int c) {
int count = 0;
if (r < N && arr[r][c]) {
for (int i = c; i >= 0 && arr[r][i]; --i) {
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
}
for (int i = c + 1; i < M && arr[r][i]; ++i) {
arr[r][i] = 0;
count += fill(arr, r + 1, i) + 1;
}
}
return count;
}
int print_components(int arr[N][M]) {
for (int r = 0; r < N; ++r) {
for (int c = 0; c < M; ++c) {
if (arr[r][c]) {
std::cout << fill(arr, r, c) << std::endl;
}
}
}
}
int main() {
print_components(arr);
}
something like,
int max_area = 0;
foreach y
foreach x
if (pos[y][x] == 1 && !visited[y][x])
{
int area = 0;
Queue queue = new Queue();
queue.push(new Point(x, y));
visited[y][x] = true;
while (!queue.empty())
{
Point pt = queue.pop();
area++;
foreach neightboor of pt (pt.x±1, pt.y±1)
if (pos[neightboor.y][neightboor.x] == 1 && !visited[neightboor.y][neightboor.x])
{
visited[neightboor.y][neightboor.x] = true;
queue.push(new Point(neightboor.x, neightboor.y));
}
}
if (area > max_area)
max_area = area;
}
Quick approach, but I don't know if there is a way to do this in a sane way (recursive
call for each element does not scale for C++ because call stack is limited)
int maxy = 5
int maxx = 8
int areasize(int x, int y) {
if (x < 0 || y < 0 || x > maxx || y > maxy || !Arr[y][x])
return 0;
Arr[y][x] = 0;
return 1
+ areasize(x + 1, y)
+ areasize(x - 1, y)
+ areasize(x, y + 1)
+ areasize(x, y - 1);
}
maxarea = 0;
for (int y = 0; y < maxy; y++) {
for (int x = 0; x < maxx; x++) {
maxarea = std::max(maxarea, areasize(x, y));
}
}