forked from germuth/Covering-PDO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsetoper.c
144 lines (118 loc) · 2.77 KB
/
setoper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* setoper.c
**
** This file contains functions needed for subset ranking and unranking
** plus making a complement of a given subset.
**
*/
/*Subsets are ranked as follows:
0 1 2 41
0 1 3 41
0 2 3 41
1 2 3 41
0 1 4 41
0 2 4 41
1 2 4 41
0 3 4 41
1 3 4 41
2 3 4 41
Where 41 is the sentinel value at the end of every subset
*/
#include "cover.h"
#include "bincoef.h"
#include "setoper.h"
/*
** `rankSubset' calculates a unique rank for a given subset with a given
** cardinality. Varieties in the subset are numbered beginning from 0.
**
*/
rankType rankSubset(varietyType *subset, int card)
{
int i;
rankType rank = 0;
for(i = 0; i < card; i++)
rank += binCoef[*subset++][i + 1];
return rank;
}
/*
** `getFirstSubset' gets the subset with rank 0 and the given cardinality.
**
*/
void getFirstSubset(varietyType *subset, int card)
{
int i;
for(i = 0; i < card; i++)
*subset++ = i;
*subset = maxv + 1; /* sentinel */
}
/*
** `getNextSubset' gets the subset that has rank one bigger than the rank
** of the given subset. `v' is the number of varieties. Varieties range
** from 0 to v - 1. It returns 0, if this was the greatest possible rank
** for this type subset, otherwise the return value is 1.
*/
int getNextSubset(varietyType *subset, int card, int v) {
int i,j;
if(subset[0] >= v - card){
return 0;
} else {
j = 0;
while(subset[j + 1] <= subset[j] + 1)
j++;
subset[j]++;
for(i = 0; i < j; i++)
subset[i] = i;
return 1;
}
}
/*
** `unrankSubset' makes a subset out of a rank.
**
*/
void unrankSubset(rankType rank, varietyType *subset, int card)
{
int p, m, i;
m = rank;
for(i = card - 1; i >= 0; i--) {
p = i;
while(binCoef[p + 1][i + 1] <= m)
p++;
m -= binCoef[p][i + 1];
subset[i] = p;
}
}
/*
** `makeComplement' forms the complement of a given subset `s' with a
** cardinality `c'. The number of varieties is `v'.
**
*/
//doesn't return valid ticket, just stores what numbers you didn't choose
void makeComplement(varietyType *s, varietyType *c, int v) {
int i;
for(i = 0; i < v; i++) {
if(*s == (varietyType) i)
s++;
else
*c++ = (varietyType) i;
}
*c = maxv + 1; /* sentinel */
}
/*
** printSubset prints a subset of a given cardinality in a format given by
** the command-line parameters.
*/
void printSubset(FILE *fp, rankType r, int card) {
varietyType set[maxv + 1], *vptr;
int i;
unrankSubset(r, set, card);
if(solX)
for(i = 0, vptr = set; i < v; i++)
if(*vptr == i) {
fprintf(fp, "X");
vptr++;
}
else
fprintf(fp, "-");
else
for(i = 0; i < card; i++)
fprintf(fp, "%d ", set[i]);
}