N Queens in C++ using vectors - c++

I'm having trouble understanding backtracking, I can conceptually understand that we make a move, then if no solutions can be found out of it we try the next solution.
With this in mind I'm trying to solve the N Queens problem,
I'm finding out all the possible candidates that can be placed in the next row and then trying them one by one, if a candidate doesn't yield a solution, I pop it off and go with the next one.
This is core of the code that I have come up with :
void n_queens(int n)
{
vector<int> queens = vector<int>();
backtrack(queens,0,n);
}
void backtrack(vector<int>& queens, int current_row, int N)
{
// check if the configuration is solved
if(is_solution(queens, N))
{
print_solution(queens,N);
}
else
{
// construct a vector of valid candidates
vector<int> candidates = vector<int>();
if(construct_candidates(queens,current_row,N,candidates))
{
for(int i=0; i < candidates.size(); ++i)
{
// Push this in the partial solution and move further
queens.push_back(candidates[i]);
backtrack(queens,current_row + 1,N);
// If no feasible solution was found then we ought to remove this and try the next one
queens.pop_back();
}
}
}
}
bool construct_candidates(const vector<int>& queens, int row, int N, vector<int>& candidates)
{
// Returns false if there are no possible candidates, we must follow a different
// branch if this so happens
for(int i=0; i<N; ++i)
{
if(is_safe_square(queens,row,i,N))
{
// Add a valid candidate, this can be done since we pass candidates by reference
candidates.push_back(i);
}
}
return candidates.size() > 0;
}
It doesn't print anything for any input that I give it. I tried running it through gdb but with no success, I think that is because there is a problem with my fundamental understanding of backtracking.
I have read up about backtracking in a couple of books and also an online tutorial and I still feel hazy, it'd be nice if someone could give me ideas to approach this and help me understand this slightly unintuitive concept.
The entire compilable source code is :
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// The method prototypes
void n_queens(int n);
void backtrack(vector<int>&, int current_row, int N);
bool construct_candidates(const vector<int>&, int row, int N, vector<int>&);
bool is_safe_square(const vector<int>&, int row, int col, int N);
bool is_solution(const vector<int>&, int N);
void print_solution(const vector<int>&, int N);
int main()
{
int n;
cin>>n;
n_queens(n);
return 0;
}
void n_queens(int n)
{
vector<int> queens = vector<int>();
backtrack(queens,0,n);
}
void backtrack(vector<int>& queens, int current_row, int N)
{
// check if the configuration is solved
if(is_solution(queens, N))
{
print_solution(queens,N);
}
else
{
// construct a vector of valid candidates
vector<int> candidates = vector<int>();
if(construct_candidates(queens,current_row,N,candidates))
{
for(int i=0; i < candidates.size(); ++i)
{
// Push this in the partial solution and move further
queens.push_back(candidates[i]);
backtrack(queens,current_row + 1,N);
// If no feasible solution was found then we ought to remove this and try the next one
queens.pop_back();
}
}
}
}
bool construct_candidates(const vector<int>& queens, int row, int N, vector<int>& candidates)
{
// Returns false if there are no possible candidates, we must follow a different
// branch if this so happens
for(int i=0; i<N; ++i)
{
if(is_safe_square(queens,row,i,N))
{
// Add a valid candidate, this can be done since we pass candidates by reference
candidates.push_back(i);
}
}
return candidates.size() > 0;
}
bool is_safe_square(const vector<int>& queens, int row, int col, int N)
{
for(int i=0; i<queens.size(); ++i)
{
// case when the queens are already placed in the same row or column
if(queens[i] == row || queens[i] == col) return false;
// case when there is a diagonal threat
// remember! y = mx + c for a diagonal m = 1 therefore |x2 - x1| = |y2 - y1|
if(abs(i - row) == abs(queens[i] - col)) return false;
}
//Returns true when no unsafe square is found
//handles the case when there are no queens on the board trivially
return true;
}
bool is_solution(const vector<int>& queens, int N)
{
return queens.size() == N;
}
void print_solution(const vector<int>& queens, int N)
{
for(int i=0; i<N; ++i)
{
for(int j=0; j<N; ++j)
{
if(queens[i] == j){ cout<<'Q'; }
else { cout<<'_'; }
}
cout<<endl;
}
}

It's not a fundamental problem, it's just a bug.
In is_safe_square, change
queens[i] == row
to
i == row

Related

Quick sort: Pivot is the first element that is greater than its neighbor

