Alternative to backtracking and to speed up program - c++

I was trying to make a knights tour problem solution and i have just made it. Now i want to improve it.It takes the starting value and then outputs the step by step instructions to move (in command line output).
Now the technique which i have used is that firstly i have divided the board into 4 blocks according to the solution given in a video
(here www.youtube.com%2Fwatch%3Fv%3DdWM5pKYZCHw&b=28) and also divided the whole board into 4 systems of boxes.
In the solution i have to do do lots of backtracking to decide between two different possibilities which greatly reduces the speed.Is there any way to do less or no backtracking to decide between two possibilities. And any other suggestion to improve the technique.
Here is a part of the code (a function which moves the knight across the board)
void move(int l[8][8][2],int g, int e) // g and e are the required systems and blocks respectively
{
backtracking(backtrackarray, l); // calling function to backtrack the array
backtracking(secondbacktrackarray,l); againcalling function to backtrack array in different array
int system = currentsystem(l, currentposition[0], currentposition[1]); //storing the current system
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]); //moving knight
}
if (blockshiftpossible(l, system, currentposition[0], currentposition[1])!= 1) // checks if next block shift possible
{
backimage(l, backtrackarray); getting back the stored image
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in the opposite way
}
}
if ((systemshiftpossible(l, currentposition[0], currentposition[1])!= 1) && (g==4) && (e==4)) // checking if system shift is possible
{
backimage(l,secondbacktrackarray); // getting again image from second backtrack array
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in opposite direction
}
if (systemshiftpossible(l, currentposition[0], currentposition[1])!= 1)
{
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]);
}
}
}
if ((blockshiftpossible(l, system, currentposition[0], currentposition[1])
== 1) && (g!=4))
{
blockshift(l, currentposition[0], currentposition[1]);
}
else
{
cout << "logical error"<<endl;
}
}
To see the details of this technique check my previous question
Solving knight tour with c++
Also how i can change it to get solutions for n*n puzzles if possible.

Related

Conway's game of life algoritm is not working

I'm trying to simulate conway's game of life. The algorithm I made is not working, but I can't figure out how.
If I have a situation like this:
|.........|
|....x....|
|....x....|
|....x....|
|.........|
a . is a dead cell, an x is an alive cell
It is expected that the vertical bar flips into a horizontal bar, but this doesn't happen.
Instead it only removes the bottom one, running it again again only removes the bottom so theres 1 left.
Clearly theres something wrong with the algorithm, but I can't figure out what.
I've been looking online but all problems other people have had, the solutions didn't work for me.
So what is the error in this algorithm?
This is my code:
void new_generation() {
// Create one new generation
// double for loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
// find the amount of living neighbours, stored in count
// dubbele for loop -> iterates every neighbour of the current cell
count = 0;
for (int y=0; y<2; y++) {
for (int x=0; x<2; x++){
if (i != 0 and j!= 0) { // the cell itself doesnt count
if (world[i+y][j+x]) count++;
}
}
}
if (world[i][j]) { // current cell is alive
if (count<2 or count>3) new_world[i][j] = false;
else new_world[i][j] = true;
}
else { // current cell is dead
if (count==3) new_world[i][j] = true;
else new_world[i][j] = false;
}
}
}
// copy every value from the newly generated world to the current
// double foor loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
world[i][j] = new_world[i][j];
}
}
worldHeight and worldWidth are ints denoting how big the world is.
world and new_world are 2-dimensional arrays containing booleans where true is a living cell and false is a dead cell
You count the neighbor cells wrong
Both x and y are runing from 0 to 2 not from -1 to 2. in
for (int y=0; y<2; y++) {//should be int y=-1; y<2; y++
for (int x=0; x<2; x++){//should be int x=-1; x<2; x++
if (i != 0 and j!= 0) { // shold be x!=0 or y!=0
if (world[i+y][j+x]) count++;
}
}
}
Also you have to check if world[i+y][j+x] is valid (coordinates are in teh 0,size range)
And the third problem is that when you want not to count in word[i][j] you check if (i!=0 and j!=0) not x!=0 or y!=0 i and j are the coordinates of the examined cell, x and y are the difference of the coordinates.

