This is my test array
int [] A = {1,2,7,3,5,6};
this is the method
public static int largest(int [] A)
{
int temp = A[0];
return largestRec(A, 0, A.length - 1, temp);
}
// WRITE THIS METHOD that returns the largest of the elements in A
// that are indexed from low to high. RECURSIVELY!
private static int largestRec(int [] A, int low, int high, int temp)
{
if (low == high)
return A[low];
if (low <= A.length){
if (A[low] > temp){
temp = A[low];
}
largestRec(A, low+1, high, temp);
}
return temp
}
Why does the tem reset and return A[0] which is 1?
The problem is that you are not doing anything with the return value of the recursive call to largestRec. Remember that parameters are pass by value (even in recursive calls to the same function) so changing it inside the function does not affect the outside.
I don't think you should be passing the temp as a parameter at all.
private static int largestRec(int [] A, int low, int high )
{
int temp;
if (low == high)
temp = A[low];
else
{
temp = largetstRec( A, low+1, high );
if (A[low] > temp){
temp = A[low];
}
}
return temp;
}
That keeps temp local to the function (which I think is what you probably meant be calling it temp in the first place).
private static int largestRec(int [] A, int low, int high){
var largest = A[low];
if(low == high)
return largest; // or A[high] because both are same
for(var i = low; i < high; i++){
if(largest < A[i])
largest = A[i];
}
return largest;
}
Related
I tried this problem by backtracking and did some optimization, though I am getting TLE. what further optimization can I do on this code?
Abridged problem statement - Task is to print all different r combinations of a string s (a r combination of a string s is a collection of exactly r letters from different positions in s).There may be different permutations of the same combination; consider only the one that has its r
characters in non-decreasing order. If s = "abaa" and s = 3.Then output should be (aaa,aab).
My code(in c)
int compare_chars(const void* a, const void* b);
char s[50];
int len;
int r ;
char combination[50];
void combinate(int index,int at)
{
if(at == r)
{
combination[at] = '\0';
puts(combination);
return ;
}
int i = index+1;
for ( ; i <= len-r+at ;)
{
char temp = s[I];
combination[at] = temp;
combinate(i,at+1);
while(s[i] == temp and i <= len-r+at)
i++;
}
return ;
}
int solve()
{
while ((scanf("%s %i",s,&r)) == 2)
{
len = strlen(s);
if(len == r)
{
printf("%s\n",s);
continue;
}
qsort(s,len,sizeof(char),compare_chars);
combinate(-1,0);
}
return 0;
}
int main()
{
int a = 1;
int t = 1;
while (a <= t)
{
int kk = solve();
}
return 0;
}
int compare_chars(const void* a, const void* b)
{
char arg1 = *(const char*)a;
char arg2 = *(const char*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
I am currently busy with a project that requires you to use the minimax with AB pruning.
I have successfully implemented a serial version of the program
//Assume maximizing player is WHITE
int minimax_move(int *current_board, int player, int *chosen_move, int alpha, int beta) {
int *moves_list;//capture the moves for a board
int moves_len;
int opponent = BLACK;
if (player == BLACK) {
opponent = WHITE;
}
get_moves_list(current_board,&moves_list,&moves_len,player);
//No Move to be generated
if (moves_list[0] == 0) {
*chosen_move = -1;
} else {
//Remember the best move
int best_move_value = INT_MIN;
int best_move = moves_list[1];
//Try all the moves
for (int i = 1; i <= moves_len; i++) {
int *temp_board = (int *) malloc(sizeof(int) * BOARDSIZE);
copy_board(current_board,temp_board);
apply_move(&temp_board,moves_list[i],player);
//Initial Call to minimax_value
int value = minimax_value(temp_board,player,opponent,1,alpha,beta);
//Remember best move
if (value > best_move_value) {
best_move_value = value;
best_move = moves_list[i];
}
}
//Set the chosen move
*chosen_move = best_move;
printc("Chosen Move is: %d\nFrom %s\n",*chosen_move,get_turn_player(player));
}
return *chosen_move;
}
//original_turn -> maximizing player
//current_turn -> minimizing_player
//Current turn is what alternates the turn player when simulating move look aheads
//The maximizing player is established in minimax_moves
int minimax_value(int *current_state,int original_turn, int current_turn,int depth,int a,int b) {
if (depth == MAXDEPTH || is_game_over(current_state)) {
return evaluate_board(current_state);
}
int *moves_list;
int moves_len;
int opponent = BLACK;
if (current_turn == BLACK) {
opponent = WHITE;
}
get_moves_list(current_state,&moves_list,&moves_len,current_turn);
//if no moves, skip to next player's (opponent) turn
if (moves_list[0] == 0) {
return minimax_value(board,original_turn,opponent,depth+1,a,b);
} else {
//Remember the best move - Setting the limits
//For max player
int best_move_value = INT_MIN;
int alpha = a;
int beta = b;
if (original_turn != current_turn) {
//original_turn -> max player
//current_tunr -> min player
best_move_value = INT_MAX;
}
for (int i = 1; i <= moves_len; i++) {
//Apply a move to the board
int *temp_board = (int *) malloc(sizeof(int) * BOARDSIZE);
copy_board(current_state,temp_board);
apply_move(&temp_board,moves_list[i],current_turn);
//Recursive calls
int value = minimax_value(temp_board,original_turn,opponent,depth+1,alpha,beta);
//Remember best move
//MAX PLAYER
if (original_turn == current_turn) {
if (value > best_move_value) {
best_move_value = value;
}
if (value > alpha) {
alpha = value;
}
} else {
//MIN PLAYER
if (value < best_move_value) {
best_move_value = value;
}
if (value < beta) {
beta = value;
}
}
//Alpha-Beta pruning
printc("ALPHA: %d - BETA: %d\n",alpha,beta);
if (beta <= alpha) {
printc("\n\nPRUNED\n\n");
break;
}
}
return best_move_value;
}
//return -1; ERROR
}
The project requires me to use MPI to parallelize the minimax algorithm. I have no idea where to start. I have read http://www.pressibus.org/ataxx/autre/minimax/node6.html#SECTION00060000000000000000
but am no closer to solving the problem as I do not understand the psuedo-code written.
My idea was to somehow scatter the moves_list generated in minimax_move() amongst (n-1) slave processes where 1 process will be the master process. However, the first call to minimax_move() yields a move_list of length 3, and we can assume that the number of processors that will be used to run the program will be >= 4.
I would appreciate a starting point on how to solve this as I cannot seem to wrap my head around how I would use MPI to parallelize this. It has to be done using MPI.
Ultimately alpha-beta mini-maxing requires you to score every tree generated by a turn and choose the best one. It sounds like your task is to parallelise the calculation of the scores, you should be able to utilise different processors to score different trees.
vector<int> a;
a.push_back(0);
int n = a.size();
int cnt = 0;
for (auto itr = a.begin(); itr != a.end(); itr++)
{
if(*itr == 0)
{
cnt++;
a.erase(itr);
}
}
The code is working on inserting numbers other than zero.
The line a.erase(itr) is giving a runtime error for some reason.
Please help.
with erase you modify the vector so the iterator become invalid, a solution modifying a little your code :
vector<int> a;
a.push_back(0);
int n=a.size();
int cnt=0;
auto itr=a.begin();
while (itr != a.end())
{
if(*itr == 0)
{
cnt++;
itr = a.erase(itr);
}
else
++itr;
}
Note the right type for n and count is size_type rather than int
question:
Write a recursive method flgIsSorted to check if a given array (provided as a parameter) is sorted in increasing order. The method returns true if and only if the array is sorted in increasing order. Hint, when the array has only one element, it is sorted. If the first half is sorted, the second half is sorted, and the first element of the second half is not smaller than the last element in the first half, the array is sorted. Your initial method can only take one parameter – the array. That method can call another auxiliary method that takes other parameters.
public boolean flgIsSorted(int a[], int startIndex, int endIndex ){
boolean result = false;
if(startIndex < endIndex){
int mid = (startIndex + endIndex)/2;
flgIsSorted(a, startIndex, mid);
flgIsSorted(a, mid+1, endIndex);
result = check(a, startIndex, mid, endIndex);
}
return result;
}
public boolean check(int a[], int startIndex, int mid, int endIndex){
//deal with left array
//If array has odd number of elements,
//left array will be even number
//and right array will be odd number
int n1 = mid - startIndex + 1;
// n1 is index, and we need n1 + 1 spots for copy array
int L[] = new int[n1 + 1];
//copy subarray A[p..q] into L[0..n1],
//i starts from the beginning of unsorted array
for(int i = startIndex; i <= mid + 1; i++){
//make sure copy to the index 0 of left array
L[i - startIndex] = a[i];
}
L[n1] = Integer.MAX_VALUE;
//deal with right array
int n2 = endIndex - mid;
int R[] = new int[n2 + 1];
//copy subarray A[q+1..r] into R[0..n2]
for(int j = mid + 1; j <= endIndex; j++){
//make sure start from the index 0 of right array
R[j - (mid + 1)] = a[j];
}
R[n2] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
boolean result = false;
for(int k = startIndex; k <= endIndex; k++){
if(L[i] < R[j]){
//a[k] = L[i];
i++;
result = true;
System.out.println("true in check");
}else{
//a[k] = R[j];
j++;
System.out.println("false in check");
result = false;
}
}
System.out.println("return in check final");
return result;
}
Problem:
It always returns true.
I think I just figured it out this morning. At least the output is what I want now.
Code:
public boolean flgIsSorted(int a[], int startIndex, int endIndex){
boolean result = false;
if(a.length == 1){
result = true;
}else{
if(startIndex < endIndex){
int mid = (startIndex + endIndex)/2;
if(a[startIndex] <= a[mid + 1]){
result = true;
}else{
result = false;
}
flgIsSorted(a, startIndex, mid);
flgIsSorted(a, mid + 1, endIndex);
}
}
return result;
}
This dynamic programming algorithm is returning unhandled exception error probably due to the two dimensional arrays that I am using for various (and very large) number of inputs. I can't seem to figure out the issue here. The complete program as follows:
// A Dynamic Programming based solution for 0-1 Knapsack problem
#include<stdio.h>
#include<stdlib.h>
#define MAX 10000
int size;
int Weight;
int p[MAX];
int w[MAX];
// A utility function that returns maximum of two integers
int maximum(int a, int b) { return (a > b) ? a : b; }
// Returns the maximum value that can be put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
int i, w;
int retVal;
int **K;
K = (int**)calloc(n+1, sizeof(int*));
for (i = 0; i < n + 1; ++i)
{
K[i] = (int*)calloc(W + 1, sizeof(int));
}
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= W; w++)
{
if (i == 0 || w == 0)
K[i][w] = 0;
else if (wt[i - 1] <= w)
K[i][w] = maximum(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]);
else
K[i][w] = K[i - 1][w];
}
}
retVal = K[n][W];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;
}
int random_in_range(unsigned int min, unsigned int max)
{
int base_random = rand();
if (RAND_MAX == base_random) return random_in_range(min, max);
int range = max - min,
remainder = RAND_MAX % range,
bucket = RAND_MAX / range;
if (base_random < RAND_MAX - remainder) {
return min + base_random / bucket;
}
else {
return random_in_range(min, max);
}
}
int main()
{
srand(time(NULL));
int val = 0;
int i, j;
//each input set is contained in an array
int batch[] = { 10, 20, 30, 40, 50, 5000, 10000 };
int sizeOfBatch = sizeof(batch) / sizeof(batch[0]);
//algorithms are called per size of the input array
for (i = 0; i < sizeOfBatch; i++){
printf("\n");
//dynamic array allocation (variable length to avoid stack overflow
//calloc is used to avoid garbage values
int *p = (int*)calloc(batch[i], sizeof(int));
int *w = (int*)calloc(batch[i], sizeof(int));
for (j = 0; j < batch[i]; j++){
p[j] = random_in_range(1, 500);
w[j] = random_in_range(1, 100);
}
size = batch[i];
Weight = batch[i] * 25;
printf("| %d ", batch[i]);
printf(" %d", knapSack(Weight, w, p, size));
free(p);
free(w);
}
_getch();
return 0;
}
Change this:
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return K[size][Weight];
To this:
int retVal;
...
retVal = K[size][Weight];
for (i = 0; i < size + 1; i++)
free(K[i]);
free(K);
return retVal;