I am learning quick sort and I found an algorithm where pivot is the first element that is greater than its neighbor, here is pseudo code
void quicksort(int i,int j)
{
pivotindex=findpivot(i,j);
if(pivotindex!=-1)
{
pivot=a[pivotindex];
k=partition(i,j,pivot); // l
quicksort(i,k-1);
quicksort(k,j);
}
}
int findpivot(int i, int j)
{
for i=0 to j
{
if(a[i]>a[i+1])
return(i);
else if(a[i]<a[i+1])
return(i+1);
else
continue;
}
return(-1);
}
int partition(int i, int j, int pivot)
{
int l, r;
l=i, r=j;
do
{
swap(a[l],a[r]);
while(a[l]<pivot)
l=l+1;
while(a[r]>=pivot)
r=r-1;
} while(l<r);
return(l);
}
Will this pseudocode work fine?
I tried to write c++ code for this, here is my code
#include <iostream>
using namespace std;
void swap(int *i,int *j){
int temp = *i;
*i = *j;
*j = temp;
}
int partition(int l, int r, int idx, int arr[]){
do{
int index = arr[idx];
swap(&arr[l],&arr[r]);
//cout<<arr[l]<<" "<<arr[r]<<" pivot : "<<index<<endl;
while(arr[l]<index){
l=l+1;
}
while(arr[r]>=index){
r=r-1;
}
}while(l<r);
return l;
}
int findpivot(int l,int r,int arr[]){
for(int i = l; i<=r; i++){
if(arr[i]>arr[i+1]){
return i;
}
else if(arr[i+1]>arr[i]){
return i+1;
}
else{
continue;
}
}
return(-1);
}
void Quicksort(int l, int r,int arr[]){
int idx = findpivot(l,r,arr);
if(idx!=-1){
int pivot = arr[idx];
int k = partition(l,r,idx,arr);
Quicksort(l,k-1,arr);
Quicksort(k,r,arr);
}
}
int main()
{
int arr[10] = {19,23,11,43,24,68,98,47,99,89};
Quicksort(0,9,arr);
cout<<"final"<<endl;
for(int i =0;i<10;i++){
cout<<arr[i]<<" ";
}
return 0;
}
My code does fine till these steps and then it turns into an infinite loop, is something wrong with my code, or is the pseudocode wrong?
{89,23,11,43,24,68,98,47,99,19}
{19,23,11,43,24,68,98,47,99,89}
{19,11,23,43,24,68,98,47,99,89}
{11,19}
can someone help me with this.
In addition to what #stark says in a comment about the initial value in the pseudocode's iteration in findpivot, the termination condition is clearly incorrect. Your implementation fixes the initial value (which was probably a typo) but repeats the problem with the termination: for(int i = l; i<=r; i++).
But the termination condition must be i < r. If i is equal to r, the loop will access element a[r+1], which is outside the range (and possibly outside the array). In addition, the algorithm depends on findpivot detecting the end-of-recursion condition, which is when all the elements in the range are equal, not when all the elements in the range and the next element are equal. Hence the endless loop.

Cannot get "stack" to populate in DFS based task ordering program

I am writing a program that uses the recursive BFS algorithm to determine dependencies in an undirected graph. I am using a 5x5 array as an adjacency matrix to represent the graph. While debugging, I noticed that my "stack s" variable is remaining empty while running and I cannot figure where the logical error is. Please note that I am new to programming and if I have made any fundamental mistakes or misunderstandings in the code please let me know.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
void TaskOrderHelper(int A[5][5], int start, vector<bool> visited, stack<int> s)
{
for(int i = 0; i < 5; i++)
{
if(A[start][i] == 1 && visited[i] == false)
{
visited[i] = true;
TaskOrderHelper(A, i, visited, s);
s.push(i);
}
}
}
vector<int> taskOrder(int A[5][5], int start)
{
vector<bool> visited(5,false);
stack<int> s;
vector<int> result;
for(int i = 0; i < 5; i++)
{
visited[i] = true;
}
visited[start] = true;
TaskOrderHelper(A, start, visited, s);
while(!s.empty())
{
int w = s.top();
result.push_back(w);
s.pop();
}
return result;
}
int main()
{
int A[5][5] =
{
{0,1,1,0,0},
{1,0,0,1,0},
{1,0,0,0,1},
{0,1,0,0,1},
{0,0,1,1,0}
};
vector<int> result = taskOrder(A, 0);
for(auto i: result)
{
cout << i;
}
return 0;
}
Line 26 you set visited[i] = true; for all visiteds, your recursive if statement never hits
There are other issues here with the BFS but to answer your question on why your stack is empty, your stack is being passed by value, to modify a parameter passed into another function you'll want to pass by reference. Try changing TaskOrderHelper to
void TaskOrderHelper(int A[5][5], int start, vector<bool>& visited, stack<int>& s)

