-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathactivity_selection.c
More file actions
193 lines (158 loc) · 4.87 KB
/
activity_selection.c
File metadata and controls
193 lines (158 loc) · 4.87 KB
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* 活动选择问题 - 选择最多数量的相容活动
*
* 算法:
* - 给定一组带有开始时间和结束时间的活动
* - 选择数量最多的互不重叠活动
* - 策略:按结束时间排序,然后贪心地选择活动
*
* 时间复杂度:O(n log n)(排序)
* 空间复杂度:O(n)(存储结果)
*
* 关键思想:
* 总是优先选择结束时间最早的活动,可以为后续活动留下最多空间,
* 这一贪心选择可以得到最优解。
*/
typedef struct {
int start;
int end;
int id;
} Activity;
/*
* 按结束时间排序的比较函数
*/
int compare_by_end_time(const void *a, const void *b) {
Activity *act_a = (Activity *)a;
Activity *act_b = (Activity *)b;
return act_a->end - act_b->end;
}
/*
* 选择最多数量的不重叠活动
*
* 参数:
* activities: 活动数组
* n: 活动数量
* selected: 用于存放被选中活动的数组
*
* 返回:
* 选中活动的数量
*/
int activity_selection(Activity *activities, int n, Activity *selected) {
if (n == 0) {
return 0;
}
/*
* 按结束时间对活动进行排序
*/
qsort(activities, n, sizeof(Activity), compare_by_end_time);
/*
* 总是先选择结束时间最早的第一个活动
*/
int count = 1;
selected[0] = activities[0];
int last_end_time = activities[0].end;
/*
* 贪心选择剩余的活动
*/
for (int i = 1; i < n; i++) {
/*
* 如果当前活动的开始时间不早于上一个已选活动的结束时间,
* 则视为相容,可以选择该活动
*/
if (activities[i].start >= last_end_time) {
selected[count] = activities[i];
last_end_time = activities[i].end;
count++;
}
}
return count;
}
void test_basic_example() {
printf("\n[Test 1] Basic example with overlapping activities\n");
Activity activities[] = {
{1, 3, 1}, {2, 5, 2}, {4, 6, 3},
{6, 7, 4}, {5, 8, 5}, {8, 9, 6}
};
int n = 6;
Activity selected[n];
int count = activity_selection(activities, n, selected);
printf("Input activities:\n");
for (int i = 0; i < n; i++) {
printf(" Activity %d: [%d, %d]\n", activities[i].id, activities[i].start, activities[i].end);
}
printf("Selected activities: %d\n", count);
for (int i = 0; i < count; i++) {
printf(" Activity %d: [%d, %d]\n", selected[i].id, selected[i].start, selected[i].end);
}
}
void test_all_compatible() {
printf("\n[Test 2] All activities compatible (non-overlapping)\n");
Activity activities[] = {
{1, 2, 1}, {2, 3, 2}, {3, 4, 3}, {4, 5, 4}
};
int n = 4;
Activity selected[n];
int count = activity_selection(activities, n, selected);
printf("Selected activities: %d\n", count);
for (int i = 0; i < count; i++) {
printf(" Activity %d: [%d, %d]\n", selected[i].id, selected[i].start, selected[i].end);
}
}
void test_all_overlapping() {
printf("\n[Test 3] All activities overlapping\n");
Activity activities[] = {
{1, 10, 1}, {2, 9, 2}, {3, 8, 3}, {4, 7, 4}
};
int n = 4;
Activity selected[n];
int count = activity_selection(activities, n, selected);
printf("Selected activities: %d\n", count);
for (int i = 0; i < count; i++) {
printf(" Activity %d: [%d, %d]\n", selected[i].id, selected[i].start, selected[i].end);
}
}
void test_single_activity() {
printf("\n[Test 4] Single activity\n");
Activity activities[] = {{5, 10, 1}};
int n = 1;
Activity selected[n];
int count = activity_selection(activities, n, selected);
printf("Selected activities: %d\n", count);
}
void test_empty() {
printf("\n[Test 5] Empty input\n");
Activity *activities = NULL;
int n = 0;
Activity selected[1];
int count = activity_selection(activities, n, selected);
printf("Selected activities: %d\n", count);
}
void test_complex_scheduling() {
printf("\n[Test 6] Complex scheduling scenario\n");
Activity activities[] = {
{0, 6, 1}, {1, 4, 2}, {3, 5, 3},
{5, 7, 4}, {8, 9, 5}, {5, 9, 6}
};
int n = 6;
Activity selected[n];
int count = activity_selection(activities, n, selected);
printf("Selected activities: %d\n", count);
for (int i = 0; i < count; i++) {
printf(" Activity %d: [%d, %d]\n", selected[i].id, selected[i].start, selected[i].end);
}
}
int main() {
printf("==================================================\n");
printf("ACTIVITY SELECTION - Greedy Algorithm (C)\n");
printf("==================================================\n");
test_basic_example();
test_all_compatible();
test_all_overlapping();
test_single_activity();
test_empty();
test_complex_scheduling();
return 0;
}