I have a problem when I want to check my execution time with time.h in C. Namely; I added a timer for calculation of execution time when a search is started. However, the timer is starting when I select a number of variables.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int selection = 0;
printf(" 1. Calculate Execution Time Depends on Variables. \n 2. Calculate Variable Numbers Depends on Time Execution.\n What You want to do ? \n Selection : ");
scanf_s("%d", &selection);
if (selection==1)
{
int numberselection = 0;
int number_Elements = 0;
printf(" Please Select the Number of Elements. \n 1. 500.000 2. 1.000.000 3. 2.000.000 4. 3.000.000 5. 100.000.000 \n Selection : ");
scanf_s("%d", &numberselection);
if (numberselection==1)
{
number_Elements = 500000;
}
if (numberselection == 2)
{
number_Elements = 1000000;
}
if (numberselection == 3)
{
number_Elements = 2000000;
}
if (numberselection == 4)
{
number_Elements = 3000000;
}
if (numberselection == 5)
{
number_Elements = 100000000;
}
int i = 0;
int *NumberList = malloc(number_Elements * sizeof(int));
NumberList[number_Elements];
srand((unsigned)time(NULL));
for (i = 0; i < number_Elements; i++)
{
double random = rand() % 99999 + 99999999;
NumberList[i] = random;
}
double number_Search;
printf("\n Please Enter Number To Search : ");
scanf_s("%d", &number_Search);
Algorithm(number_Elements, NumberList, number_Search);
}
return 0;
}
int Algorithm(int G_Number_Elements , int G_NumberList[] , int G_Number_Search)
{
int k = 0;
double time_taken = 0;
clock_t t = 0;
for ( k = 0; k < G_Number_Elements; k++) // NUMBER TO TIME
{
if (G_NumberList[k] == G_Number_Search)
{
break;
}
else
{
printf("\n Not Found...");
break;
}
}
t = clock() - t;
time_taken = ((double)t) / CLOCKS_PER_SEC;
printf("\n Exacution Time Depends %d Variables = %f ms.\n", G_Number_Elements, time_taken);
return 0;
}
The time I wait for the console is added when I get the timer value. I have a two scenario;
Pictures of Scenarios
My question is that, How can I eliminate the waiting time from the timer?
I solved problem by the help of #Korrat !
Last state of codes :
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int selection = 0;
printf(" 1. Calculate Execution Time Depends on Variables. \n 2. Calculate Variable Numbers Depends on Time Execution.\n \n What You Want to Do ? \n Selection : ");
scanf_s("%d", &selection);
if (selection == 1)
{
int numberselection = 0;
int number_Elements = 0;
printf(" Please Select the Number of Elements. \n 1. 500.000 2. 1.000.000 3. 2.000.000 4. 3.000.000 5. 100.000.000 \n Selection : ");
scanf_s("%d", &numberselection);
if (numberselection == 1)
{
number_Elements = 500000;
}
if (numberselection == 2)
{
number_Elements = 1000000;
}
if (numberselection == 3)
{
number_Elements = 2000000;
}
if (numberselection == 4)
{
number_Elements = 3000000;
}
if (numberselection == 5)
{
number_Elements = 100000000;
}
int i = 0;
int *NumberList = malloc(number_Elements * sizeof(int));
NumberList[number_Elements];
srand((unsigned)time(NULL));
for (i = 0; i < number_Elements; i++)
{
double random = rand() % 99999 + 99999999;
NumberList[i] = random;
}
double number_Search;
printf("\n Please Enter Number To Search : ");
scanf_s("%d", &number_Search);
int k = 0;
clock_t begin = clock();
for (k = 0; k <= number_Elements; k++) // NUMBER TO TIME
{
if (NumberList[k] == number_Search)
{
break;
}
if (k == number_Elements)
{
printf("Your Number Not Found in List ! \n");
}
}
clock_t end = clock();
float time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("\n Exacution Time Depends %d Variables = %f Second !. \n", number_Elements, time_spent);
}
return 0;
}
The problem is that clock() counts all clock ticks your program uses.
You probably want to initialize t to the current value of clock() like this
clock_t t = clock();
That way you take the amount of time spent on selecting your input out of the time calculation.
Additinal information taken from the C reference on clock()
To calculate the actual processing time of a program, the value returned by clock shall be compared to a value returned by a previous call to the same function.
Related
This is the given condition and I have problem with setting time interval
Find prime numbers from 2 in 5 minutes:
include <time.h>
end= start = (unsigned)time(NULL);
while((end-start)<300)
find primes
print the prime number and how many primes are there(frequency)
end = (unsigned)time(NULL);
print total execution time
And this is the code I did.
#include <stdio.h>
#include <time.h>
int main()
{
time_t end, start;
end = start = (unsigned)time(NULL);
int i, j;
int freq = 0;
int count = 0;
while ((end-start) < 300) {
for (i = 2;; i++) {
for (j = 2; j < i; j++) {
if (i % j == 0) {
count = 1;
break;
}
}
if (!count) {
++freq;
}
count = 0;
}
return i, freq;
printf("Prime number: %d, frequency: %d\n", i, freq);
}
end = (unsigned)time(NULL);
printf("total time : %d seconds\n", end);
return 0;
}
I checked the finding prime part and the frequency part was fine when I put this way`
}
count = 0;
printf("Prime number: %d, frequency: %d\n", i, freq);
}
return i, freq;`
but there's no result even after the 5 minutes
Your while cycle ends when according to the value of end and start 5 minutes passed. They are initialized with the same value.
end is never updated inside the loop, so this will be an infinite cycle. You update end after the loop, but that is too late. You need to update it at each step, like:
while ((end-start) < 300) {
for (i = 2;(end-start) < 300; i++) {
for (j = 2; j < i; j++) {
if (i % j == 0) {
count = 1;
break;
}
}
if (!count) {
++freq;
}
count = 0;
end = (unsigned)time(NULL); printf("Prime number: %d, frequency: %d\n", i, freq);
}
//Don't return at this point
//return i, freq;
}
I am having trouble printing out the number of items entered and the average of this program and I am supposed to use a while loop can you help me figure out what I am doing wrong.
#include <stdio.h>
int main(void) {
double n;
int counter = 0;
double sum = 0.0, average;
scanf("%lf", &n);
while (1 != scanf("%lf", &n)) {
counter++;
scanf("%lf", &n);
sum = sum + n;
printf("%d", counter);
average = sum / counter;
printf("%lf", average);
}
return 0;
}
This is what it's supposed to look like
Input: 2.2 2.4 1.5 1.1 3.3 5.5 Q
Output: 6 2.666667
You should read the values in a loop, testing if scanf() returns 1 for successful conversion, update the sum and counter inside the body of the while loop and output the average and count after the end of the loop.
Here is a modified version:
#include <stdio.h>
int main(void) {
int counter = 0;
double n, sum = 0.0;
while (scanf("%lf", &n) == 1) {
counter++;
sum = sum + n;
}
if (counter == 0) {
printf("no values\n");
} else {
printf("%d %f\n", counter, sum / counter);
}
return 0;
}
There is too much redundancy in your code:
double n;
int counter = 0;
double sum = 0.0, average;
// you do not need the following initial read
// (see reconstructed while condition)
scanf("%lf", &n);
// replace the following line with "while (1)"
while (1 != scanf("%lf", &n)) {
// sth like the following if block is to be inserted to check end of input
if (scanf("%lf", &n) == 0) {
break;
}
counter++; // ok
// you do not need the following line
// if block takes care of the input
scanf("%lf", &n);
sum = sum + n; // ok
// better pull the remaining lines out of the while loop
printf("%d\n", counter); // better to insert '\n' here
average = sum / counter;
printf("%lf\n", average); // and here '\n'
}
return 0;
And btw, for the code above, your input layout had to be :
2.2
2.4
1.5
1.1
3.3
5.5
Q
A working example might be, like;
int main(void) {
double n;
int counter = 0;
double sum = 0.0, average;
while (1) {
if (scanf("%lf", &n) == 0) {
break;
}
counter++;
sum = sum + n;
}
printf("%d\n", counter);
average = sum / counter;
printf("%lf\n", average);
return 0;
}
The problem is I can't get the proper GPA. I am suspecting the divisions and type conversions. Below is the exact question I'm trying to do but I would like to learn what am I missing with my code.
https://imgur.com/a/HFrIO - They don't mention about credits so I simply ask it from the user in the program.
Edit: As seen from the question above, it should calculate the GPA but when I try with marks 50, 60, 70 respectively and 3 credits for each course, I get no sense outputs like 0.
(Original assignment wants 30 students and 5 courses but I defined them and changed them to 2 courses 1 student in order to test it in runtime.)
#include <stdio.h>
#define NUMBER_OF_COURSES 2 // Homework asks for 5, change at the end
#define NUMBER_OF_STUDENTS 1 // Homework asks for 30, change at the end
void calculateCourse(int *letterGradePoints, int *credit); // Func. prototype
float calculateStudentGpa(); // Func. prototype
int main()
{
// Store gpa s of students in an array
float studentGpas[NUMBER_OF_STUDENTS];
int i;
for(i = 0; i < NUMBER_OF_STUDENTS; ++i)
{
/*DEBUG*/printf("----\nPROGRAM IS IN MAIN FOR LOOP\n----\n");
studentGpas[i] = calculateStudentGpa();
}
// Print all gpas
for(i = 0; i < NUMBER_OF_STUDENTS; ++i)
{
printf("\nGPA of student %d is : %d ", i + 1, studentGpas[i]);
}
// Find min gpa
int min = studentGpas[0];
for(i = 1; i < NUMBER_OF_STUDENTS; ++i)
if(min > studentGpas[i])
min = studentGpas[i];
// Find max gpa
int max = studentGpas[0];
for(i = 1; i < NUMBER_OF_STUDENTS; ++i)
if(max < studentGpas[i])
max = studentGpas[i];
// Print min and max
printf("Min gpa is : %d Max gpa is : %d", min, max);
return 0;
}
float calculateStudentGpa()
{
/*DEBUG*/printf("\nPROGRAM IS IN calculateStudentGpa FUNCTION");
/* Dealing with a single students gpa */
int credit[NUMBER_OF_COURSES];
int letterGradePoints[NUMBER_OF_COURSES];
int i; int debug = 0;
for(i = 0; i < NUMBER_OF_COURSES; ++i)
{
/*DEBUG*/ if(debug == 0) { /*DEBUG*/printf("\nPROGRAM IS IN calculateStudentGpa FUNCTION for LOOP\n"); debug++; } // Print this one once
calculateCourse(&letterGradePoints[i], &credit[i]);
/*DEBUG*/printf("\nPROGRAM IS IN calculateStudentGpa FUNCTION for LOOP\n");
/*DEBUG*/printf("\n[DEBUG] i in calculateStudentGpa : %d", i);
/*DEBUG*/printf("\n[DEBUG] letterGradePoints[i] in calculateStudentGpa : %d", letterGradePoints[i]);
/*DEBUG*/printf("\n[DEBUG] credit[i] in calculateStudentGpa : %d\n", credit[i]);
}
/*DEBUG*/printf("\nPROGRAM HAS ..PASSED.. calculateStudentGpa FOR LOOP");
float gpa; float up = 0; float down = 0;
/* Either we need to have
* (i = 0; i < NUMBER_OF_COURSES; ++i) AND indexes of arrays as i
* or
* (i = 1; i <= NUMBER_OF_COURSES; ++i) AND indexes of arrays as i - 1
* below in 2 for loops!!!!
*/
for(i = 0; i < NUMBER_OF_COURSES; ++i)
{
up += (letterGradePoints[i] * credit[i]); // Might need (float)
}
for(i = 1; i <= NUMBER_OF_COURSES; ++i)
{
down += credit[i - 1];
}
gpa = up / down;
/* We are done with a single student, we need all 30 students */
return gpa;
}
void calculateCourse(int *letterGradePoints, int *credit)
{
/*DEBUG*/printf("\n--------------------------------------");
/*DEBUG*/printf("\nVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
/*DEBUG*/printf("\nPROGRAM IS IN calculateCourse FUNCTION\n");
/* Dealing with a single course */
int labMark, midtermMark, finalMark;
printf("\nEnter lab mark : ");
scanf("%d", &labMark);
printf("Enter midterm mark : ");
scanf("%d", &midtermMark);
printf("Enter final mark : ");
scanf("%d", &finalMark);
float average =
(
(float) (0.5 * finalMark)
+
(float) (0.4 * midtermMark)
+
(float) (0.1 * labMark)
); // Might need (float)
/*DEBUG*/printf("\n[DEBUG] average : %f", average);
// int letterGradePoints; // I decided to use pass by reference in order to return 2 values
if(average >= 0) *letterGradePoints = 0;
if(average >= 50) *letterGradePoints = 1;
if(average >= 60) *letterGradePoints = 2;
if(average >= 70) *letterGradePoints = 3;
if(average >= 80) *letterGradePoints = 4;
/*DEBUG*/printf("\n[DEBUG] letterGradePoints in calculateCourse : %d\n", *letterGradePoints);
// int credit; // I decided to use pass by reference in order to return 2 values
printf("Enter the credit for the course : ");
scanf("%d", credit);
/*DEBUG*/printf("\n[DEBUG] *credit in calculateCourse : %d\n", *credit);
/*DEBUG*/printf("/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\\n");
/*DEBUG*/printf("--------------------------------------\n");
/* We are done with a single course, we need all 5 courses for the gpa */
}
You're printing the GPA as an integer instead of as a floating point number. Change
printf("\nGPA of student %d is : %d", i + 1, studentGpas[i]);
to
printf("\nGPA of student %d is : %f", i + 1, studentGpas[i]);
Look here for a list of format specifiers used by printf.
I would like to parallelize a while loop in C with OpenMP. It is a classic while until flag = false.
This is a semi-pseudo-code of my work without openMP
//Something before
found = 0;
while (!found){
//Pull an element from an array and do some work with it
if(something) found = 1;
//Do other work and put an element in the same array
}
//Something later
It is not a problem for me if the work in the loop is done some times more, it's just overwork that doesn't affect the results. There is a simple correct way to parallelize this with OpenMP in C?
Thanks
As requested, this is the complete code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
typedef struct location {int x, y;} location;
typedef struct node {
int x, y; // Coordinates of the node on the grid
int x_prec, y_prec; // Coordinates of the predecessor
int walkable; // Whether this node can be walked through
int opened; // It indicates if the node was been estimated
int closed; // It indicates if the node was been evaluated
int inPath; // If the node is in the shortest path
int g; /* The past-cost function, which is the known distance from the starting
* node to the current one. */
int f; /* The estimated-cost function, which is an admissible heuristic estimate
* of the distance from the starting node to the goal passing through the
* current node. */
int h; // The estimated cost of the path between the current node and the goal
} node;
typedef struct list {
location loc;
int isValid;
} list;
location start,end;
node **grid;
int cols, rows;
double time1, time2, time3, time4, time5;
double time_aStar_s, time_aStar_e;
double time_getNeighbor_s, time_getNeighbor_e;
double time_while_s, time_while_e;
double time_for_s, time_for_e;
double time_for = 0;
double time_pull_s, time_pull_e;
double time_pull = 0;
int count_getNeighbor = 0;
int count_current = 0;
void setGrid(char [6]);
int checkLocation(location);
void aStar(int);
int isListEmpty(list *);
void constructPath(location);
void getNeighbor(location, location *);
int heuristic(location, location);
void printStatistics();
void saveStatistics(char *);
int main (int argc, char *argv[]){
char input_map[20];
int input_algo = -1;
char input_stat[20];
printf("Which map you prefer?\n");
scanf("%s", input_map);
setGrid(input_map);
printf("Enter a valid start point.\n");
scanf("%i", &start.x);
scanf("%i", &start.y);
printf("Enter a valid end point.\n");
scanf("%i", &end.x);
scanf("%i", &end.y);
if (checkLocation(start) || checkLocation(end)) printf("Invalid start and/or end points.\n");
printf("Dijkstra or A*?(press <0> or <1> respectively)\n");
scanf("%i", &input_algo);
// Save when aStar is called
time_aStar_s = omp_get_wtime();
if(input_algo == 0) aStar(0); // 0 for Dijkstra
else if (input_algo == 1) aStar(1); // 1 for A*
// Save when aStar finishes
time_aStar_e = omp_get_wtime();
printf("End of the program. \n");
printStatistics();
printf("Would you like to save the statistics?(Enter <y> or <n> respectively)\n");
scanf("%s", input_stat);
if(input_stat[0] == 'y'){
printf("Enter file name.\n");
scanf("%s", input_stat);
saveStatistics(input_stat);
}
return(0);
}
void setGrid(char mapName[6]) {
char temp[1024];
char fileName[20];
int i,j;
FILE *file;
// Try to open the file
strcpy(fileName, "src/maps/");
strcat(fileName, mapName);
if((file = fopen(fileName, "r")) == NULL){
printf("ERROR: No such file.\n");
exit(1);
}
// Save dimensions of the map
rows = 0;
while(42){
if(fscanf(file, "%s", temp) == EOF){
printf("EOF\n");
printf("columns: \t%i \nrows: \t\t%i\n", cols, rows);
break;
}
printf("%s\n", temp);
cols = strlen(temp);
rows++;
}
// Reset the file position indicator
rewind(file);
// Set dimensions of grid matrix
grid = (node **)malloc(rows * sizeof(node*));
for(i = 0; i < rows; i++) grid[i] = (node *)malloc(cols * sizeof(node));
i=0;
while(42){
if(fscanf(file, "%s", temp) == EOF) break;
for (j = 0; j < cols; j++) {
grid[i][j].x = i;
grid[i][j].y = j;
grid[i][j].x_prec = -1;
grid[i][j].y_prec = -1;
if(temp[j] == '#') {
grid[i][j].walkable = 0;
} else if(temp[j] == '-') {
grid[i][j].walkable = 1;
}
grid[i][j].opened = 0;
grid[i][j].closed = 0;
grid[i][j].inPath = 0;
grid[i][j].g = -1;
grid[i][j].f = -1;
}
i++;
}
fclose(file);
}
void printGrid(int option) {
int i,j;
switch(option){
case 0:
// It prints grid with start point, end point and optimal path
for(i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
if(i == start.x && j == start.y) printf("S");
else if(i == end.x && j == end.y) printf("E");
else if (grid[i][j].walkable){
if (grid[i][j].inPath) printf("+");
else printf(" ");
} else printf("#");
}
printf("\n");
}
printf("\n");
break;
case 1:
// It prints evaluated cost g
for(i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
if (grid[i][j].walkable){
if(grid[i][j].closed == 1) printf("%3d ", grid[i][j].g);
else printf(" ");
} else printf("### ");
}
printf("\n");
}
printf("\n");
break;
case 2:
// It prints estimated cost g
for(i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
if (grid[i][j].walkable){
if(grid[i][j].closed == 1) printf("%3d ", grid[i][j].g);
else printf(" ");
} else printf("### ");
}
printf("\n");
}
printf("\n");
break;
default:
printf("ERROR: Bad option %i for function printGrid(). Please check the code.\n", option);
break;
}
}
int checkLocation(location l) {
if(grid[l.x][l.y].walkable) return(0);
else return (1);
}
void aStar(int opt_dijkstra) {
list openList[10000];
location current;
location neighbors[4];
int empty;
int found = 0;
int i,j; // Counters
int exit; // control variable
int f_min;
int pos;
int x,y;
int ng;
// Set g and f values of the start node to be 0
grid[start.x][start.y].g = 0;
grid[start.x][start.y].f = 0;
// Initialization of the open list
for (i = 0; i < sizeof(openList)/sizeof(openList[0]); i++) {
openList[i].isValid = 0;
}
// Push the start node into the open list
grid[start.x][start.y].opened = 1;
openList[0].loc.x = start.x;
openList[0].loc.y = start.y;
openList[0].isValid = 1;
// Save when the "while is not empty" begins
time1 = time_while_s = omp_get_wtime();
// While the open list is not empty
empty = isListEmpty(openList);
while (!empty && !found){
// Save time to pull a node
time_pull_s = omp_get_wtime();
// pull the position of the node which has the minimum f value
f_min = -1;
#pragma omp parallel for default(none) shared(openList, f_min, current, pos, grid)
for(i = 0; i < sizeof(openList)/sizeof(openList[0]); i++) {
if (openList[i].isValid == 1 && (f_min == -1 || (grid[openList[i].loc.x][openList[i].loc.y].f < f_min))){
#pragma omp critical(pullopenlist)
{
f_min = grid[openList[i].loc.x][openList[i].loc.y].f;
current.x = openList[i].loc.x;
current.y = openList[i].loc.y;
pos = i;
}
}
}
openList[pos].isValid = 0;
grid[current.x][current.y].closed = 1;
//Save time to pull a node
time_pull_e = omp_get_wtime();
time_pull += time_pull_e - time_pull_s;
// Update the count of evaluated points
count_current++;
// If the end position is reached, construct the path and return it
if (current.x == end.x && current.y == end.y){
printf("Reached the end position.\n");
constructPath(end); // To be defined
found = 1;
}
// Save when enter in getNeighbor
time_getNeighbor_s = omp_get_wtime();
// Get neighbors
getNeighbor(current, neighbors);
// Save when exit from getNeigbor
time_getNeighbor_e = omp_get_wtime();
// Get the distance between current node and the neighbor and calculate the next g score
ng = grid[current.x][current.y].g + 1;
// Save when started the "for all neighbors"
time2 = time_for_s = omp_get_wtime();
// Evaluate neighbors
/* Seems that is not convenient to parallelize the loop.
* Probably this happens because of critical section
*/
#pragma omp parallel for default(none) private(x, y, j) shared(exit, openList, neighbors, ng, grid, opt_dijkstra, end, current)
for (i = 0; i < 4; i++) {
x = neighbors[i].x;
y = neighbors[i].y;
if (x != -1 || y != -1){
// Check if the neighbor has not been inspected yet, or if it
// can be reached with smaller cost from the current node
if (!grid[x][y].opened || ng < grid[x][y].g) {
grid[x][y].g = ng;
if(opt_dijkstra == 0) grid[x][y].h = 0; // Dijkstra case with heuristic cost = 0;
else grid[x][y].h = heuristic(neighbors[i], end);
grid[x][y].f = grid[x][y].g + grid[x][y].h;
grid[x][y].x_prec = current.x;
grid[x][y].y_prec = current.y;
}
// If the neighbor is not in open list push it into it
#pragma omp critical (pushopenList)
{
if(!grid[x][y].opened) {
exit = 0;
for(j = 0; exit == 0; j++) {
if(openList[j].isValid == 0) {
openList[j].loc.x = x;
openList[j].loc.y = y;
openList[j].isValid = 1;
exit = 1;
}
}
}
grid[x][y].opened = 1;
}
}
}
// Save when finish the "for all neighbors"
time_for_e = omp_get_wtime();
time_for += time_for_e - time_for_s;
} // End while the open list is not empty until end point is found.
// Save when finish the "while is not empty"
time_while_e = omp_get_wtime();
}
int isListEmpty(list l[]){
// It should check if the list is empty. It checks if there is at least one element that is valid.
int i;
int empty = 0;
for (i = 0; i < sizeof(l)/sizeof(l[0]); i++){
if (l[i].isValid){
empty = 1;
i = sizeof(l)/sizeof(l[0]);
}
}
return (empty);
}
void constructPath(location n){
/* The function reconstructs the path starting from the given point setting .inPath
*/
int i;
location temp;
location temp_prec;
temp.x = grid[n.x][n.y].x;
temp.y = grid[n.x][n.y].y;
grid[temp.x][temp.y].inPath = 1;
for(i = 0; grid[temp.x][temp.y].x_prec != -1; i++) {
temp_prec.x = grid[temp.x][temp.y].x_prec;
temp_prec.y = grid[temp.x][temp.y].y_prec;
temp.x = temp_prec.x;
temp.y = temp_prec.y;
grid[temp.x][temp.y].inPath = 1;
}
}
void getNeighbor(location current, location neighbors[4]){
/*
* Get the neighbors of the given node.
*
* offsets
* +---+---+---+
* | | 0 | |
* +---+---+---+
* | 3 | | 1 |
* +---+---+---+
* | | 2 | |
* +---+---+---+
*/
int i;
int x = current.x;
int y = current.y;
// Update count of getNeighbor executions
count_getNeighbor++;
for (i = 0; i < 4; i++){
switch(i) {
// ↑
case 0:
if(x >= 0 && y - 1 >= 0 && x < rows && y - 1 < cols && grid[x][y - 1].walkable){
neighbors[i].x = x;
neighbors[i].y = y - 1;
} else{
neighbors[i].x = -1;
neighbors[i].y = -1;
}
break;
// →
case 1:
if(x + 1 >= 0 && y >= 0 && x + 1 < rows && y < cols && grid[x +1][y].walkable){
neighbors[i].x = x + 1;
neighbors[i].y = y;
} else{
neighbors[i].x = -1;
neighbors[i].y = -1;
}
break;
// ↓
case 2:
if(x >= 0 && y + 1 >= 0 && x < rows && y + 1 < cols && grid[x][y + 1].walkable) {
neighbors[i].x = x;
neighbors[i].y = y + 1;
} else{
neighbors[i].x = -1;
neighbors[i].y = -1;
} break;
// ←
case 3:
if(x - 1 >= 0 && y >= 0 && x - 1 < rows && y < cols && grid[x - 1][y].walkable) {
neighbors[i].x = x - 1;
neighbors[i].y = y;
} else{
neighbors[i].x = -1;
neighbors[i].y = -1;
}
break;
}
}
}
int heuristic(location from, location to){
int h;
// Manhattan distance from the two points
h = abs(from.x - to.x) + abs(from.y - to.y);
return(h);
}
void printStatistics(){
// Print some useful statistics about the parallel execution of the program
printf("\nStatistics of aStar:\n");
printf("time to execute aStar: \t\t\t\t%f \tms\n", 1000*(time_aStar_e - time_aStar_s));
printf("time at first check point: \t\t\t%f \tms\n", 1000*(time1 - time_aStar_s));
printf("time at second check point: \t\t\t%f \tms\n", 1000*(time2 - time_aStar_s));
printf("\nStatistic of \"while until is empty\":\n");
printf("number of iterations: \t\t\t\t%i\n", count_current);
printf("mean time to do an iteration: \t\t\t%f \tms\n", 1000*(time_while_e - time_while_s)/count_current);
printf("time to do all iterations: \t\t\t%f \tms\n", 1000*(time_while_e - time_while_s));
printf("\nStatistic of pull a node into openList:\n");
printf("mean time to perform a pull operation: \t\t%f \tms\n", 1000*time_pull/count_current);
printf("total time spent to perform pulls operations: \t%f \tms\n", 1000*time_pull);
printf("\nStatistic of \"for each neighbor\":\n");
printf("total number of iterations: \t\t\t%i\n", 4*count_current);
printf("mean time to do all four iterations: \t\t%f \tms\n", 1000*time_for/count_current);
printf("time to do the last four iterations: \t\t%f \tms\n", 1000*(time_for_e - time_for_s));
printf("time to do all the iterations: \t\t\t%f \tms\n", 1000*time_for);
printf("\nStatistic of getNeighbor:\n");
// time_getNeighbor is updated at each execution, so we have only the value relative to the last execution
printf("time to execute getNeighbor (last execution): \t%f \tms\n", 1000*(time_getNeighbor_e - time_getNeighbor_s));
printf("number of executions: \t\t\t\t%i\n", count_getNeighbor);
// Just an indicative time, it is NOT the time to do all executions
printf("estimated time to do all executions: \t\t%f \tms\n", 1000*count_getNeighbor*(time_getNeighbor_e - time_getNeighbor_s));
}
void saveStatistics(char *string_input){
FILE *fileOutput;
char fileOutputName[30];
strcpy(fileOutputName, "src/stats/");
strcat(fileOutputName, string_input);
if((fileOutput = fopen(fileOutputName, "w")) == NULL){
printf("ERROR: Error in opening the output file.\n");
exit(1);
}
// Print some useful statistics about the parallel execution of the program
fprintf(fileOutput, "\nStatistics of aStar:\n");
fprintf(fileOutput, "time to execute aStar: \t\t\t\t%f \tms\n", 1000*(time_aStar_e - time_aStar_s));
fprintf(fileOutput, "time at first check point: \t\t\t%f \tms\n", 1000*(time1 - time_aStar_s));
fprintf(fileOutput, "time at second check point: \t\t\t%f \tms\n", 1000*(time2 - time_aStar_s));
fprintf(fileOutput, "\nStatistic of \"while until is empty\":\n");
fprintf(fileOutput, "number of iterations: \t\t\t\t%i\n", count_current);
fprintf(fileOutput, "mean time to do an iteration: \t\t\t%f \tms\n", 1000*(time_while_e - time_while_s)/count_current);
fprintf(fileOutput, "time to do all iterations: \t\t\t%f \tms\n", 1000*(time_while_e - time_while_s));
fprintf(fileOutput, "\nStatistic of pull a node into openList:\n");
fprintf(fileOutput, "mean time to perform a pull operation: \t\t%f \tms\n", 1000*time_pull/count_current);
fprintf(fileOutput, "total time spent to perform pulls operations: \t%f \tms\n", 1000*time_pull);
fprintf(fileOutput, "\nStatistic of \"for each neighbor\":\n");
fprintf(fileOutput, "total number of iterations: \t\t\t%i\n", 4*count_current);
fprintf(fileOutput, "mean time to do all four iterations: \t\t%f \tms\n", 1000*time_for/count_current);
fprintf(fileOutput, "time to do the last four iterations: \t\t%f \tms\n", 1000*(time_for_e - time_for_s));
fprintf(fileOutput, "time to do all the iterations: \t\t\t%f \tms\n", 1000*time_for);
fprintf(fileOutput, "\nStatistic of getNeighbor:\n");
// time_getNeighbor is updated at each execution, so we have only the value relative to the last execution
fprintf(fileOutput, "time to execute getNeighbor (last execution): \t%f \tms\n", 1000*(time_getNeighbor_e - time_getNeighbor_s));
fprintf(fileOutput, "number of executions: \t\t\t\t%i\n", count_getNeighbor);
// Just an indicative time, it is NOT the time to do all executions
fprintf(fileOutput, "estimated time to do all executions: \t\t%f \tms\n", 1000*count_getNeighbor*(time_getNeighbor_e - time_getNeighbor_s));
fclose(fileOutput);
printf("Saved all the stats");
}
If you have suggestion on the other parts of code you're welcome.
You can certainly do something like this with OpenMP, but it isn't as simple as putting #pragma omp parallel around a for loop. For that structure, the compiler needs to know at the time of entering the loop how many iterations will be made, so that it can decompose the iterations across threads; and you necessarily don't have that information here when you're exiting once you've found something.
You can make something like this work - and it can be very useful if the test you need to perform is very CPU heavy (here, I have a made-up example of brute-force primality testing), so that you're breaking up the work amongst several cores, and you only care about finding a result (or that there are none). But note that you are definitely not guaranteed that doing this in parallel will return the first result.
In the below example, we have a flag found that is set (using an omp atomic capture construct) when a thread finds an item. If it was the first to set the flag, it stores the value and location. Once the threads (eventually) see the flag has been set, they all return from the while loop.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "omp.h"
/* brute force prime-testing algorithm */
int isprime(int x) {
int prime = 1;
for (int i=2; i<=floor(sqrt(1.0*x)); i++) {
if (x % i == 0) {
prime = 0;
break;
}
}
return prime;
}
int main(int argc, char **argv) {
const int MAXN=128;
int start=200;
if (argc > 1)
start = atoi(argv[1]);
int candidates[MAXN];
for (int i=0; i<MAXN; i++) {
candidates[i] = start+i;
}
int found=0;
int value=-1;
int location=-1;
#pragma omp parallel shared(found, candidates, value, location) default(none)
{
int tid=omp_get_thread_num();
int nthreads=omp_get_num_threads();
int item=tid;
while (!found && item < MAXN) {
int prime=isprime(candidates[item]);
if (prime) {
int alreadyfound=0;
#pragma omp atomic capture
{ alreadyfound = found; found++; }
if (!alreadyfound) {
location = item;
value = candidates[item];
}
}
item += nthreads;
}
}
if (!found)
printf("No primes found\n");
else
printf("Found prime: %d (%d) in location %d (%d)\n", value, isprime(value), location, candidates[location]);
return 0;
}
Running gives
$ gcc -o stopwhenfound stopwhenfound.c -std=c99 -lm -fopenmp
$ ./stopwhenfound 370262
Found prime: 370373 (1) in location 111 (370373)
I disagree with Jonathan, I think it is very easy to do in OpenMP. You just need to flush the done variable (so its value is consistent across all the caches):
//Something before
found = 0;
**#pragma omp flush(done)**
while (!found){
//Pull an element from an array and do some work with it
if(something){
found = 1;
**#pragma omp flush(done)**
}
//Do other work and put an element in the same array
}
//Something later
I'm very new to programming and I was asked to find the sum of prime numbers in a given range, using a while loop. If The input is 5, the answer should be 28 (2+3+5+7+11). I tried writing the code but it seems that the logic isn't right.
CODE
#include <stdio.h>
int main()
{
int range,test;
int sum = 2;
int n = 3;
printf("Enter the range.");
scanf("%i",range);
while (range > 0)
{
int i =2;
while(i<n)
{
test = n%i;
if (test==0)
{
goto end;
}
i++;
}
if (test != 0)
{
sum = sum + test;
range--;
}
end:
n++;
}
printf("The sum is %i",sum);
return 0;
}
It would be nice if you could point out my mistake and possibly tell me how to go about from there.
first of all, in the scanf use &range and not range
scanf("%i",&range);
Second this instruction is not correct
sum = sum + test;
it should be
sum = sum + n;
and also the
while (range > 0)
should be changed to
while (range > 1)
Because in your algorithm you have already put the first element of the range in the sum sum = 2 so the while should loop range - 1 times and not range times
That's all
OK, my C is really bad, but try something like the following code. Probably doesn't compile, but if it's a homework or something, you better figure it out yourself:
UPDATE: Made it a while loop as requested.
#include <stdio.h>
int main()
{
int range, test, counter, innerCounter, sum = 1;
int countPrimes = 1;
int [50] primesArray;
primesArray[0] = 1;
printf("Enter the range.");
scanf("%i",range);
counter = 2;
while (counter <= range) {
for (innerCounter = 1; innerCounter < countPrimes; innerCounter++) {
if (counter % primesArray[innerCounter] == 0)
continue;
primesArray[countPrimes + 1] = counter;
countPrimes ++;
sum += counter;
}
counter ++
}
printf("The sum is %i",sum);
return 0;
}
I haven't done C in a while, but I'd make a few functions to simplify your logic:
#include <stdio.h>
#include <math.h>
int is_prime(n) {
int i;
for (i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
int main() {
int range, i, sum, num_primes = 0;
printf("Enter the range: ");
scanf("%d", &range);
for (i = 2; num_primes < range; i++) {
if (is_prime(i)) {
sum += i;
num_primes++;
}
}
printf("The sum is %d", sum);
return 0;
}
Using goto and shoving all of your code into main() will make your program hard to debug.
Copy - pasted from here.
#include <stdio.h>
int main() {
int i, n, count = 0, value = 2, flag = 1, total = 0;
/* get the input value n from the user */
printf("Enter the value for n:");
scanf("%d", &n);
/* calculate the sum of first n prime nos */
while (count < n) {
for (i = 2; i <= value - 1; i++) {
if (value % i == 0) {
flag = 0;
break;
}
}
if (flag) {
total = total + value;
count++;
}
value++;
flag = 1;
}
/* print the sum of first n prime numbers */
printf("Sum of first %d prime numbers is %d\n", n, total);
return 0;
}
Output:
Enter the value for n:5
Sum of first 5 prime numbers is 28
Try the simplest approach over here. Check C program to find sum of all prime between 1 and n numbers.
CODE
#include <stdio.h>
int main()
{
int i, j, n, isPrime, sum=0;
/*
* Reads a number from user
*/
printf("Find sum of all prime between 1 to : ");
scanf("%d", &n);
/*
* Finds all prime numbers between 1 to n
*/
for(i=2; i<=n; i++)
{
/*
* Checks if the current number i is Prime or not
*/
isPrime = 1;
for(j=2; j<=i/2 ;j++)
{
if(i%j==0)
{
isPrime = 0;
break;
}
}
/*
* If i is Prime then add to sum
*/
if(isPrime==1)
{
sum += i;
}
}
printf("Sum of all prime numbers between 1 to %d = %d", n, sum);
return 0;
}