Skiplast random function need explained - c++

I read about skipList implementation in C++ and I don't understand this random function :
float frand() {
return (float) rand() / RAND_MAX;
}
int random_level() {
static bool first = true;
if (first) {
srand( (unsigned)time(NULL) );
first = false;
}
int lvl = (int)(log(frand())/log(1.-P));
return lvl < MAX_LEVEL ? lvl : MAX_LEVEL;
}
Thanks for reading and I'm waiting for your answer :)

So, the way skiplists work is it makes the new node link to other nodes at levels, randomly choosing to add a level or not. Normally this means flipping a coin once for each level the new node is intended to link to. if it comes up heads, you go up a level and flip again, if tails, you're done.
What this does is it simulates the flipping of that coin several times, but only calling the random number source once, and applying a function with the same probability distribution as summing consecutive coin flips

// this function generates a random number between 0 and 1
float frand() {
return (float) rand() / RAND_MAX; // RAND_MAX is the biggest possible value returned by rand()
}
int random_level() {
static bool first = true; // a static variable to track whether or not this is the first run of the function
if (first) { // if this is the first time the function has been called...
srand( (unsigned)time(NULL) ); // generate a seed from the current time
first = false; // set first to false
}
int lvl = (int)(log(frand())/log(1.-P)); // generate the value of lvl with some weird log functions
return lvl < MAX_LEVEL ? lvl : MAX_LEVEL; // cap the value to MAX_LEVEL, and return
}

Related

Enumeration class and array declaration

I'm doing a C++ tutorial that teaches the language through game development.
Within this tutorial there's a piece of code which I do not understand how it works.
First an enum class is declared and an array is initialized:
enum class side {LEFT,RIGHT, NONE};
side branchPositions[NUM_BRANCHES]; / which is a const variable and has the value of 6
Within the main function I have this code:
for (int i = 0; i < NUM_BRANCHES; i++)
{
float height = i * 150;
if (branchPositions[i] == side::LEFT)
{
branches[i].setPosition(610, height);
branches[i].setRotation(180);
}
else if (branchPositions[i] == side::RIGHT)
{
branches[i].setPosition(1330, height);
branches[i].setRotation(0);
}
else
{
branches[i].setPosition(3000, height);
}
}
What it does is, it updates the position of the branch sprites.
When running the code, I get the following result:
After the following function is added and called
void updateBranches(int seed)
{
for (int j = NUM_BRANCHES - 1; j > 0; j--)
{
branchPositions[j] = branchPositions[j - 1];
}
srand((int)time(0) + seed);
int r = (rand() % 2);
switch (r)
{
case 0:
branchPositions[0] = side::LEFT;
break;
case 1:
branchPositions[0] = side::RIGHT;
break;
default:
branchPositions[0] = side::NONE;
break;
}
}
the branches get distributed randomly, like so:
Now, I do not get why this is.
I do understand why the branch at position 0 is either left, right or not visible due to the switch statement. But I don't understand how the for loop in the function interacts with the array and why this leads to the behavior shown in image 2.
I also do not understand what values are stored in the array and what the connection with the enum class is.
Could somebody please clarify ? Thanks
The first for loop in updateBranches will move the branches up the array, so that the branch that was in branch[4] will be stored in branch[5], all the way down to storing branch[0] into branch[1]. Then branch[0] is replaced with a new randomly chosen branch. Except that srand should only be called once, and not every time the function is called. And it should use % 3, not % 2, since % 2 will only give you values of 0 or 1.

Find largest X pos value in QGraphicsItems