copy constructor [array] C++

So I'm doing a puzzle game and I came to a problem. My Board will get scrambled later on in the program. I want to make a copy of it before it gets scrambled, to use it in the win-condition for my game. My Idea is to compare the copied board to the scrambled board every time the user moves a tile to see if they succeded (won) or not. But I'm a bit unsure how to do the copy constructor for the board. Here is what I have done(doesn't work as it's supposed to do).
Board::Board(int userInput)
{
this->gameSize = userInput;
int zeroPos[2] = { 0, 0 };
SetTileNumbers();
}
void Board::SetTileNumbers()
{
const int sizeOfGame = gameSize; //Size given from user when the board was created.
int tileNumber = 0; //The value given to each Tile.Number.
int row, column;
boardOfTiles = new Tile* [sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile [sizeOfGame]; //The doublepointer is given an additional dimension
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = tileNumber; //Loops that goes through the entirety to instantiate the board of tiles.
tileNumber++;
}
}
}
void Board::SetTileNumbers(const Board& copy)
{
const int sizeOfGame = copy.gameSize;
int row , column;
boardOfTiles = new Tile*[sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile[sizeOfGame];
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = copy.boardOfTiles[row][column].number;
}
}
}
I hope this does not sound off-topic, but copy-constructor aside, I think you might have a different problem: the way you decide on a solution is very inefficient. You waste cpu time and you waste memory.
For every step to compare two NxN boards is about as ineffciciet as it gets. You can try a different approach: assign a number to each position on the board and you know that the solution is to have the numbers sorted in a particular order.
For a 3x3 board, 'THE' solution would look like:
1 2 3
4 5 6
7 8 9
Furthermore, a 2d array is stored in memory as a continuous array, you you can treat the solution as an array:
1 2 3 4 5 6 7 8 9
Any other arrangement will not represent an solution.
Checking weather an array is sorted is a much easier problem to solve. Worst case scenario you are still looking at O(n^2) to check if the array is sorted but without the memory overhead. Plus I'm sure you can figure out a more efficient algorithm to check if the array is sorted.
I hope this helps...

Replacing duplicates in a randomized 2 dimensional array

I am having some trouble with my class project, essentially what I want to do is spawn objects randomly which so far is working perfectly, they are spawned from an 2d array that stores X and Z which have been randomly generated within reasonable distance. The issue I am having is objects being placed inside each other due to lack of duplicate detection. I need to go through the 2d array, see if any X and Y co-ords match and randomize any matches found. Sorry if this doesn't make a lot of sense, i'm not too good at explaining things but perhaps you could take a look at my current detection method and give me some tips?
for (int k = 0; k <= NumofShrooms - 1; k++)
{
for (int i = 0; i <= NumofShrooms - 1;)
{
if (k == i)
{
i++;
}
if (SpawnArray[k][2] == SpawnArray[i][2])
{
SpawnArray[k][2] = rand() % 16 + 1;
i = 0;
}
else i++;
}
}

5 queens on a 8x8 chess board

