This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Here is part of my code. The rest is just the function definitions. I have an array of 20 x 20 that records the temperature of a plate. I need to reiterate through a loop until no cell in the array changes more than 0.1 degree (I refresh the values through every iteration) How would you monitor the largest change for any cell in an array in order to determine when to stop iterating? Right now I have tried this, but it doesn't output correctly. I believe it is because I am incorrectly defining my previous one to compare the current one with.
while (true)
{
bool update = false;
for (int a = 1; a < array_size -1; a++)
{
for (int b = 1; b < array_size -1; b++)
{
hot_plate[a][b] = sum_cell(hot_plate, a, b);
}
}
for (int a = 1; a < array_size-1; a++)
{
for (int b = 1; b < array_size-1; b++)
{
hot_plate_next[a][b]=sum_cell(hot_plate_next, a,b);
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
hot_plate_next[a][b] = hot_plate[a][b];
cout << hot_plate[a][b] << " ";
}
}
if (!update) {
break;
}
}
The problem is that you overwrite update when a cell has a smaller change. In that case, any cell that has a smaller change will stop the iteration.
Structure your loop like this:
float largest_change = 0.0f;
do {
largest_change = 0.0f;
for (...) {
float new_value = ...
float change = abs(new_value - hot_plate[a][b]);
if (change > largest_change)
largest_change = change;
hot_plate[a][b] = change;
}
} while (largestChange > 0.1f);
When you put:
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) < 0.1)
{
update = false;
}
inside the 2nd nested for-loop, you are setting "update" to false if ANY of the cells have a difference less than 0.1 between current and previous checks, instead of ALL cells like you wanted.
Update your code as follows:
bool update = false;
and
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
(I would have put >=, but you said "until no cell in the array changes more than 0.1 degree")
Edit as per request: to output the matrix cleanly, add the following line:
cout << "\n";
here:
for (int a = 1; a < array_size-1; a++)
{
for (int b = 1; b < array_size-1; b++)
{
hot_plate_next[a][b]=sum_cell(hot_plate_next, a,b);
if (abs(hot_plate_next[a][b] - hot_plate[a][b]) > 0.1)
{
update = true;
}
hot_plate_next[a][b] = hot_plate[a][b];
cout << hot_plate[a][b] << " ";
}
cout << "\n"; // Add this line
}
Related
Could anyone point the flaw in the code?
The idea that I used is backtracking with recurrence and I would like to stick to this way of sloving the given problem. When the variable moves is <= 60 couple of answers are printed instantly though the program is still running. If moves = 61,62 it takes couple of minutes to print some solutions and if moves = 63 no solution is printed within 15 mins in both cases the program is still running.
Here is the code:
//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;
void solve()
{
//printing one solution
if(moves==63)
{
for(int k = 0; k < 8; k++)
{
for(int n = 0; n < 8; n++)
cout << setw(2) << board[k][n] << " ";
cout << "\n";
}
cout << "--------------------\n";
return;
}
else
{
for(int i = 0; i < 8; i++)
{
//checking if knight is not leaving the board
if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
continue;
//moving theknight
x+=move_to[i][0];
y+=move_to[i][1];
//increasing the moves count
moves++;
//marking the square to be visited
board[x][y] = moves+1;
//backtracking
solve();
board[x][y] = 0;
x-=move_to[i][0];
y-=move_to[i][1];
moves--;
}
}
}
int main()
{
solve();
return 0;
}
I remember this problem from study. I do not fix them but I change initial position then the first path is found faster (that is how I passed this lab ;P). It is normal because
the number of path is too big.
But you can:
choose from move_to in random order
use multiple threads
Other hand you can read about "Constraint Programming"
So I am currently working on a project to place N queens on an NxN board and prevent them from attacking each other. This project is for an intro level AI course. It has a few specific criteria to get full points which are, finding up to 3 solutions for any board size up to N = 100 in 5 seconds or less. I'm currently trying to make this a constraint satisfaction problem by choosing the most constrained row which if I understand it correctly will prevent rows that are closer to fully attacked from getting there.
Initially the user will input a column number and a queen will be placed in that column on the first row of the board. From there the attack board will be updated using that row column combination by increasing the value of all diagonals and the row and column a small example of the former and the latter below
void main()
{
int size, row, col;
row = 1;
cout << "Enter the board size: ";
cin >> size;
cout << "Enter column of first queen: ";
cin >> col;
cols[row] = col; // cols store the column value of each queen in that particular row.
updateAttack(row, col, +1, size);
findNextQueen(size);
// return here if we found all the solution
//cout << solutionCount << " solutions found. see NQueen.out.\n";
cout << solutionCount << " solutions found. see NQueen.out.\n";
fout.close();
system("pause");
}
void updateAttack(int r, int c, int change, int size) // Updates the attack board given the location a queen being placed
{
int r1, c1;
// update diagnals
for (r1 = r - 1, c1 = c - 1; r1 >= 1 && c1 >= 1; r1--, c1--)
attack[r1][c1] += change;
for (r1 = r + 1, c1 = c + 1; r1 <= size && c1 <= size; r1++, c1++)
attack[r1][c1] += change;
for (r1 = r - 1, c1 = c + 1; r1 >= 1 && c1 <= size; r1--, c1++)
attack[r1][c1] += change;
for (r1 = r + 1, c1 = c - 1; r1 <= size && c1 >= 1; r1++, c1--)
attack[r1][c1] += change;
// update columns
for (r1 = 1, c1 = c; r1 <= size; r1++) // k goes to each row
attack[r1][c1] += change;
}
The main issue with this program is choosing which row to place the queen in. In a simple backtracking method with recursive calls of the queen placing you increment down the rows and place the queen in the first space in that row that isn't currently under attack and then doing the same for the next row and the next queen until the queen cannot be placed, in which case you backtrack and attempt to fix the previous queen by moving it to the next spot. An example of this being done with backtracking and no CSP implemented below.
void findNextQueen(int r, int size)
{
for (int c=1;c<=size;c++)
{
if (attack[r][c]==0) // not under attack
{
cols[r]=c; // assign another queen
if (r<size)
{
updateAttack(r,c,+1, size);
findNextQueen(r+1, size);
updateAttack(r,c, -1, size);
}
else
{
print1solution(size);
if (solutionCount >= 3)
{
cout << solutionCount << " solutions found. see NQueen.out.\n";
system("pause");
exit(0);
}
}
}
}
return;
}
The constraint satisfaction attempts to solve a problem caused during this backtracking where you might later on completely fill rows below with attack values which will cause alot of backtracking to be required increasing the time it takes by alot of time. It does this by attempting to choose rows that have more spaces being attacked first in order to prevent them from being lost and requiring the late backtracking. My example of this that is causing the issues, currently that it always seems to come to 0 solutions possible below.
void findNextQueen(int size)
{
int bestRowCount = 0;
int bestRow = 2;
for (int r = 2; r <= size; r++) // Meant to find the most constrained row and use that as my r value for attack array
{
int aRowCount = 0; // Count of attacks in current row
for (int c = 1; c <= size; c++)
{
if (attack[r][c] >= 1)
{
aRowCount++;
}
}
if ((aRowCount > bestRowCount) && (aRowCount != size))
{
bestRowCount = aRowCount;
bestRow = r;
}
}
for (int c = 1; c <= size; c++)
{
if (attack[bestRow][c] == 0) // not under attack
{
cols[bestRow] = c; // assign another queen
if (queensLeft(size) == 1) // returns true if there are rows that still lack a queen
{
updateAttack(bestRow, c, +1, size);
findNextQueen(size);
cols[bestRow] = 0;
updateAttack(bestRow, c, -1, size);
}
else
{
print1solution(size);
if (solutionCount >= 3)
{
cout << solutionCount << " solutions found. see NQueen.out.\n";
system("pause");
exit(0);
}
}
}
}
return;
}
The very similar problem was introduced in LeetCode:
https://leetcode.com/problems/n-queens-ii
You can go to discussions and find explanation with code solutions.
You will need to modify code to return possible results when you reach your limit.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
When I run the executable containing a function with the following code from the command line result[1] is only printed twice before the program crashes (" *.exe has stopped working ") even though blocklength is set to 25.
When I run the exact same executable with a double click the program crashes without printing anything. (but it runs until right before the for loop)
result is an array of type double and length blocklength, it is passed to the function as an argument.
for (int i = 0; i < blocklength; i++) {
cout << result[1] << endl;
}
When I used the GNU Project Debugger (GDB) to go through the program step by step it printed out result[1] 25 times and did not crash.
Obviously the original for loop did more than just print the same value over and over, but I narrowed the problem down to this and am now totally stuck and confused.
I would really appreciate any help or inputs.
Here's the full code, result is defined in the main function as double* result = new double[blocklength] and immediately passed to the function:
void entropy(char* input, int l_input, double* result, int blocklength, char order)
{
int l_counter = pow(order, blocklength);
int* counter = new int[l_counter];
double prob = 0;
int max_counter = 1;
int* temp = new int[l_input];
for (int i = 0; i < l_input; i++) {
temp[i] = 0;
}
for (int s = 1; s <= blocklength; s++)
{
max_counter *= order;
// reset counter
for (int i = 0; i < max_counter; i++) {
counter[i] = 0;
}
// init result
result[s] = 0;
for (int b = 0; b < l_input + 1 - s; b++) {
temp[b] = order * temp[b] + input[b - 1 + s];
counter[temp[b]]++;
}
for (int b = 0; b < max_counter; b++) {
prob = counter[b] / (double)(l_input - s + 1);
if (prob != 0)
{
result[s - 1] = result[s - 1] + fabs(prob * log(prob));
}
}
std::cout << "Block " << s << " okay" << std::endl;
}
cout << "sum done" << endl;
for (int i = 0; i < blocklength; i++)
{
cout << result[1] << endl;
}
std::cout << "Entroyp done!" << std::endl;
}
There are 2 things that seem wrong with your code.
result[s] is not read/written after it's initialised.
result[s] = 0;
Instead result[s-1] is accessed.
result[s - 1] = result[s - 1] + fabs(prob * log(prob));
This means that result[0] will never be set to 0. This also means that result[blocklength] = 0 will be assigned but never used.
If you have a line like int* result = new int[blocklength]; in your code, then you access a value that isn't in your array at all. A valid index is between 0 and arrayLenght-1.
Or more general:
If your input is wrong your programm blows up. You have to ensure that no value beyond an arrays capacity is accessed, this should be done in the line/loop in which it is accessed, not somewhere else.
In this case you have to ensure that results capacity is atleast blocklength+1.
I have an assignment where I need to calculate the probability that two people share the same birthday for a given room size (in my case 50) over many trials (5000). I have to assign the birthdays randomly to the number of people in the room. The difference is I need to use a Boolean function to check the if the Birthdays are the same. I cannot figure why my outputs are off, but I believe it has something to do with two of my loops.
>
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
bool SameBirthday(int birthdays[], int numpeople);
const int MAX_PEOPLE = 50;
const double NUM_TRIALS = 5000.0;
const int DAYS_IN_YEAR = 365;
int main(void)
{
int numMatches = 0;
int people = 2;
int trial = 0;
int numpeople = 0;
int i = 0;
int birthdays[MAX_PEOPLE];
bool Match;
double Probability = 0;
srand(time(0));
for (people = 2; people <= MAX_PEOPLE; people++)
{
numMatches = 0;
for (trial = 0; trial < NUM_TRIALS; trial++)
{
for (i = 0; i < people; i++)
{
birthdays[i] = (rand() % 365 + 1);
numpeople = i;
}
if ((SameBirthday(birthdays, numpeople) == true))
{
numMatches++;
}
}
Probability = (numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about " << Probability << endl;
}
}
bool SameBirthday(int birthdays[], int numpeople)
{
bool match = false;
int numberofmatches = 0;
//Use this function to attempt to search the giving array birthdays and count up number of times
//at least two people have matching birthdays for any given 1 trial
for (int SpaceOne = 0; SpaceOne < numpeople; SpaceOne++)
{
for (int SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
{
if (birthdays[SpaceTwo] == birthdays[SpaceOne])
{
return true;
}
}
}
return false;
}
I know that the code has errors in certain spots that was because I started trying different things, but any help would be appreciated.
EDIT- My only issue now is that for my output I have a zero for the probability of 2 people in the room have a birthday, which is not right. It seems like my outputs are like a person off, the probability of 2 people is shown as the probability for three people and so on.
EDIT(8-31-2015): I also forgot to mention that my Professor stated that my SameBirthday function needed the parameters: birthday[], and numpeople so I cannot use MAX_PEOPLE as a parameter. My professor also suggested using a triple nested for loop within the main body of the function. I believe what is making my output off by one for each person relates to the triple nested for loop, but I am unsure what would cause the issue.
Just do it like this:
bool SameBirthday(int birthdays[], int numPeople)
{
for(int x=0; x<numPeople; x++){
for(int y=0; y<numPeople; y++){
if(birthdays[x] == birthdays[y])
return true;
}
}
return false;
}
Your logic in your nested loop is wrong..
for (SpaceOne = 0; SpaceOne < numpeople - 1; SpaceOne++)
for (SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
Your inner loop is skipping n number of checks where n equals SpaceOne.
By the way, this is not C programming. You can declare variable within a for-loop.
I see two problems with the actual functionality. First, SameBirthday needs to return a value (false) when there is no birthday match. You can do that at the end of the function, after all the loops are done.
Second, you need to increment numMatches when you find a match.
To clarify issues from other parts of your coding. I think this is what your school wants.
int main(){
//All your variables
for(int x=0; x<NUM_TRIALS; x++){
for(int y=0; y< MAX_PEOPLE; y++){
birthdays[y] = (rand() % 365 + 1);
}
if(SameBirthday(birthdays, MAX_PEOPLE) == true)
numMatches ++;
}
Probability = ((double)numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about "
<< Probability << endl;
}
NUM_TRIALS to generate 5000 datasets. Hence, you generate birthday for 50 students 5000 times. For each trial within a class of 50, you check whether there are 2 person with same birthday. If there is, numMatches + 1.
After 5000 trials, you get the probability.
Your other problem is that numpeople will always be the number of people minus 1. You don't actually need that variable at all. Your "people" variable is the correct number of people.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So, there are ways to do this, and/or optimize this. Stupid that I am, I immediately wants to implement a recursive function, which later caused a segmentation fault, and then I tried to adopt dynamic programming, and it seemed to work, but somehow I got Wrong answer.
Problem Here
So here's my code, and I think it's pretty self-explanatory.
#include <iostream>
using namespace std;
int cycleLength(long long int);
int cycleLengthResult[1000000];
int main(int argc, char *argv[])
{
int i = 0, j = 0, cur = 0, max = 0;
while ( cin >> i >> j )
{
if ( i > j ) //swap to ensure i <= j
{
int s = i;
i = j;
j = s;
}
for ( int k = i ; k <= j ; ++ k )
{
cur = cycleLength(k);
if (cur > max) max = cur;
}
cout << i << " " << j << " " << max << endl;
max = 0;
}
}
int cycleLength(long long int arg)
{
if ( arg > 1000000 ) //if out of array bound, then don't memorize, just calculate
{
if (arg % 2 == 0)
{
return 1 + cycleLength(arg/2);
}
else
{
return 1 + cycleLength(arg*3+1);
}
}
if (!cycleLengthResult[arg-1]) //if result for arg doesn't exist then....
{
int valueForArg = 0;
if (arg == 1)
{
valueForArg = 1;
}
else if (arg % 2 == 0)
{
valueForArg = 1 + cycleLength(arg/2);
}
else
{
valueForArg = 1 + cycleLength(arg*3+1);
}
cycleLengthResult[arg-1] = valueForArg;
}
return cycleLengthResult[arg-1];
}
I passed all the sample inputs, and also (1, 1000000) for speed test. But it seemed that it's not the problem.
I want to fix my code, and not change the methodology used, of course, I can just not use recursive, and use a loop instead in main, which wouldn't overflow. But it's fun.
Read the statement carefully:
The integers i and j must appear in the output in the same order in which they appeared in the input
So save them after reading and print the saved values.