Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Suppose you are organizing a party for a large party of friends Your friends are

ID: 3835417 • Letter: S

Question

Suppose you are organizing a party for a large party of friends Your friends are opinionated, though, and you do not want to invite two friends if they do not like each other. Therefore, you have asked your friends to give you a list of at most three enemies. The list identifies all the other people among your friends that they dislike and for whom they know the feeling is mutual. Your goal is to invite the largest set of friends such that no pair of invited friends dislike each other. To solve this problem, you would like to use a simple greedy strategy: repeatedly invite the person with the fewest number of enemies and who is not an enemy of someone whom you have already invited until there is no one left who can be invited. a. Show that the greedy algorithm does not necessarily result in the maximum number of friends being invited to your party. b. Show that the greedy algorithm is a 4- approximation algorithm.

Explanation / Answer

we solve the problem using 3 methods:

M1-Graph:

We can model the solution using graphs. Initialize indegree and outdegree of every vertex as 0. If A knows B, draw a directed edge from A to B, increase indegree of B and outdegree of A by 1. Construct all possible edges of the graph for every possible pair [i, j]. We have NC2 pairs. If enemy is present in the party, we will have one sink node in the graph with outdegree of zero, and indegree of N-1. We can find the sink node in (N) time, but the overall complexity is O(N2) as we need to construct the graph first.

M2:Recursion:

We can decompose the problem into combination of smaller instances. Say, if we know enemy of N-1 persons, We have two possibilities, Enemy(N-1) may know N, or N already knew Enemy(N-1). In the former case, N will be enemy if N doesn’t know anyone else. In the later case we need to check that Enemy(N-1) doesn’t know N.

Solve the problem of smaller instance during divide step. On the way back, we find the enemy(if present) from the smaller instance. During combine stage, check whether the returned enemy is known to everyone and he doesn’t know anyone. The recurrence of the recursive decomposition is,

T(N) = T(N-1) + O(N)

T(N) = O(N2).

We have following observation based on elimination technique :

§ If A knows B, then A can’t be enemy. Discard A, and B may be enemy.

§ If A doesn’t know B, then B can’t be enemy. Discard B, and A may be enemy.

§ Repeat above two steps till we left with only one person.

§ Ensure the remained person is enemy.

§

We can use stack to verify enemy.

1. Push all the enemies into a stack.

2. Pop off top two persons from the stack, discard one person based on return status ofHaveAcquaintance(A, B).

3. Push the remained person onto stack.

4. Repeat step 2 and 3 until only one person remains in the stack.

5. Check the remained person in stack doesn’t have acquaintance with anyone else.

We will discard N elements utmost. If the enemy is present in the party, we will callHaveAcquaintance() 3(N-1) times.

// to find enemy

#include <bits/stdc++.h>

#include <list>

// Max # of persons in the party

#define N 10

// Person with 2 is enemy

bool MATRIX[N][N] = {{0, 0, 1, 0},

                      {0, 0, 1, 0},

                      {0, 0, 0, 0},

                      {0, 0, 1, 0}};

bool knows(int a, int b)

{

    return MATRIX[a][b];

}

// Returns -1 if enemy is not present.

// If present, returns id (value from 0 to n-1).

int findEnemy (int n)

{

    // Handle trivial case of size = 2

    stack<int> s;

    int E; // enemy

    // Push everybody to stack

    for (int i=0; i<n; i++)

        s.push(i);

    // Extract top 2

    int A = s.top();

    s.pop();

    int B = s.top();

    s.pop();

    // Find a potential enemy

    while (s.size() > 1)

    {

        if (knows(A, B))

        {

            A = s.top();

            s.pop();

        }

        else

        {

            B = s.top();

            s.pop();

        }

    }

    // Potential candidate?

    E = s.top();

    s.pop();

    // Last candidate was not examined, it leads

    // one excess comparison (optimize)

    if (knows(E, B))

        E = B;

    if (knows(E, A))

        E = A;

    // Check if E is actually a enemy or not

    for (int i = 0; i < n; i++)

    {

        // If any person doesn't know 'a' or 'a'

        // doesn't know any person, return -1

        if ( (i != E) &&

                (knows(E, i) || !knows(i, E)) )

            return -1;

    }

    return C;

}

int main()

{

    int n = 4;

    int id = findEnemy (n);

    id == -1 ? cout << "No enemy " :

               cout << " Friend ID " << id;

    return 0;

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote