I need urgent help with this assignment- under 24 hours maximum therefore, if it cannot be done before the deadline please don’t accept the assignment.
This is an assignment for any C programming tutor/expert. All instructions are given in instructions_a2.pdf. You have to complete the methods according to the instructions given. Please let me know if it’s possible under 24 hours maximum.
Thank you :)
For this assignment, you will write a multi-process program that takes advantage of multiple CPU cores in parallel to solve the Closest Pair of Points Problem. Background The closest pair of points problem is a computational geometry problem that can be solved using a divide and conquer algorithm. As a reminder of what a divide-and-conquer algorithm is: A divide-and-conquer algorithm works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem. Source: Wikipedia A high-level explanation of the problem is explained in this handout. A more detailed explanation, which is required reading, is available in this PDF printout of Section 33.4 from "Introduction to Algorithms" by Cormen, Leiserson, Rivest, and Stein (CLRS). If you have any questions about the algorithm, to avoid clutter and to make the Piazza threads more useful for everyone, please avoid vague questions such as, "I don't understand Step X". Instead, please reference specific elements from the text in the handout or provided PDF file and ask a specific question about that text. Did We Get Transferred to CSC236? No, don't worry, this is still CSC209. Divide and conquer algorithms are well-suited for parallel computation, which makes this is a good opportunity to apply systems-level concepts to solve a real-world problem efficiently. Merge sort is a popular divide-and-conquer algorithm that you have all seen in CSC148. If you have also taken CSC236, you may have seen other examples. The Closest Pair of Points Problem Given n points on a 2D plane, find the distance between the closest pair of points. Naive (Brute-Force) Approach The naive solution can be implemented in just a few lines, by finding the distance between all pairs of points and returning the distance between the closest pair. This approach requires O(n^2) time. Recursive Divide-and-Conquer Approach The problem can be solved in O(nlogn) time using the following recursive divide and conquer approach: 1. Sort the points in ascending order by their x-coordinates. 2. Split the list of points into two equal-sized halves. This is like drawing a vertical line through the plane to divide the points into a left-hand-side and right-hand-side, each containing an equal number of points. 3. Solve the problem recursively on the left and right halves. 4. Find the distance between the closest pair of points where one point lies on the left-hand- side, and the other point lies on the right-hand-side. This can be done in linear time. 5. The final answer is the minimum among the: Distance between the closest pair of points on the left-hand side. Distance between the closest pair of points on the right-hand side. Distance between the closest pair of points where one point is on the left-hand-side and the other point is on the right-hand side. Illustration of algorithm steps Note: Our implementation in this assignment is not exactly O(nlogn), as we do not adhere strictly to all the guidelines outlined in the CLRS text. Assignment Structure First, let us go over the files provided in the starter code: Makefile, which you will notice contains a new flag, -fsanitize=signed-integer- overflow, as well as the -lm flag required for the math library. main.c contains the logic to: 1. Parse command-line arguments 2. Either generate points or read them from a file 3. Optionally save generated points to a file 4. Sort the points with qsort() 5. Call both the single-process and multi-process implementations to find the distance between the closest pair of points 6. Measure the time taken by both the single-process and multi-process implementations closest_tests.c contains a test case to test the correctness of your implementation. You may use this as a skeleton to add additional test cases. closest_helpers.h, closest_brute.h, closest_serial.h, and closest_parallel.h declare all the functions that you will implement. closest_helpers.c, closest_brute.c, closest_serial.c, and closest_parallel.c are where your implementations will go. Your implementation (i.e., closest*.c) MUST work with the original Makefile, main.c, and closest*.h files supplied in your starter code. If you do modify them for testing purposes, be sure to revert back to the original versions using git checkout COMMIT_ID FILENAME when running your final set of tests (check git log to find the commit ID of the starter code). The closest_tests.c file is supplied only for your convenience, so you may modify it as you see fit. It will not be marked. Program Output Your implementation should not print ANYTHING to stdout. The only data printed to stdout should be from the printf() calls supplied in main.c. Any other information that you print for debugging purposes should be printed to stderr if your program is run in verbose mode (explained below). If the program is not in verbose mode, no output should be printed except for error messages before the program exits. Global Variables Notice that the header files declare two global variables: 1. curr_depth will help you keep track of your number of processes. 2. verbose is a boolean value, toggled using the -v command-line argument. In verbose mode, any of your functions may print any additional debugging information of your choosing to stderr. We will not be testing your program in verbose mode. Naive (Brute-Force) Implementation First, you must implement the naive algorithm, which requires that you implement: 1. double dist(struct Point, struct Point); (in closest_helpers.c) 2. double brute_force(struct Point P[], size_t n); (in closest_brute.c) Implementing the naive approach is a requirement for implementing the recursive approach described below. Specifically, the naive approach is used for solving the simplest instance (base case) of the problem, where only 2 or 3 points are given as input. You may test your naive implementation using closest_tests.c. Single-Process Implementation Next, you must implement the single-process divide-and-conquer solution. Your single-process implementation requires that you implement: 1. The naive solution, as described above. 2. int compare_x(const void*, const void*); (in closest_helpers.c) 3. int compare_y(const void*, const void*); (in closest_helpers.c) 4. double combine_lr(struct Point P[], size_t n, struct Point mid_point, double d); (in closest_serial.c) 5. double _closest_serial(struct Point P[], size_t n); (in closest_serial.c) 6. double closest_serial(struct Point P[], size_t n); (in closest_serial.c) All functions above will be re-used when completing the next part of your assignment, which is to write your multi-process solution. Multi-Process Implementation Your multi-process implementation requires that you implement: 1. The naive solution and single-process recursive solution, as described above. 2. double _closest_parallel(struct Point P[], size_t n, int pdmax, int *pcount); (in closest_parallel.c) 3. double closest_parallel(struct Point P[], size_t n, int pdmax, int *pcount); (in closest_parallel.c) Implementation Requirements Naive Solution There are no special requirements for the naive solution, aside from the correct implementation of the algorithm. Single-Process Recursive Solution Implement the algorithm as described earlier in this handout, under the "Recursive Divide-and- Conquer Approach" section. We will check for compliance with ALL the following requirements. No credit will be given to submissions that violate these requirements (e.g., not using qsort(), or implementing the naive solution instead of the divide-and-conquer solution). The closest_serial() function should first sort the points, using qsort(), in ascending order by their x-coordinates. It should then call _closest_serial(). The _closest_serial() function should: 1. Find the middle point, p_mid, by x-coordinate. This is easy since the points should already be sorted by x-coordinate. 2. Split the array of points into two equal-sized halves. The left half should consist of elements 0 to the floor of n/2 (i.e., if n is odd, the right half will consist of one more point). 3. Solve the problem on the left and right halves: If one or both of the halves consist of 3 points or fewer, call brute_force() to find the solution. This is the "stop condition" of your recursive function. Otherwise, make two recursive calls to _closest_serial() (for the left half and the right half). 4. Let dl be the distance between the closest pair of points on the left-hand side, and dr be the distance between the closest pair of points on the right-hand side. Let d be the minimum among dl and dr. 5. Find the distance between the closest pair of points where one point lies on the left-hand- side and the other point lies on the right-hand-side. Do this by calling combine_lr(), passing in the array of n points, along with d and p_mid. This function implements the following linear-time solution: 1. Build an array consisting of points where for each point p_i, abs(p_i.x - p_mid.x) < d.="" 2.="" sort="" the="" points="" with="" qsort()="" by="" their="" y-coordinate.="" there="" is="" a="" more="" efficient="" solution,="" explained="" towards="" the="" end="" of="" the="" pdf="" handout,="" where="" this="" step="" can="" be="" avoided.="" but="" we="" are="" skipping="" that="" optimization="" for="" simplicity.="" 3.="" for="" each="" point="" in="" the="" array="" p_i,="" find="" the="" distance="" between="" it="" and="" each="" subsequent="" point="" p_j="" where="" p_j.y="" -="" p_i.y="">< d.="" although="" this="" is="" implemented="" with="" a="" nested="" loop,="" and="" thus="" appears="" to="" be="" an="" o(n^2)="" solution="" at="" first="" glance,="" it="" is="" actually="" a="" linear-time="" solution,="" since="" it="" is="" proven="" that,="" for="" each="" point,="" the="" distance="" only="" needs="" to="" be="" computed="" for="" (at="" most)="" the="" next="" 7="" points="" in="" the="" list="" that="" is="" sorted="" by="" y-coordinate.="" (see="" the="" clrs="" pdf="" for="" details.)="" 4.="" return="" the="" smaller="" of="" d="" or="" the="" smallest="" distance="" found="" in="" the="" previous="" step.="" 6.="" the="" final="" answer="" is="" the="" minimum="" among="" the:="" distance="" between="" the="" closest="" pair="" of="" points="" on="" the="" left-hand="" side,="" dl.="" distance="" between="" the="" closest="" pair="" of="" points="" on="" the="" right-hand="" side,="" dr.="" distance="" between="" the="" closest="" pair="" of="" points="" where="" one="" point="" is="" on="" the="" left-hand-side="" and="" the="" other="" point="" is="" on="" the="" right-hand="" side.="" multi-process="" recursive="" solution="" we="" will="" check="" for="" compliance="" with="" all="" the="" following="" requirements.="" no="" credit="" will="" be="" given="" to="" submissions="" that="" violate="" these="" requirements="" (e.g.,="" implementing="" a="" single-process="" solution,="" or="" not="" using="" pipes="" to="" communicate="" between="" processes).="" the="" closest_parallel()="" function="" should="" first="" sort="" the="" points,="" using="" qsort(),="" in="" ascending="" order="" by="" their="" x-coordinates.="" it="" should="" then="" call="" _closest_parallel().="" the="" following="" logic="" specifies="" the="" requirements="" for="" the="" creation="" of="" and="" the="" co-ordination="" between="" the="" worker="" processes="" by="" _closest_parallel():="" 1.="" sort="" the="" array="" of="" n="" points,="" by="" their="" x-coordinates,="" in="" ascending="" order.="" 2.="" let="" pdmax="pdepth," where="" pdepth="" is="" the="" maximum="" depth="" of="" the="" process="" tree,="" specified="" by="" the="" argument="" of="" the="" command-line="" option="" -d.="" 3.="" if="" n=""><= 3, or pdmax == 0, invoke _closest_serial() to obtain the answer without creating any child processes. this is the stop 3,="" or="" pdmax="=" 0,="" invoke="" _closest_serial()="" to="" obtain="" the="" answer="" without="" creating="" any="" child="" processes.="" this="" is="" the="">= 3, or pdmax == 0, invoke _closest_serial() to obtain the answer without creating any child processes. this is the stop>