Related
I have created a C Program to simulate the Non-Preemptive Shortest Job First Algorithm but it has bugs with certain inputs. The shortest job first algorithm program takes in inputs for the arrival and burst times of the required number of processes and arranges the processes in 2 phases. The first phase involves arranging the program by arrival times and the 2nd phase arranges them by burst times given that their arrival times are lower than the time for the previous process to complete. This is all then compiled in the end and shown.
#include <stdio.h>
// n - total processes
// p - process no. array
// bt - burst time array
// at - arrival time array
// wt - the time taken for the process to start from it's arrival time array
// tat - time spent by process in cpu array
int i, n, j, m, min, sum = 0, x = 1, btTally = 0, p[20], bt[20], at[20], wt[20], tat[20], ta = 0;
float tatTally = 0, wtTally = 0;
//function grabs arrival and burst times of each process and stores it in its respective array
void getInput(){
printf("\nEnter the total number of processes: ");
scanf("%d", & n);
// For Loop for user to input info about the processes
for (i = 0; i < n; i++) {
p[i] = i + 1;
printf("\nEnter the arrival time of process %d: ", p[i]);
scanf(" %d", & at[i]);
printf("\nEnter the burst time of process %d: ", p[i]);
scanf(" %d", & bt[i]);
}
}
//Function arranges processes according to their arrival times
void arrangePhase1(){
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (at[j] > at[i]) {
m = p[j];
p[j] = p[i];
p[i] = m;
m = at[j];
at[j] = at[i];
at[i] = m;
m = bt[j];
bt[j] = bt[i];
bt[i] = m;
}
}
}
}
//Function arranges the processes according to Burst time
void arrangePhase2(){
for (i = 0; i < n; i++) {
btTally = btTally + bt[i];
min = bt[x];
for (j = x; j < n; j++) {
if (bt[j] < min && btTally >= at[j]) {
m = p[x];
p[x] = p[j];
p[j] = m;
m = at[x];
at[x] = at[j];
at[j] = m;
m = bt[x];
bt[x] = bt[j];
bt[j] = m;
}
}
x++;
}
}
//Function calculates the tallies of turnaround time and waiting time
void calcTallies(){
for (i = 0; i < n; i++) {
ta = ta + bt[i];
tat[i] = ta - at[i];
tatTally = tatTally + tat[i];
}
wt[0] = 0;
for (i = 1; i < n; i++) {
sum = sum + bt[i - 1];
wt[i] = sum - at[i];
wtTally = wtTally + wt[i];
}
}
//Function displays all of the information about the algorithm running
void showFinal(){
printf("\nProcess\t Arrival Time\t Burst Time\t Waiting Time\t Turnaround Time");
for (i = 0; i < n; i++) {
printf("\n p%d\t %d\t\t %d\t\t %d\t\t %d", p[i], at[i], bt[i], wt[i], tat[i]);
}
printf("\nAverage Waiting Time: %.2f", (wtTally / n));
printf("\nAverage Turn Around Time: %.2f", (tatTally / n));
}
int main() {
getInput();
arrangePhase1();
arrangePhase2();
arrangePhase2();
calcTallies();
showFinal();
return 0;
}
These are the expected results:
These are the results I get with my programme:
Any help would really be appreciated. Thanks!
I ... rearrange your program a bit ...
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int p, at, bt, wt, tat;
} Job;
#define maxN (20)
Job jobs[maxN ];
int n, btTally = 0, sum = 0, ta = 0;
float tatTally = 0, wtTally = 0;
#define TestSize (5)
Job Test[TestSize] = {
{ 1, 2, 1, 0, 0 },
{ 2, 1, 5, 0, 0 },
{ 3, 4, 1, 0, 0 },
{ 4, 0, 6, 0, 0 },
{ 5, 2, 3, 0, 0 }
};
void getInput(){
int i;
printf("\nEnter the total number of processes: ");
scanf("%d", & n);
if (n == 0) {
for (i = 0; i < TestSize; ++i)
jobs[i] = Test[i];
n = TestSize;
return;
}
// For Loop for user to input info about the processes
for (i = 0; i < n; i++) {
jobs[i].p = i + 1;
printf("\nEnter the arrival time of process %d: ", jobs[i].p);
scanf(" %d", & jobs[i].at);
printf("\nEnter the burst time of process %d: ", jobs[i].p);
scanf(" %d", & jobs[i].bt);
}
}
int compareAT (const void * a, const void * b) {
Job *jobA = (Job *)a;
Job *jobB = (Job *)b;
return ( jobA->at - jobB->at );
}
void arrangePhase1(){
qsort (jobs, n, sizeof(Job), compareAT);
}
void Swap(int i, int j) {
Job m = jobs[i];
jobs[i] = jobs[j];
jobs[j] = m;
}
void calcTallies(){
int i;
for (i = 0; i < n; i++) {
ta = ta + jobs[i].bt;
jobs[i].tat = ta - jobs[i].at;
tatTally = tatTally + jobs[i].tat;
}
jobs[0].wt = 0;
for (i = 1; i < n; i++) {
sum = sum + jobs[i - 1].bt;
jobs[i].wt = sum - jobs[i].at;
wtTally = wtTally + jobs[i].wt;
}
}
void showFinal(){
int i;
printf("\nProcess\t Arrival Time\t Burst Time\t Waiting Time\t Turnaround Time");
for (i = 0; i < n; i++) {
printf("\n p%d\t %d\t\t %d\t\t %d\t\t %d", jobs[i].p, jobs[i].at, jobs[i].bt, jobs[i].wt, jobs[i].tat);
}
printf("\nAverage Waiting Time: %.2f", (wtTally / n));
printf("\nAverage Turn Around Time: %.2f", (tatTally / n));
}
void arrangePhase2() {
int i, j, min, x = 1;
for (i = 0; i < n; i++) {
btTally = btTally + jobs[i].bt;
min = jobs[x].bt;
for (j = x; j < n; j++) {
if (jobs[j].bt < min && btTally >= jobs[j].at) {
Swap(x, j);
min = jobs[x].bt;
showFinal();
}
}
x++;
}
}
int main() {
getInput();
arrangePhase1();
showFinal();
arrangePhase2();
// arrangePhase2();
calcTallies();
showFinal();
return 0;
}
And left some test and prints in it.
The main problem is that the min is not updated. Try to add the update to your original program and see if it works. Next is to move the int i,j; to the functions, does it work now? (it wont work without this if you just add the showFinal(); test to your code).
Now the code I made is not the one true truth, it is just an example from someone who hasn't programmed C in decades.
Short code review.
Using globals are bad in C, you easily gets a problem with your loops if you use globals for loop control, here i,j is reused a lot.
You could use structs more, at least for the 3 main values, makes some of the sorting a bit easier. In either case having a Swap function makes the code easier to check and understand.
void SwapInt(int *i, int *j) {
int m = *i;
*i = *j;
*j = m;
}
SwapInt(&at[i], &at[j]); // example of calling swapping
The 2nd call to arrangePhase2(); doesn't do anything.
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.
I've created this 2D 21x21 array that has all it's values set to -1. I wrote it to print the address and value and somehow it only starts at [6][19] why?
What i want to do is to replace some of the -1 values with random numbers from 0 to 100 in the same array. I know i need to seed it with srand but i'm having problems connecting the functions since i'm a total beginner in C.
EDIT 1:
Now i can print the whole array and fill it with random numbers. For the -1 values i just assigned directly which for this case its fine.
What i'm trying now is finding the average of all the values and the maximum number, so what i have is:
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int a[21][21], i , j;
for (i = 0; i < 21; i++)
{
for ( j = 0; j < 21; j++)
{
a[i][j] = GetRand(0, 100);
a[7][15] = -1;
a[10][6] = -1;
a[13][5] = -1;
a[15][17] = -1;
a[17][17] = -1;
a[19][6] = -1;
printf("%3d" , a[i][j]);
}
printf("\n");
}
return 0;
}
// random seed
int GetRand(int min, int max);
int get() {
int i, r;
for (i = 0; i < 21; i++)
{
r = GetRand(0, 100);
printf("Your number is %d \n", r);
}
return(0);
}
int GetRand(int min, int max)
{
static int Init = 0;
int rc;
if (Init == 0)
{
srand(time(NULL));
Init = 1;
}
rc = (rand() % (max - min +1) +min);
return (rc);
}
// average
int avg()
float sum=0.0;
for(i = 0; i <= 21; i = i + 1) {
for(j = 0; j <= 21; j = j + 1){
sum = sum + a[21][21];
}
printf("The the average number is %.2f\n", sum/21);
}
//find maximum of all values
int *pv = &a[0][0];
max = min = 0;
for (i = 1; i < i*j; ++i){
if (pv[i] > pv[max])
max =i;
if (pv[i] < pv[min])
min = i;
}
printf("The max value is %d in row %d, col %d\n", pv[max], max/j, max%j);
return 0;
}
For the average function the compiler tells me that expected a declaration before i, which is "float sum=0.0;" but i haven't been able to fix that yet.
For the finding the max function i'm not sure yet what i'm doing there, i just have a vague idea of how it's done...am i going in the right direction?
Thanks!
It's very simple: Just assign the result of your GetRand function to the matrix entry.
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;
}