How can I loop through a set of Qt QGraphicsItems and find the max X value within the graph items selected. I have a function which seems to work but i recall it not being ideal to set the min value to NULL. The only reason im doing that is because otherwise the value returns something insanely far away. I just don't feel like im doing this the most efficient way. Keep in mind im taking into consideration the width of the actual graph item itself.
float max = NULL;
foreach (QGraphicsItem* item, items) {
if (!item) continue;
if (item->type() == NexusBlockItem::Type) {
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
if (max == NULL) max = x;
if (x > max) {
max = x;
}
}
}
I have a function which seems to work but i recall it not being ideal
to set the min value to NULL.
It's not actually possible to set a floating point value to NULL, since only pointers can be NULL in C++ and float is not a pointer type. What you're likely actually doing there is initializing max to 0.0f (because NULL is typically defined as 0), but conceptually it doesn't make any sense, and of course it will mess up your result if any of your actual x positions are less than zero.
As far as how to do it better, you have two options that I can think of:
1) Add a separate maximum_value_is_set variable to track when your max variable is not initialized yet.
float max; // not initialized here, because...
bool maximum_value_is_set = false; // we'll keep track of it this way instead
[...]
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
if ((maximum_value_is_set == false)||(x > max)) {
max = x;
maximum_value_is_set = true;
}
2) or, alternatively, you could just set the default value of max to the smallest possible floating point value:
float max = -FLT_MAX;
[...]
... that way any conceivable x value will be greater than the original value of max.
Btw...
float x = item->pos().x() + item->sceneBoundingRect().width()*.5;
Why the *.5 there? It looks like this code computes the center the the rectangle, but according to your graphic, you are more interested in the right side (in which case I think you'd want to get rid of the *.5).
this code is for your items you shared.
float max = 0;
foreach (QGraphicsItem* item, items) {
if (!item) continue;
if (item->type() == NexusBlockItem::Type) {
float x = item->boundingRect().width();
if (x > max) {
max = x;
}
}
but if your second item or others shifted to more right other than
item->boundingRect().windth(); is not give correct value.
what is the max value of "X"? is it biggest item's width or scene Rectangle's width?

multiply numbers on all paths and get a number with minimum number of zeros

I have m*n table which each entry have a value .
start position is at top left corner and I can go right or down until I reach lower right corner.
I want a path that if I multiply numbers on that path I get a number that have minimum number of zeros in it's right side .
example:
1 2 100
5 5 4
possible paths :
1*2*100*4=800
1*2*5*4= 40
1*5*5*4= 100
Solution : 1*2*5*4= 40 because 40 have 1 zero but other paths have 2 zero.
easiest way is using dfs and calculate all paths. but it's not efficient.
I'm looking for an optimal substructure for solving it using dynammic programming.
After thinking for a while I came up to this equation :
T(i,j) = CountZeros(T(i-1,j)*table[i,j]) < CountZeros(T(i,j-1)*table[i,j]) ?
T(i-1,j)*table[i,j] : T(i,j-1)*table[i,j]
Code :
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
using Table = vector<vector<int>>;
const int rows = 2;
const int cols = 3;
Table memo(rows, vector<int>(cols, -1));
int CountZeros(int number)
{
if (number < 0)
return numeric_limits<int>::max();
int res = 0;
while (number != 0)
{
if (number % 10 == 0)
res++;
else break;
number /= 10;
}
return res;
}
int solve(int i, int j, const Table& table)
{
if (i < 0 || j < 0)
return -1;
if (memo[i][j] != -1)
return memo[i][j];
int up = solve(i - 1, j, table)*table[i][j];
int left = solve(i, j - 1, table)*table[i][j];
memo[i][j] = CountZeros(up) < CountZeros(left) ? up : left;
return memo[i][j];
}
int main()
{
Table table =
{
{ 1, 2, 100 },
{ 5, 5, 4 }
};
memo[0][0] = table[0][0];
cout << solve(1, 2, table);
}
(Run )
But it is not optimal (for example in above example it give 100 )
Any idea for better optimal sub-structure ? can I solve it with dynammic programming ?!
Let's reconsider the Bellman optimality equation for your task. I consider this as a systematic approach to such problems (whereas I often don't understand DP one-liners). My reference is the book of Sutton and Barto.
The state in which your system is can be described by a triple of integer numbers (i,j,r) (which is modeled as a std::array<int,3>). Here, i and j denote column and row in your rectangle M = m_{i,j}, whereas r denotes the multiplication result.
Your actions in state (i,j,r) are given by going right, with which you end in state (i, j+1, r*m_{i,j+1}) or by going down which leads to the state (i+1, j, r*m_{i+1,j}).
Then, the Bellman equation is given by
v(i,j,r) = min{ NullsIn(r*m_{i+1,j}) - NullsIn(r) + v_(i+1,j, r*m_{i+1,j})
NullsIn(r*m_{i,j+1}) - NullsIn(r) + v_(i,j+1, r*m_{i,j+1}) }
The rationale behind this equation is the following: NullsIn(r*m_{i+1,j}) - NullsIn(r) denotes the zeros you have to add when you take one of the two actions, i.e. the instant penalty. v_(i+1,j, r*m_{i+1,j}) denotes the zeros in the state you get to when you take this action. Now one wants to take the action which minimizes both contributions.
What you need further is only a function int NullsIn(int) which returns the nulls in a given integer. Here is my attempt:
int NullsIn(int r)
{
int ret=0;
for(int j=10; j<=r; j*=10)
{
if((r/j) * j == r)
++ret;
}
return ret;
}
For convenience I further defined a NullsDifference function:
int NullsDifference(int r, int m)
{
return NullsIn(r*m) - NullsIn(r);
}
Now, one has to do a backwards iteration starting from the initial state in the right bottom element of the matrix.
int backwardIteration(std::array<int,3> state, std::vector<std::vector<int> > const& m)
{
static std::map<std::array<int,3>, int> memoization;
auto it=memoization.find(state);
if(it!=memoization.end())
return it->second;
int i=state[0];
int j=state[1];
int r=state[2];
int ret=0;
if(i>0 && j>0)
{
int inew=i-1;
int jnew=j-1;
ret=std::min(NullsDifference(r, m[inew][j]) + backwardIteration({inew,j,r*m[inew][j]}, m),
NullsDifference(r, m[i][jnew]) + backwardIteration({i,jnew,r*m[i][jnew]}, m));
}
else if(i>0)
{
int inew=i-1;
ret= NullsDifference(r, m[inew][j]) + backwardIteration({inew,j,r*m[inew][j]}, m);
}
else if(j>0)
{
int jnew=j-1;
ret= NullsDifference(r, m[i][jnew]) + backwardIteration({i,jnew,r*m[i][jnew]}, m);
}
memoization[state]=ret;
return ret;
}
This routine is called via
int main()
{
int ncols=2;
int nrows=3;
std::vector<std::vector<int> > m={{1,2,100}, {5,5,4}};
std::array<int,3> initialState = {ncols-1, nrows -1, m[ncols-1][nrows - 1]};
std::cout<<"Minimum number of zeros: "backwardIteration(initialState, m)<<"\n"<<std::endl;
}
For your array, it prints out the desired 1 for the number of zeros.
Here is a live demo on Coliru.
EDIT
Here is an important thing: in production, you usually don't call backwardIteration as I did because it takes an exponentially increasing number of recursive calls. Rather, you start in the top left and call it, then store the result. Next you go left and down and each time call backwardIteration where you now use the previously stored result. And so on.
In order to do this, one needs a memoization concept within the function backwardIteration, which returns the already stored result instead of invoking another recursive call.
I've added memoization in the function call above. Now you can loop through the array from left top to right bottom in any way you like -- but prefereably take small steps, such as row-by-row, column-by-column, or rectangle-for-rectangle.
In fact, this and only this is the spirit of Dynamic Programming.

Implementing Alpha Beta into Minimax

I'm trying to add Alpha Beta pruning into my minimax, but I can't understand where I'm going wrong.
At the moment I'm going through 5,000 iterations, where I should be going through approximately 16,000 according to a friend. When choosing the first position, it is returning -1 (a loss) whereas it should be able to definitely return a 0 at this point (a draw) as it should be able to draw from an empty board, however I can't see where I'm going wrong as I follow my code it seems to be fine
Strangely if I switch returning Alpha and Beta inside my checks (to achieve returning 0) the computer will attempt to draw but never initiate any winning moves, only blocks
My logical flow
If we are looking for alpha:
If the score > alpha, change alpha. if alpha and beta are overlapping, return alpha
If we are looking for beta:
If the score < beta, change beta. if alpha and beta are overlapping, return beta
Here is my
Recursive call
int MinimaxAB(TGameBoard* GameBoard, int iPlayer, bool _bFindAlpha, int _iAlpha, int _iBeta)
{
//How is the position like for player (their turn) on iGameBoard?
int iWinner = CheckForWin(GameBoard);
bool bFull = CheckForFullBoard(GameBoard);
//If the board is full or there is a winner on this board, return the winner
if(iWinner != NONE || bFull == true)
{
//Will return 1 or -1 depending on winner
return iWinner*iPlayer;
}
//Initial invalid move (just follows i in for loop)
int iMove = -1;
//Set the score to be instantly beaten
int iScore = INVALID_SCORE;
for(int i = 0; i < 9; ++i)
{
//Check if the move is possible
if(GameBoard->iBoard[i] == 0)
{
//Put the move in
GameBoard->iBoard[i] = iPlayer;
//Recall function
int iBestPositionSoFar = -MinimaxAB(GameBoard, Switch(iPlayer), !_bFindAlpha, _iAlpha, _iBeta);
//Replace Alpha and Beta variables if they fit the conditions - stops checking for situations that will never happen
if (_bFindAlpha == false)
{
if (iBestPositionSoFar < _iBeta)
{
//If the beta is larger, make the beta smaller
_iBeta = iBestPositionSoFar;
iMove = i;
if (_iAlpha >= _iBeta)
{
GameBoard->iBoard[i] = EMPTY;
//If alpha and beta are overlapping, exit the loop
++g_iIterations;
return _iBeta;
}
}
}
else
{
if (iBestPositionSoFar > _iAlpha)
{
//If the alpha is smaller, make the alpha bigger
_iAlpha = iBestPositionSoFar;
iMove = i;
if (_iAlpha >= _iBeta)
{
GameBoard->iBoard[i] = EMPTY;
//If alpha and beta are overlapping, exit the loop
++g_iIterations;
return _iAlpha;
}
}
}
//Remove the move you just placed
GameBoard->iBoard[i] = EMPTY;
}
}
++g_iIterations;
if (_bFindAlpha == true)
{
return _iAlpha;
}
else
{
return _iBeta;
}
}
Initial call (when computer should choose a position)
int iMove = -1; //Invalid
int iScore = INVALID_SCORE;
for(int i = 0; i < 9; ++i)
{
if(GameBoard->iBoard[i] == EMPTY)
{
GameBoard->iBoard[i] = CROSS;
int tempScore = -MinimaxAB(GameBoard, NAUGHT, true, -1000000, 1000000);
GameBoard->iBoard[i] = EMPTY;
//Choosing best value here
if (tempScore > iScore)
{
iScore = tempScore;
iMove = i;
}
}
}
//returns a score based on Minimax tree at a given node.
GameBoard->iBoard[iMove] = CROSS;
Any help regarding my logical flow that would make the computer return the correct results and make intelligent moves would be appreciated
Does your algorithm work perfectly without alpha-beta pruning? Your initial call should be given with false for _bFindAlpha as the root node behaves like an alpha node, but it doesn't look like this will make a difference:
int tempScore = -MinimaxAB(GameBoard, NAUGHT, false, -1000000, 1000000);
Thus I will recommend for you to abandon this _bFindAlpha nonsense and convert your algorithm to negamax. It behaves identically to minimax but makes your code shorter and clearer. Instead of checking whether to maximize alpha or minimize beta, you can just swap and negate when recursively invoking (this is the same reason you can return the negated value of the function right now). Here's a slightly edited version of the Wikipedia pseudocode:
function negamax(node, α, β, player)
if node is a terminal node
return color * the heuristic value of node
else
foreach child of node
val := -negamax(child, -β, -α, -player)
if val ≥ β
return val
if val > α
α := val
return α
Unless you love stepping through search trees, I think that you will find it easier to just write a clean, correct version of negamax than debug your current implementation.

BST in array traversal

I have the following implementation of a binary tree in an array;
32
/ \
2 -5
/ \
-331 399
The data is grouped 3 indexes at a time. index%3==0 is the value of the node, index%3==1 is the index of the value of the left node and index%3==2 is the index of the value of the right node. If the left or right index reference is 0, there is no node that direction.
I'm trying to find the depth (height) of this tree. I've written it recursively
height(node):
if node == null:
return 0
else:
return max(height(node.L), height(node.R)) + 1
I want to find a non-recursive solution, however.
Here is some pseudocode i have, assuming the tree is not empty
int i = 0; int left = 0; int right = 0;
while (i != n ){
if ( a[i+1] != 0 ){
left++;
}
else if ( a[i+2] != 0 ){
right++;
}
i = i + 3;
}
return max ( left, right ) + 1;
I don't think this is right and I'd like some help figuring out how to do this correctly.
You haven't said what your problem is with recursion for us to understand what behavior you want to improve.
There are many solutions to this, but almost all of them have the same or worse performance than your recursive solution. Really, the best solutions are going to be things you'd have to do when you're creating the tree. For example, you could store the height of each node in a fourth array index per node. Then it's a trivial scan of every fourth index to find the max height. It would also make it easier if nodes had parent references stored with them so that didn't have to be computed during the height check.
One solution is to simulate recursion with a stack, but that's really no different than recursion.
Another solution is to go through each node and determine its height based on it's parent, but not in a specific traversal's order. However, because of how you have this configured, without a secondary datastructure to store the hierarchy, it's going to be less efficient O(n^2). The problem is you can't get from the child to its parent without a full array scan. Then you can do it in linear time (but recursion is also linear time, so I'm not sure we're doing better. It's also not going to be much better from a memory perspective).
Can you define what type of efficiency you want to improve?
Here's the pseudocode for each, but I'm depending on a few datastructures that aren't easily present:
"recursion without recursion" solution:
int get_height(int * tree, int length) {
Stack stack;
int max_height = 0;
if (length == 0) {
return 0;
}
// push an "array" of the node index to process and the height of its parent.
// make this a struct and use that for real c code
stack.push(0,0);
while(!stack.empty()) {
int node_index, parent_height = stack.pop();
int height = parent_height + 1;
if (height > max_height) {
max_height=height;
}
if (tree[node_index+1] != 0 )
stack.push(tree[node_index+1], height);
if (tree[node_index+2] != 0 )
stack.push(tree[node_index+2], height);
}
return max_height;
}
Now working on really slow solution that uses no additional memory, but it's REALLY bad. It's like writing fibonacci recursively bad. The original algorithm went through each node and performed O(n) checks worst case for a runtime of O(n^2) (actually not quite as bad as I had originally thought)
edit: much later I'm adding an optimization that skips all nodes with children. This is REALLY important, as it cuts out a lot of calls. Best case is if the tree is actually a linked list, in which case it runs in O(n) time. Worst case is a fully balanced tree - with logn leaf nodes each doing logn checks back to the root for O((log(n)^2). Which isn't nearly so bad. Lines below to be marked as such
"really slow but no extra memory" solution (but now updated to not be nearly so slow):
int get_height(int * tree, int length) {
int max_height = 0;
for (int i = 0; i < length; i+=3) {
// Optimization I added later
// if the node has children, it can't be the tallest node, so don't
// bother checking from here, as the child will be checked
if (tree[i+1] != 0 || tree[i+2] != 0)
continue;
int height = 0;
int index_pointing_at_me;
// while we haven't gotten back to the head of the tree, keep working up
while (index_pointing_at_me != 0) {
height += 1;
for (int j = 0; j < length; j+=3) {
if (tree[j+1] == tree[i] ||
tree[j+2] == tree[i]) {
index_pointing_at_me = j;
break;
}
}
}
if (height > max_height) {
max_height = height;
}
}
return max_height;
}
Improved on previous solution, but uses O(n) memory - this assumes parents are always before children in array (which I suppose isn't technically required)
int get_height(int * tree, int length) {
if (length == 0)
return 0;
// two more nodes per node - one for which node is its parent, the other for its height
int * reverse_mapping = malloc((sizeof(int) * length / 3) * 2)
reverse_mapping[1] = 1; // set height to 1 for first node
// make a mapping from each node to the node that points TO it.
// for example, for the first node
// a[0] = 32
// a[1] = 3
// a[2] = 6
// store that the node at 3 and 6 are both pointed to by node 0 (divide by 3 just saves space since only one value is needed) and that each child node is one taller than its parent
int max_height = 0;
for (int i = 0; i < length; i+=3) {
int current_height = reverse_mapping[(i/3)*2+1];
if (current_height > max_height)
max_height = current_height;
reverse_mapping[(tree[i+1]/3)*2] = i;
reverse_mapping[(tree[i+1]/3)*2 + 1] = current_height + 1;
reverse_mapping[(tree[i+2]/3)*2] = i;
reverse_mapping[(tree[i+2]/3)*2 + 1] = current_height + 1;
}
return max_height
}