Stuck in an infinite loop (Knight's Tour Problem)

The Knight's Tour Problem:
The knight is placed on the first block of an empty board and, moving according to the rules of chess, must visit each square exactly once. Print the path such that it covers all the blocks.
Could not understand why the code is stuck in an infinite loop. wasted hours still no clue.
I have the solution but couldn't understand why this particular code is not working.
#include<bits/stdc++.h>
using namespace std;
#define N 8
//possible moves
int rowMove[] = {2,1,-1,-2,-2,-1,1,2};
int colMove[] = {1,2,2,1,-1,-2,-2,-1};
void printBoard(vector<vector<int>> visited)
{
for(int i=0; i<N; i++)
{
for(int j=0;j<N;j++)
cout<<visited[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
//check if the given move is valid
bool isValid(vector<vector<int>> visited,int row, int col)
{
return (row>=0 && row<N && col>=0 && col<N && visited[row][col]==0);
}
bool solveKnight(vector<vector<int>> visited,int row, int col,int move)
{
//printBoard(visited);
if(move==N*N)
{
printBoard(visited);
return true;
}
else
{
for(int i=0;i<8;i++)
{
int newRow = row + rowMove[i];
int newCol = col + colMove[i];
if(isValid(visited,newRow,newCol))
{
move++;
visited[newRow][newCol] = move;
if(solveKnight(visited,newRow,newCol,move))
return true;
move--;
visited[newRow][newCol]=0;
}
}
}
return false;
}
int main()
{
vector<vector<int>> visited(N,vector<int>(N,0));
visited[0][0]=1;
if(!solveKnight(visited,0,0,1))
cout<<"not possible";
return 0;
}
There are two things wrong here:
You're copying over the 64-int vector every. single. time.
You're printing 9 lines to stdout every. single. time.
Both of these are extremely expensive operations. And you could recurse up to 8^64 = 2^192 times. That's not an insignificant number.
If you pass your vector by reference and kill the printBoard at the beginning of every recursive call...viola! https://ideone.com/K0DU3q

How to write a comparator for map and priority_queue where the elements are 2 dimensional array

I am trying to implement A* search for a N puzzle whose size is 15. My start state would be random. The goal state is the des array in the code. I can only swap tiles with 0 (blank state) in 4 directions in the puzzle to create a new state. To implement this I have used a priority_queue and 4 maps. For all of these , I have used 2 dimensional array. Compare is the comparator for the priority_queue and map_cmp is the comparator for the 4 maps. Vis is used to keep track of the visited states, Dis is used to keep count of the path , parent is used to keep the parent of the state and ab is used to keep the position of 0 (blank space) of each state. Here is the code:
enter code here
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
int fx[]={0,0,1,-1};
int fy[]={1,-1,0,0};
int des[4][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}};
int func1(int node[][4])
{
int cnt=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(i==0 && j==0)
continue;
if(des[i][j]!=node[i][j])
cnt++;
}
}
return cnt;
}
double func2(int node[][4])
{
int a,b,x,y;
double sum=0.0;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(node[i][j]==0)
continue;
a=node[i][j];
x=a/4;
y=a%4;
sum+=sqrt((i-x)*(i-x)+ (j-y)*(j-y));
}
}
}
struct map_cmp {
bool operator()(const int (&a)[4][4], const int (&b)[4][4]) const {
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(a[i][j]!=b[i][j])
return true;
else
continue;
}
}
return false;
}
};
map<int[4][4],int,map_cmp>vis;
map<int[4][4],int,map_cmp>dist;
map<int[4][4],int[][4],map_cmp>parent;
map< int[4][4],pair<int,int>,map_cmp >ab;
struct compare
{
bool operator()(const int (&a)[4][4],const int (&b)[4][4] )const{
return ((dist[a]+func1(a)) < (dist[b]+func1(b)));
}
};
bool isValid(int row, int col)
{
return (row >= 0) && (row < 4) && (col >= 0) && (col < 4);
}
int bfs( int src[][4],int a,int b)
{
int u[4][4];
int v[4][4];
int x,y;
vis[src]=1;
dist[src]=0;
parent[src]={0};
ab[src]=pii(a,b);
pii pos;
priority_queue < int[4][4], vector < int[4][4] > , compare > q;
q.push(src);
while(!q.empty())
{
u = q.top();
q.pop();
pos=ab[u];
for(int i=0;i<4;i++)
{
copy(u,u+16,v);
x=pos.first+fx[i];
y=pos.second+fy[i];
if(isValid(x,y))
{
swap(v[pos.first][pos.second],v[x][y]);
vis[v]=1;
dist[v]=dist[u]+1;
ab[v]=pii(x,y);
parent[v]=u;
if(memcmp(des,v,sizeof(des))==0)
return dist[v];
q.push(v);
}
}
}
}
int main()
{
int a,b,i,j,k,m,n,x,y;
int result[5];
int src[4][4]={{7,2,12,11},{10,14,0,6},{8,13,3,1},{9,5,15,4}};
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(src[i][j]==0)
{
x=i;
y=j;
break;
}
}
if(j!=4)
break;
}
a=bfs(src,x,y);
ab.clear();
}
The errors i am getting are for the comparator of maps and priority_queue.
They are:
1. no match for operator[] in dist[a]/vis/parent/ab[in short all the maps]
2. invalid array assignment
3. no matching function for call to 'std::priority_queue, compare>::push(int (*&)[4])'
This is my first post here. Sorry for any mistakes. Any help will be appreciated as i have already done whatever i can
Leave alone the unsized array issue.
Let's consider about the issue in question title, starting from the definition of std::priority_queue,
std::priority_queue<class _Tp, class _Container, class _Compare>
three parameters are element type, element container(default std::vector), comparator(It's a class with () comparator, default std::less).
class TpType {};
class TpTypeComparatator {
bool operator () (TpType &a, TpType &b) const {
return true;
}
};
std::priority_queue, TpTypeComparatator> q;

bubble sorting an array using recursion (no loops) c++

#include <iostream>
#include <cstdlib>
using std:: cin;
using std:: cout;
using std:: endl;
const int N=10;
void readarray(int array[], int N);
int bubble_sort (int array[], int size, int round,
int place);
int main ()
{
int array[N];
readarray( array, N );
int round, place;
cout << bubble_sort(array, N, place, round);
return EXIT_SUCCESS;
}
void readarray(int array[], int N)
{
int i=0;
if (i < N)
{
cin >> array[i];
readarray(array+1, N-1);
}
}
int bubble_sort (int array[], int size, int round,
int place)
{
round =0;
place =0;
if (round < N-1) // this goes over the array again making sure it has
// sorted from lowest to highest
{
if (place < N - round -1) // this sorts the array only 2 cells at a
// time
if (array[0] > array[1])
{
int temp = array[1];
array[1]=array[0];
array[0]=temp;
return (array+1, size-1, place+1, round);
}
return (array+1, size-1, place, round+1);
}
}
I know how to do a bubble sort using two for loops and I want to do it using recursion. Using loops you require two for loops and I figured for recursion it might also need two recursive functions/calls. This is what I have so far. The problem is that its outputting only one number, which is either 1 or 0. I'm not sure if my returns are correct.
In c++11, you can do this:
#include <iostream>
#include <vector>
void swap(std::vector<int &numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(std::vector<int> &numbers, size_t at)
{
if (at >= numbers.size() - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(std::vector<int> &numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
std::vector<int> numbers = {1,4,3,6,2,3,7,8,3};
bubble_sort(numbers);
for (size_t i=0; i != numbers.size(); ++i)
std::cout << numbers[i] << ' ';
}
In general you can replace each loop by a recursive function which:
check the guard -> if fail return.
else execute body
recursively call function, typically with an incremented counter or something.
However, to prevent a(n actual) stack overflow, avoiding recursion where loops are equally adequate is good practice. Moreover, a loop has a very canonical form and hence is easy to read for many programmers, whereas recursion can be done in many, and hence is harder to read, test and verify. Oh, and recursion is typically slower as it needs to create a new stackframe (citation needed, not too sure).
EDIT
Using a plain array:
#include <iostream>
#include <vector>
#define N 10
void swap(int *numbers, size_t i, size_t j)
{
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
bool bubble_once(int *numbers, size_t at)
{
if (at >= N - 1)
return false;
bool bubbled = numbers[at] > numbers[at+1];
if (bubbled)
swap(numbers, at, at+1);
return bubbled or bubble_once(numbers, at + 1);
}
void bubble_sort(int *numbers)
{
if ( bubble_once(numbers, 0) )
bubble_sort(numbers);
}
int main() {
int numbers[N] = {1,4,3,6,2,3,7,8,3,5};
bubble_sort(numbers);
for (size_t i=0; i != N; ++i)
std::cout << numbers[i] << ' ';
}
Please read this post
function pass(i,j,n,arr)
{
if(arr[i]>arr(j))
swap(arr[i],arr[j]);
if(j==n)
{
j=0;
i=i+1;
}
if(i==n+1)
return arr;
return pass(i,j+1,n,arr);
}