I am trying to find the number of ways possible to set 5 queens on a chess board without them being able to attack each other. I have succeeded to find the first set. The problem is how would I be able to find the next set of positions for 5 queens. The procedure in my program is like this:
Generate a vector of disallowed positions based on the current queens on the board
Loop through all the positions on the board
Check if the current position is one of the disallowed positions on the board
If it is not, return the position, add it to the vector of queens on the board and begin the process again
Continue until there is no more position available i.e. all the remaining positions are disallowed
#include <iostream>
#include <vector>
using namespace std;
const int BSIZE = 8;
char chessBoard[BSIZE][BSIZE];
struct qPos
{
qPos() : h(0), v(0), found(true) {}
int h; //horizontal pos
int v; //vertical pos
bool found; //if position is available
};
qPos findNextQPos(vector<qPos> Qs);
void fillBoard(vector<qPos> Qs);
void print();
vector<qPos> generateDisallowed(vector<qPos> Qs);
bool isDisallowed(qPos nextPos, vector<qPos> disallowedPos);
int main(int argc, char **argv){
vector<qPos> QsOnBoard; //Position of all the queens on board
qPos nextQ; //next possible position
while (nextQ.found)
{
nextQ = findNextQPos(QsOnBoard);
if (nextQ.found)
{
QsOnBoard.push_back(nextQ); //If the nextQ is available i.e. not disallowed, add it to the queens vector
}
}
fillBoard(QsOnBoard); //Fill the board with queens positions
print(); // print the board
return 0;
}
qPos findNextQPos(vector<qPos> Qs) {
// Generate disallowed positions based on all the queens on board
vector <qPos> disallowedPos = generateDisallowed(Qs);
qPos nextQ;
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
nextQ.h = i;
nextQ.v = j;
if (!isDisallowed(nextQ, disallowedPos)) { //Check if next possible position is a disallowed position
//cout << "Next available:\n" << nextQ.h << ", " << nextQ.v << endl;
return nextQ; // if it is avaible return the position, break the loop
}
}
}
nextQ.found = false; // No available position is found to return, found is set to false, return the position
return nextQ;
}
Rest of the source code where I have the other functions such as generate disallowed and isDisallowed and etc is on this pastebin. I thought it would not be really related to the question and the code here should not be too long.
The result of the first set looks like this:
So how should I continue in order to be able to find all solution sets? This is where I get stuck.
First, combine these two loops into one:
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
Instead:
for (size_t n = 0; n < (BSIZE * BSIZE); ++n)
{
size_t i = n % BSIZE;
size_t j = n / BSIZE;
Now your function can easily take a starting n. To find the "next" solution, simply remove the last queen (noting its position) and call FindNextQPos, telling it to start at the position one past that queen. If that queen is already at the last position, go back and remove another queen.
If you find no solution, do the same thing as if you do find a solution. Remove the last queen and call FindNextQPos, again starting one past the position of the queen you removed.
When you have no queens to remove, you are done.
You can do this with a single "continue" function. You can call this function whether you found a solution or found no solution. Its logic is:
Find the last queen. If there's no last queen, stop. We are done.
Note its position. Remove it.
Call FindNextQPos starting at the position one past the position we noted. If we placed a queen, keep trying to place more queens starting at position zero until we find a solution or can't place a queen.
If we found a solution, output it.
Go to step 1.

Algorithm for smoothing

I wrote this code for smoothing of a curve .
It takes 5 points next to a point and adds them and averages it .
/* Smoothing */
void smoothing(vector<Point2D> &a)
{
//How many neighbours to smooth
int NO_OF_NEIGHBOURS=10;
vector<Point2D> tmp=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=a.at(i+j).x;
a.at(i).y+=a.at(i+j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=tmp.at(i-j).x;
a.at(i).y+=tmp.at(i-j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
}
}
But i get very high values for each point, instead of the similar values to the previous point . The shape is maximized a lot , what is going wrong in this algorithm ?
What it looks like you have here is a bass-ackwards implementation of a finite impulse response (FIR) filter that implements a boxcar window function. Thinking about the problem in terms of DSP, you need to filter your incoming vector with NO_OF_NEIGHBOURS equal FIR coefficients that each have a value of 1/NO_OF_NEIGHBOURS. It is normally best to use an established algorithm rather than reinvent the wheel.
Here is a pretty scruffy implementation that I hammered out quickly that filters doubles. You can easily modify this to filter your data type. The demo shows filtering of a few cycles of a rising saw function (0,.25,.5,1) just for demonstration purposes. It compiles, so you can play with it.
#include <iostream>
#include <vector>
using namespace std;
class boxFIR
{
int numCoeffs; //MUST be > 0
vector<double> b; //Filter coefficients
vector<double> m; //Filter memories
public:
boxFIR(int _numCoeffs) :
numCoeffs(_numCoeffs)
{
if (numCoeffs<1)
numCoeffs = 1; //Must be > 0 or bad stuff happens
double val = 1./numCoeffs;
for (int ii=0; ii<numCoeffs; ++ii) {
b.push_back(val);
m.push_back(0.);
}
}
void filter(vector<double> &a)
{
double output;
for (int nn=0; nn<a.size(); ++nn)
{
//Apply smoothing filter to signal
output = 0;
m[0] = a[nn];
for (int ii=0; ii<numCoeffs; ++ii) {
output+=b[ii]*m[ii];
}
//Reshuffle memories
for (int ii = numCoeffs-1; ii!=0; --ii) {
m[ii] = m[ii-1];
}
a[nn] = output;
}
}
};
int main(int argc, const char * argv[])
{
boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
//Make a rising saw function for demo
vector<double> a;
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
box.filter(a);
for (int nn=0; nn<a.size(); ++nn)
{
cout << a[nn] << endl;
}
}
Up the number of filter coefficients using this line to see a progressively more smoothed output. With just 1 filter coefficient, there is no smoothing.
boxFIR box(1);
The code is flexible enough that you can even change the window shape if you like. Do this by modifying the coefficients defined in the constructor.
Note: This will give a slightly different output to your implementation as this is a causal filter (only depends on current sample and previous samples). Your implementation is not causal as it looks ahead in time at future samples to make the average, and that is why you need the conditional statements for the situation where you are near the end of your vector. If you want output like what you are attempting to do with your filter using this algorithm, run the your vector through this algorithm in reverse (This works fine so long as the window function is symmetrical). That way you can get similar output without the nasty conditional part of algorithm.
in following block:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x=a.at(i).x+a.at(i+j).x;
a.at(i).y=a.at(i).y+a.at(i+j).y;
}
for each neighbour you add a.at(i)'s x and y respectively to neighbour values.
i understand correctly, it should be something like this.
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
Filtering is good for 'memory' smoothing. This is the reverse pass for the learnvst's answer, to prevent phase distortion:
for (int i = a.size(); i > 0; --i)
{
// Apply smoothing filter to signal
output = 0;
m[m.size() - 1] = a[i - 1];
for (int j = numCoeffs; j > 0; --j)
output += b[j - 1] * m[j - 1];
// Reshuffle memories
for (int j = 0; j != numCoeffs; ++j)
m[j] = m[j + 1];
a[i - 1] = output;
}
More about zero-phase distortion FIR filter in MATLAB: http://www.mathworks.com/help/signal/ref/filtfilt.html
The current-value of the point is used twice: once because you use += and once if y==0. So you are building the sum of eg 6 points but only dividing by 5. This problem is in both the IF and ELSE case. Also: you should check that the vector is long enough otherwise your ELSE-case will read at negative indices.
Following is not a problem in itself but just a thought: Have you considered to use an algorithm that only touches every point twice?: You can store a temporary x-y-value (initialized to be identical to the first point), then as you visit each point you just add the new point in and subtract the very-oldest point if it is further than your NEIGHBOURS back. You keep this "running sum" updated for every point and store this value divided by the NEIGHBOURS-number into the new point.
You make addition with point itself when you need to take neighbor points - just offset index by 1:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
This works fine for me:
for (i = 0; i < lenInput; i++)
{
float x = 0;
for (int j = -neighbours; j <= neighbours; j++)
{
x += input[(i + j <= 0) || (i + j >= lenInput) ? i : i + j];
}
output[i] = x / (neighbours * 2 + 1);
}