CS302 2023 Final Exam

December 12, 2023. James Plank. 120 minutes.

The exam was done on Canvas with question banks, so this is an example exam.

Please do all questions. Although it says that there are 11 questions, in my view there are 7:

Budget your time wisely. In particular, you may want to do Questions 3, 5, 6, 7 and 8 before you do Questions 4, 9, 10 and 11. Try not to let time slip away from you in question 4.

Finally -- you can use Question 2 for scratch space. You may find that helpful, for example, in Question 3, part D."


Question 1 - 0 Points

Please enter your UTK username/netid. For example, mine is jplank.

Question 2 - 0 Points

If you feel the need to make comments on your answers, please do so here, rather than in the answer space for the question. You may leave this blank.

Question 3 - 20 Points

Part A

When you implemented merge sort in lab, I recommended the following recursive prototype:

void recursive_sort(vector <double> &v, vector <double> &temp, int start, int size, int print);

Suppose I call recursive_sort(v, tmp, 32, 16, 0). This is going to make two recursive calls. Please tell me start and size are in these two recursive calls:

Start: _____ Size: _____
Start: _____ Size: _____

Part B

Suppose I call recursive_sort(v, tmp, 4, 4, 0), and v is as follows:
93 49 31 15 71 26 59 10
This is going to make two recursive calls. Right after the second of these returns, please enter v (enter numbers each separated by a space):

________________________________

Part C

When I call quicksort, here is my input vector:
86 99 86 98 2 47 54 3 36 66 76 14 34
You are using the median-of-three pivot selection algorithm. What is the pivot? _____

Part D

When you implemented quicksort, I recommended the following prototype for the recursive procedure:

void recursive_sort(vector <double> &v, int start, int size, int print)

I call recursive_sort(v, 0, 13, 0), and v is:

74 88 88 80 28 74 15 99 74 74 74 88 28
74 is the pivot. You will make two recursive calls. What is start and size in each recursive call?

Start: _____ Size: _____
Start: _____ Size: _____

Part E

I need to write a sorting procedure, and I am told that my vectors are going to look like the following graphs:

What sorting algorithm should I use to sort them? __________________

If the vector has n elements, when is the running time of the best algorithm for sorting them? __________________


Question 4 - 20 Points

For each problem below, I want you state the graph algorithm that you would use to solve the problem, and if you know the running time, state that. If you don't know the running time (e.g. Network Flow), then just put an X for the running time. By the way, here are the graph algorithms that we have studied in this class. You can use the abbreviations given in your answer: Hint -- if the algorithm doesn't pop out to you, figure out what in the problem are nodes and what are edges. Draw yourself an example graph for the problem, and come up with the answer for that graph. That will help you identify which algorithm is used to generate the answer.

Part 1:

I am the head of a transportation logistics company. We have two divisions -- air and train. Each of these divisions keeps the following information on cities and the routes between them. Cities are endpoints, where we can store goods. Routes may exist between two cities in either of the divisions. For each route, there is a time to travel the route, and a cost that it takes to travel the route.

Suppose I need to get goods from city A to city B, and I want to do it in cheapest manner, money-wise. Which algorithm should I use? _______________________

Suppose there are C cities and R routes. What is the running time of the algorithm? _______________________

Part 2:

A new management regime takes over from part 1, and dictates that every plane or train trip will cost $1,000. I need to get goods from city A to city B, and I want to do it in cheapest manner. Which algorithm should I use? _______________________

What is the running time? _______________________

Part 3:

A newer management regime takes over, and the costs of the routes return to what they were in Part 1. Let's suppose that the cost of going from city A to city B is the same as going from city B to city A. Management has inflicted another cost cutting measure on us -- we need to cancel as many routes as we can, but still make sure that our goods can get from any one city to another. We want to do this, but we want to make sure that the total cost of all routes is as small as possible. What algorithm do we use? _______________________

What is the running time? _______________________

Part 4:

A terrorist group has decided that they want to make it impossible to have goods go from Bangor, Maine to San Diego, CA. The first thing they will do is bomb all of the airports, so no more plane travel. Then, for each train route, they have determined the cost of bombing that route. What algorithm should they use to figure out which train routes to destroy that will achieve their goals in the cheapest manner? _______________________

What is the running time? _______________________

Part 5:

Question 4: The terrorist group has done their bombings. Some of them have been successful, and some of them haven't. You work for the government and know all of the success or failure of each bombing. You are asked if it's possible to get goods from Seattle to Miami. Which algorithm do you use to make this determination? _______________________

What is the running time? _______________________


Question 5 - 8 Points

Please state the halting problem as I stated it in class, and what has been proven about it. Be precise in your writing. Don't give me crap about Turing machines or things that you may have learned about the halting problem in other classes or on Wikipedia. Please state it as I did in class. Also, don't prove anything. I just want the statement of the problem and what has been proven about it.

