I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Related
I have the following task:
Give a recursive algorithm for filling an array like this: one 1, two 2, tree 3, four 4, ... ,n n.
For example, with n = 4 the array is supposed to look like:
{ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4 }
My attempt is
Function filling(T, k, n)
if (n = 0) do return 1
else if (0 <= k) do filling (T, n - k + 1, n);
else filling(T, k, n - 1);
fi
fi
with filling(T, k, n)
k: block start case of number n,
n: number,
T: array
As you correctly show, the function needs an array T, a starting index k of the area to fill, and a size of the task n, i.e. a maximum number for filling.
The algorithm can be described like this:
if n is zero, return;
otherwise:
perform filling from 1 till n-1,
then append n items of value n
The question arises, how should the last line know where it should start adding.
One simple answer is: the routine may return the index one past the filled area:
size_t filling(int T[], size_t k, size_t n)
{
if (n != 0)
{
k = filling(T, k, n - 1);
for (size_t i = 0; i < n; i++)
T[k + i] = n;
}
return k + n;
}
Make sure your array is at least n*(n+1)/2 items long, so that you don't overrun it.
You need to take care of two things here:
Number of digits to be insert in the array starting from 1, and
Count of a digit (which should be equal to digit itself) when inserting it in the array.
Since, the algorithm should be implemented using recursion, we should know the terminating condition of recursion.
Algorithm:
Insert digit in array.
Check if the count of digit inserted in array is equal to digit or not:
If count == digit then reset the count to 0 and increase digit by 1.
If count < digit go to step 1.
If digit to be inserted in array is greater than n, terminate the recursion.
Implementation in c++:
#include <iostream>
#include <vector>
void filling (std::vector <int>& arr, int k, int n) {
static int c;
if (c >= n) {
c = 0;
return;
}
if (k <= c) {
k = k + 1;
arr.push_back(c + 1);
} else {
k = 0;
c = c + 1;
}
filling (arr, k, n);
}
int main() {
std::vector <int> arr;
int n;
std::cout << "Enter a number:" << std::endl;
std::cin >> n;
filling (arr, 0, n);
for (const auto& x : arr) {
std::cout << x << " ";
}
std::cout << std::endl;
return 0;
}
Output:
# ./a.out
Enter a number:
5
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
# ./a.out
Enter a number:
10
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10
# ./a.out
Enter a number:
1
1
# ./a.out
Enter a number:
4
1 2 2 3 3 3 4 4 4 4
I've tried to solve problem 2 on Project Euler in C. This is the first possible solution that came to my mind, and, in fact, it gives as an output the right answer. The problem is that each time I run my program it gives me a different output, which is either "2" or "4613732" that is the right answer. Sorry for my poor english, can you help me find out what's wrong?
#include <stdio.h>
int main(){
int n, n1 = 1, n2 = 2, sum = 2;
while(n<4000000){
n = n1 + n2; /*calculate the next number of the series*/
n1 = n2;
n2 = n;
if(n%2 == 0){
sum = sum + n; /*if the number it's even add it to the main sum*/
}
}
printf("The sum is %d\n", sum);
}
You didn't initialize n; when you get the right answer, it means you got lucky.
#include <conio.h>
#include <iostream>
using namespace std;
int evenFibSum(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int sum = 0;
while (sum < max)
{
sum = i + j;
i = j;
j = sum;
if (sum % 2 == 0)
eventsum +=sum;
}
return eventsum;
}
For more efficient solution apply following logic
Fibbonaci Series => 1 2 3 5 8 13 21 34 55 89 144
Index => 0 1 2 3 4 5 6 7 8 9 10
To get even fibbonanci addition I have to add following index values[1 4 7 10]
Here I am sensing some pattern
[1 4 7 10] => I need advance index by 3
so how to advance index by 3
// k = i+j = > 3 13 55
// i = k+j => 5 21 89
// j = k+i => 8 34 144
int evenFibSumx(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int k= 0;
while (1)
{
k = i + j;
i = k + j;
j = k + i;
if(i >= max)
break;
if (j%2 == 0)
eventsum +=j;
}
return eventsum;
}
int main()
{
std::cout << evenFibSum();
std::cout << evenFibSumx();
}
I am a beginner in coding .I want to solve the following problem using simple recursion and array. But I can't visualize it. I came up with solution using link list .Following are problem and my way of solving
Given n rows of integers, such that the ith row (1 <= i <= n)
contains i integers. Using the following set of path rules, find the
path having the maximum weight.
Path traversal rules:
A valid path sequence would be top-down i.e. begins with the integer in the first row, and traverses all rows selecting only one
integer in each row.
From any jth integer in the ith row i.e. row[i][j], traversal can happen either downward (i.e. to row[i+1][j]) or diagonally downward
to the right (i.e. to row[i+1][j+1]).
The weight of a Path is the sum of values of integers in the Path
sequence.
Example:
No. of Rows: 5
4
2 9
15 1 3
16 92 41 44
8 142 6 4 8
Expected Output: 4, 2, 15, 92, 142 (Max weight is 255)
Sol.c
#include<stdio.h>
#include<stdlib.h>
int n,**ar;
struct n
{
int i,j;
int w;
struct n *ptr;
};
struct n* maxweight(int i,int j,struct n* x)
{
struct n* tmp=malloc(sizeof(struct n)),*t1,*t2;
tmp->i=i;
tmp->j=j;
tmp->ptr=x;
tmp->w=ar[i][j];
if(x)tmp->w+=x->w;
if(i==n-1)return tmp;
t1=maxweight(i+1,j,tmp);
t2=maxweight(i+1,j+1,tmp);
if(t1->w>t2->w)return t1;
return t2;
}
int main()
{
int i,j;
struct n * s;
printf("Enter the value of n\n");
scanf("%d",&n);
ar=malloc(n*sizeof(int*));
for(i=0;i<n;i++)
{
ar[i]=malloc((i+1)*sizeof(int));
for(j=0;j<=i;j++)scanf("%d",&ar[i][j]);
}
s=maxweight(0,0,NULL);
printf("MAX WEIGHT is :%d\nPATH: ",s->w);
while(s)
{
printf("%d ",ar[s->i][s->j]);
s=s->ptr;
}
printf("\n");
return 0;
}
How do I solve this using recursion simply without link-list using n x n matrix ? Is dynamic programming is applicable to this problem.
Focus on calculating the weight of the path that lies ahead of you; don't look back.
Start by solving a trivial edge case. Suppose you made it to the bottom row. Then there is nothing more to follow; the remaining path has weight zero.
In code:
int getWeight(int i, int j)
{
int remaining = 0;
In any other row, you have to make a choice. Should you go left or right? Since there is no way of knowing at this point which one is best, you just have to try both directions:
if (i < lastRow)
{
int weightLeft = getWeight(i + 1, j);
int weightRight = getWeight(i + 1, j + 1);
Notice I recursively called my own function; with a blind faith in that function's capability to come up with the optimal weight for the remaining path!
Having tried both directions, pick whichever came up with the highest weight:
int best_j = weightLeft > weightRight ? j : j + 1;
Now we walk the chosen path one more time.
remaining = getWeight(i + 1, best_j);
}
This is not very efficient, but it helps to collect the individual steps of the optimal path. I will use a straightforward array pathColumns.
pathColumns[i] = j;
Finally, we need to sum the values.
return row[i][j] + remaining;
}
To set the whole thing in motion, just call the function, and pass it the top cell's coordinates. For practical reasons, I made all arrays base-0. So the top cell is row[0][0].
printf("Optimal weight: %d\n", getWeight(0, 0));
Putting it all together:
#include <stdio.h>
#define n 5
int pathColumns[n] = {0};
int row[n][n] =
{
{4},
{2, 9},
{15, 1, 3},
{16, 92, 41, 44},
{8, 142, 6, 4, 8}
};
int getWeight(int i, int j)
{
int remaining = 0;
if (i < n-1) /* with base-0, the last row is n-1 */
{
int weightLeft = getWeight(i + 1, j);
int weightRight = getWeight(i + 1, j + 1);
int best_j = weightLeft > weightRight ? j : j + 1;
remaining = getWeight(i + 1, best_j);
}
pathColumns[i] = j;
return row[i][j] + remaining;
}
int main()
{
int i;
printf("Optimal weight: %d\n", getWeight(0, 0));
for (i = 0; i < n; i++)
{
int j = pathColumns[i];
printf("(%d, %d) = %d\n", i+1, j+1, row[i][j]);
/* NOTE: +1 is a correction to bring the output back to base-1 */
}
return 0;
}
Output:
Optimal weight: 255
(1, 1) = 4
(2, 1) = 2
(3, 1) = 15
(4, 2) = 92
(5, 2) = 142
How it works
We want getWeight(0, 0) to return the heaviest path for this pyramid.
4 <---- (0, 0) is our starting point
/ \
2 9
/ \ / \
15 1 3
/ \ / \ / \
16 92 41 44
/ \ / \ / \ / \
8 142 6 4 8
The recursive algorithm makes two recursive calls.
getWeight(1, 0) must get the heaviest path for the sub-pyramid below and to the left of our starting point.
getWeight(1, 1) must get the heaviest path for the sub-pyramid below and to the right of our starting point.
The two sub-pyramids:
2 <--- (1, 0) 9 <--- (1, 1)
/ \ / \
15 1 1 3
/ \ / \ / \ / \
16 92 41 92 41 44
/ \ / \ / \ / \ / \ / \
8 142 6 4 142 6 4 8
Assuming getWeight(1, 0) and getWeight(1, 1) return the correct weights (251 and 244, respectively), all there is left to do is pick the highest one (251) and add the top value of the big pyramid to it (4). The result is 255.
What we did is reduce a problem (calculate the maximum weight for a pyramid of height 5) so that we are left with two smaller problems to solve (calculate the maximum weight for pyramids of height 4). In the same way, we can reduce the problem for height 4 to solving the same problem for height 3. For example, getWeight(1, 1) will make two recursive calls getWeight(2, 1) and getWeight(2, 2):
1 <--- (2, 1) 3 <--- (2, 2)
/ \ / \
92 41 41 44
/ \ / \ / \ / \
142 6 4 6 4 8
getWeight(1, 1) should return 244 = 9 + max(235, 55).
Continuing this way, we eventually end up with solving the problem for pyramids of height 1. These are the values at the base of the original pyramid (8, 142, 6, 4 and 8). Here the recursion ends; a pyramid of height 1 is nothing more than a single node. The value of that node is the weight of the (only) path through that pyramid.
I'm writing a program that is to take a number between 1-10 and display all possible ways of arranging the numbers.
Ex
input: 3
output:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Whenever I input 9 or 10, the program gives a segmentation fault and dumps the core. I believe the issue is my recursive algorithm is being called too many times. Could someone help point out how I could limit the amount of recursive calls necessary? Here is my current code:
void rearange(int numbers[11], int index, int num, int fact) {
int temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
if (fact > 0) // If we have more sequences remaining
rearange(numbers, index, num, fact); // Do it all again! :D
}
int main() {
int num, i; // our number and a counter
printf("Enter a number less than 10: ");
scanf("%d", &num); // get the number from the user
int numbers[11]; // create an array of appropriate size
// fill array
for (i = 1; i <= num; i++) { // fill the array from 1 to num
numbers[i] = i;
}
int fact = 1; // calculate the factorial to determine
for (i = 1; i <= num; ++i) // how many possible sequences
{
fact = fact * i;
}
rearange(numbers, num, num, fact); // begin rearranging by recursion
return 0;
}
9! (362880) and 10! (3628800) are huge numbers that overflow the call stack when you do as many recursive calls. Because all the local variables and formal parameters have to be stored. You either you have to increase the stack size or convert the recursion into iteration.
On linux, you can do:
ulimit -s unlimited
to set the stack size to unlimited. The default is usually 8MB.
Calculating permutations can be done iteratively, but even if you do it recursively there is no need to have a gigantic stack (like answers suggesting to increase your system stack say). In fact you only need a tiny amount of your stack. Consider this:
0 1 <- this needs **2** stackframes
1 0 and an for-loop of size 2 in each stackframe
0 1 2 <- this needs **3** stackframes
0 2 1 and an for-loop of size 3 in each stackframe
1 0 2
1 2 0
2 1 0
2 0 1
Permuting 9 elements takes 9 stackframes and a for-loop through 9 elements in each stackframe.
EDIT: I have taken the liberty to add a recursion-counter to your rearrange-function, it now prints like this:
Enter a number less than 10: 4
depth 1 1 2 4 3
depth 2 1 4 2 3
depth 3 4 1 2 3
depth 4 4 1 3 2
depth 5 4 3 1 2
depth 6 3 4 1 2
depth 7 3 4 2 1
depth 8 3 2 4 1
depth 9 2 3 4 1
depth 10 2 3 1 4
depth 11 2 1 3 4
depth 12 1 2 3 4
depth 13 1 2 4 3
depth 14 1 4 2 3
depth 15 4 1 2 3
depth 16 4 1 3 2 which is obviously wrong even if you do it recursively.
depth 17 4 3 1 2
depth 18 3 4 1 2
depth 19 3 4 2 1
depth 20 3 2 4 1
depth 21 2 3 4 1
depth 22 2 3 1 4
depth 23 2 1 3 4
depth 24 1 2 3 4
....
The recursion-leafs should be the only ones which output so the depth should be constant and small (equal to the number you enter).
EDIT 2:
Ok, wrote the code. Try it out:
#include "stdio.h"
void betterRecursion(int depth, int elems, int* temp) {
if(depth==elems) {
int j=0;for(;j<elems;++j){
printf("%i ", temp[j]);
}
printf(" (at recursion depth %u)\n", depth);
} else {
int i=0;for(;i<elems;++i){
temp[depth] = i;
betterRecursion(depth+1, elems, temp);
}
}
}
int main() {
int temp[100];
betterRecursion(0, 11, temp); // arrange the 11 elements 0...10
return 0;
}
I'd make your rearange function iterative - do while added, and recursive call removed:
void rearange(int numbers[11], int index, int num, int fact) {
int temp;
do
{
temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
} while (fact > 0);
}
This is not a task for a deep recursion.
Try to invent some more stack-friendly algorithm.
Following code has rather troubles with speed than with stack size...
It's a bit slow e.g. for n=1000 but it works.
#include <stdio.h>
void print_arrangement(int n, int* x)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s%d", i ? " " : "", x[i]);
}
printf("\n");
}
void generate_arrangements(int n, int k, int* x)
{
int i;
int j;
int found;
if (n == k)
{
print_arrangement(n, x);
}
else
{
for(i = 1; i <= n; i++)
{
found = 0;
for(j = 0; j < k; j++)
{
if (x[j] == i)
{
found = 1;
}
}
if (!found)
{
x[k] = i;
generate_arrangements(n, k + 1, x);
}
}
}
}
int main(int argc, char **argv)
{
int x[50];
generate_arrangements(50, 0, x);
}
Your program is using too many recursions unnecessarily. It is using n! recursions when actually n would be enough.
To use only n recursions, consider this logic for the recursive function:
It receives an array nums[] of n unique numbers to arrange
The arrangements can have n different first number in them, as there are n different numbers in the array
(key step) Loop over the elements of nums[], and in each iteration create a new array but with the current element removed, and recurse into the same function passing this shorter array as parameter
As you recurse deeper, the parameter array will be smaller and smaller
When there is only one element left, that's the end of the recursion
Using this algorithm, your recursion will not be deeper than n and you will not get segmentation fault. The key is in the key step, where you build a new array of numbers that is always 1 item shorter than the input array.
As a side note, make sure to check the output of your program before you submit, for example run it through | sort | uniq | wc -l to make sure you are getting the correct number of combinations, and check that there are no duplicates with | sort | uniq -d (the output should be empty if no dups).
Spoiler alert: here's my implementation in C++ using a variation of the above algorithm:
https://gist.github.com/janosgyerik/5063197
In the hottest part of my program (90% of time according to gprof), I need to sum one array A into another B. Both arrays are 2^n (n is 18..24) sized and holds an integer (for simplicity, actually the element stored is mpz_t or small int array). The rule of summing: for each i in 0..2^n-1, set B[i] = sum (A[j]), where j is bit vector, and j & ~ i == 0 (in other words, k-th bit of any j can't be set to 1 if k-th bit of i is not 1).
My current code (this is a body of innermost loop) does this in the time of 2^(1.5 * n) sums, because I will iterate for each i on (in average) 2^(n/2) elements of A.
int A[1<<n]; // have some data
int B[1<<n]; // empty
for (int i = 0; i < (1<<n); i++ ) {
/* Iterate over subsets */
for (int j = i; ; j=(j-1) & i ) {
B[i] += A[j]; /* it is an `sum`, actually it can be a mpz_add here */
if(j==0) break;
}
}
My I mentioned, that almost any sum is recomputed from the values, summed earlier. I suggest, there can be code, doing the same task in the time of n* 2^n sums.
My first idea is that B[i] = B[i_without_the_most_significant_bit] + A[j_new]; where j_new is only j's having the most_significant bit from i in '1' state. This halves my time, but this is not enough (still hours and days on real problem size):
int A[1<<n];
int B[1<<n];
B[0] = A[0]; // the i==0 will not work with my idea and clz()
for (int i = 1; i < (1<<n); i++ ) {
int msb_of_i = 1<< ((sizeof(int)*8)-__builtin_clz(i)-1);
int i_wo_msb = i & ~ msb;
B[i] = B[i_wo_msb];
/* Iterate over subsets */
for (int j_new = i; ; j_new=(j_new-1) & i ) {
B[i] += A[j_new];
if(j_new==msb) break; // stop, when we will try to unset msb
}
}
Can you suggest better algorithm?
Additional image, list of i and j summed for each i for n=4:
i j`s summed
0 0
1 0 1
2 0 2
3 0 1 2 3
4 0 4
5 0 1 4 5
6 0 2 4 6
7 0 1 2 3 4 5 6 7
8 0 8
9 0 1 8 9
a 0 2 8 a
b 0 1 2 3 8 9 a b
c 0 4 8 c
d 0 1 4 5 8 9 c d
e 0 2 4 6 8 a c e
f 0 1 2 3 4 5 6 7 8 9 a b c d e f
Note the similarity of figures
PS the msb magic is from here: Unset the most significant bit in a word (int32) [C]
Divide and conquer anyone? Now not in-place.
void sums(int *a, int n, int *b) {
if (n <= 0) {
*b = *a;
return;
}
int m = 1 << (n - 1);
sums(a, n - 1, b);
sums(a + m, n - 1, b + m);
for (int i = 0; i < m; i++) {
b[m + i] += b[i];
}
}