Data Structure collection _ collection instance (set overwrite), data structure instance

Set coverage is an optimized solution. It provides a good abstract model for many combined mathematical and resource selection problems. The problem is as follows: given a set of S, Set P is composed of the subset A1 of set s to An, and set C is composed of one or more subsets in Set P. If every Member in S is included in at least one subset of C, it means that set C overwrites set S. In addition, the smaller the subset of P contained in C, the better.

Imagine selecting a team from a large group of contestants, each of which has a specific skill combination. The goal is to build a minimum team so that the team has a specific set of skill combinations. That is to say, at least one contestant in the team must possess the skills required by the team. Assume that S is the skill set required by the team, and P is the skill set of all contestants to be selected. Select a skill combination from P to Form C. C must cover all the skills required in S. Importantly, we must select as few players as possible.

An Algorithm for set coverage is an approximate algorithm that does not always obtain the optimal solution. The algorithm works as follows:

Select a set from P so that it can overwrite the maximum number of members in S. In other words, this algorithm tries to overwrite more members in S as early as possible, so it adopts the greedy method. Since each set is selected from P, if P is removed, its members will also be removed from S. When no set of remaining members in P can overwrite the members in S, overwriting set C is complete.

Let's take a look at the 12 skill sets S = {a, B, c, d, e, f, g, h, I, j, k, l. Now there are seven contestants to be selected. P = {A1,... A7 }. The skill set of contestants in P is: A1 = {a, B, c, d}, A2 = {e, f, g, h}, A3 = {j, k, l}, A4 = {a, e}, A5 = {B, f, g}, A6 = {c, d, g, h, k, l }, a7 = {l }. The best coverage set should be C = {A1, A2, A3 }. The set of algorithms selected here is C = {A6, A2, A1, A3} (see figure 1 ).

Function implementation of set coverage problems

We use the function cover, which is located in the A1 ~ subset of the Set P ~ An selects the approximate optimal solution that can overwrite the set S. This function has three parameters:

1. members is the set S to be overwritten;

2. subsets are subsets in Set P;

3. covering serves as the returned overwrite set C.

This function modifies the passed three parameters. Therefore, when calling this function, you should save a copy of the parameters if necessary.

**Function Execution Process**: At the beginning, covering first obtains initialization by calling set_init.

We use loops for iteration. As long as there are still unoverwritten members in members and the subsets in subsets are not completely selected, the loop at the outermost layer must continue iteration.

In this loop, it finds the maximum intersection that can overwrite members in subsets during each iteration.

It then adds the set to the overwrite covering and removes its members from members (because these members have been overwritten, the next iteration will determine whether the remaining members can be overwritten ). At the end of the loop, remove the selected set from the subsets (selected to be removed ). If the outermost loop terminates iteration because members is not empty, the set in subsets cannot fully meet the requirements of members. Similarly, if the members of subsets cannot overlap with members of members during iteration, it also means that the members of subsets cannot fully meet the requirements of members. If function cover finds a completely overwritten solution, the function returns 0, and the covering parameter points to the completely overwritten solution. If it is not possible to completely override the solution, 1 is returned. Otherwise,-1 is returned.

The complexity of cover is O (m3). Here m represents the number of initial members in the members set. In the worst case, each member of members has only one unique subset corresponding to the subsets. The complexity is O (m3 ). In this case, subsets have m subsets, and set_intesection is executed with the complexity of O (m), because when the computation and members evaluate the intersection, each subset of subsets has only one member to traverse. Therefore, the inner loop of cover is O (m2), and this loop needs to be executed m times.

Example 1: Set to overwrite the problematic header file

#ifndef COVER_H

#define COVER_H

#include "set.h"

typedef struct KSet_

{

void * key;

Set set;

} KSet;

int cover (Set * member, Set * subsets, Set * covering);

#endif

Example 2: Function implementation of set coverage problem

#include <stdlib.h>

#include "cover.h"

#include "list.h"

#include "set.h"

int cover (Set * members, Set * subsets, Set * covering)

{

Set intersection;

KSet * subset;

ListElmt * member, * max_member;

void * data;

int max_size;

/ * Initializing covering set covering * /

set_init (covering, subsets-> match, NULL);

while (set_size (members)> 0 && set_size (subsets)> 0)

{

/ * Find the subset that can cover the most members * /

max_size = 0;

for (member = list_head (subsets); member! = NULL; member = list_next (member))

{

if (set_intersection (& intersection, & ((KSet *) list_data (member))-> set, members)! = 0)

return -1;

if (set_size (& intersection)> max_size)

{

max_member = member;

max_size = set_size (& intersection);

}

set_destroy (& intersection);

}

/ * If there is no intersection, then there is no covering set * /

if (max_size == 0)

return 1;

/ * Insert the selected subset into the covering set cover * /

subset = (KSet *) list_data (max_member);

if (set_insert (covering, subset)! = 0)

return -1;

/ * Remove elements that have been overwritten from members * /

for (member = list_head (& ((Kset *) list_data (max_member))-> set); member! = NULL;

list_next (member))

{

data = list_data (member);

if (set_remove (members, (void **) data) == 0 && members-> destroy! = NULL)

members-> destroy (data);

}

/ * Delete the selected subset from the subset collection * /

if (set_remove (subsets, (void **) & subset)! = 0)

return -1;

}

/ * If there are still uncovered elements in members, it is impossible to achieve full coverage * /

if (set_size (members)> 0)

return -1;

return 0;

}