Question 6 - 12 Points

The following adjacency matrix is for a weighted, directed graph:
       A   B   C   D   E   F   G   H
     --- --- --- --- --- --- --- ---
A |   --  13  --  57  23  34  --  85
B |   67  --  --  40  12  20  12  51
C |   43  86  --  71  --   9  42  80
D |   --  --  --  --  21  60  29  90
E |   85  63  --  30  --  95  96   7
F |   11   6  --  79  --  --  78  41
G |   --  18  --  71  52  40  --  22
H |   --  99  79  27  --  93  --  --
You are running Dijkstra's algorithm from node A. In the table that follows, we keep track of the distance vector, the backedge vector, and the first key and first val in the multimap.

I have filled out the starting condition. Please fill out what these values are after the first two iterations of Dijkstra's algorithm:

Starting
state
After first
iteration
After second
iteration
Distance to A 0
Distance to B -
Distance to C -
Distance to D -
Distance to E -
Distance to F -
Distance to G -
Distance to H -
Back-edge to A -
Back-edge to B -
Back-edge to C -
Back-edge to D -
Back-edge to E -
Back-edge to F -
Back-edge to G -
Back-edge to H -
1st key on multimap 0
1st val on multimap A

Question 7 - 10 Points

In this problem, when you are asked to specify a path, simply specify the nodes in order, without any spaces. When you are asked to specify a collection of edges, enter pairs of nodes separated by a space, such as "AB BC CD".

Our application is network flow, and below is a graph whose source is S and whose sink is T:

We run the Edmonds-Karp algorithm on this graph, and when we're done, below is the final residual graph:

Part A

What is the first augmenting path in the algorithm? __________________

Part B

What is the minimum cut of the graph? __________________

Part C

What is the maximum flow of the graph? __________________

Question 8 - 10 Points

In the following code, I enter an unweighted, undirected graph on standard input by simply listing edges as from, to on standard input. For example, the graph:
0 --- 1

2 --- 3

is represented on standard input as:

0 1
2 3
or equivalently as:
1 0
2 3
or:
1 0
3 2
In this code, the method Components() returns the number of connected components in the graph. It uses the vector C to keep track of the components. I've written everything for you, except that you need to write DFS(). Here's the code:
#include <vector>
#include <iostream>
using namespace std;

class Graph {
  public:
    Graph();
    int Components();
  protected:
    vector < vector <int> > Adj;
    vector <int> C;
    void DFS(int node, int component);
};

Graph::Graph()
{
  int from, to;

  while (cin >> from >> to) {
    if (Adj.size() <= from) Adj.resize(from+1);
    if (Adj.size() <= to) Adj.resize(to+1);
    Adj[from].push_back(to);
    Adj[to].push_back(from);
  }
}

int Graph::Components()
{
  int i, cn;

  C.clear();
  C.resize(Adj.size(), -1);

  cn = 0;
  for (i = 0; i < Adj.size(); i++) {
    if (C[i] == -1) {
      DFS(i, cn);
      cn++;
    }
  }
  return cn;
}

int main()
{
  Graph g;

  cout << g.Components() << endl;
  return 0;
}
Here is the code running:
UNIX> echo 0 1 | ./a.out
1
UNIX> echo 0 1  2 3 | ./a.out
2
UNIX> echo 0 1  3 2 | ./a.out
2
UNIX> echo 0 1  3 2  1 2 | ./a.out
1
UNIX> 
Please write DFS() below:

Question 9 - 10 Points

Behold the following definition of a function, fA,B(x,y). And let g(A,B) = fA,B(0,0).

I have written code for calculating g(A,B), and the only thing that it is missing is the code for DP::f(x,y). Here it is:

#include <vector>
#include <iostream>
using namespace std;

class DP {
  public:
    int A, B;
    long long g(int a, int b);
    long long f(int x, int y);
    vector < vector <long long> > Cache;
};

long long DP::g(int a, int b)
{
  size_t i;

  A = a;
  B = b;
  Cache.clear();
  Cache.resize(A+1);
  for (i = 0; i < Cache.size(); i++) Cache[i].resize(B+1, -1);
  return f(0,0);
}

int main()
{
  int a, b;
  DP d;

  if (cin >> a >> b) {
    cout << d.g(a,b) << endl;
  }
  return 0;
}

Below, please implement DP::f(x,y). It should be the "Step 2" implementation of dynamic programming.


Question 10 - 7 Points

Now, please write the "step 3" implementation of dynamic programming. For this, I have changed the class definition to the following:

class DP {
  public:
    long long g(int a, int b);
};

Below, please implement DP::g(a,b).


Question 11 - 3 Points

Now, please write the "step 4" implementation of dynamic programming. For that, you don't need to change the class definition from "step 3". You may find it helpful to copy-paste your code from "step 3".

Below, please implement DP::g(a,b).