Skip to content

Commit 0977c1f

Browse files
committed
c/pareto.c (pareto_rank_2d): Simplify.
1 parent 32173b0 commit 0977c1f

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

c/pareto.c

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pareto_rank_2d(const double * restrict points, size_t size)
169169
fprintf(stderr, "\n[1] : "); vector_fprintf (stderr, help_1, size);
170170
#endif
171171

172-
// Sort in ascending lexicographic order from the first dimension.
172+
// Sort in ascending lexicographic order from the second dimension.
173173
qsort(p, size, sizeof(*p), cmp_double_asc_rev_2d);
174174

175175
#ifdef PARETO_RANK_2D_DEBUG
@@ -185,43 +185,44 @@ pareto_rank_2d(const double * restrict points, size_t size)
185185
#endif
186186

187187
int * rank = malloc(size * sizeof(*rank));
188-
const double ** front_last = malloc(size * sizeof(*front_last));
188+
double * front_last = malloc(size * sizeof(*front_last));
189189
int n_front = 0;
190-
front_last[0] = p[0];
190+
front_last[0] = p[0][0];
191191
rank[(p[0] - points) / dim] = 0; // The first point is in the first front.
192+
int last_rank = 0;
192193
for (size_t k = 1; k < size; k++) {
193-
const double * pk = p[k];
194-
const double * plast = front_last[n_front];
195-
if (pk[0] < plast[0]) {
194+
const double * restrict pk = p[k];
195+
// Duplicated points are kept in the same front.
196+
if (pk[0] == p[k-1][0] && pk[1] == p[k-1][1]) {
197+
rank[(pk - points) / dim] = last_rank;
198+
continue;
199+
}
200+
const double plast = front_last[n_front];
201+
if (pk[0] < plast) {
196202
int low = 0;
197-
int high = n_front + 1;
198-
do {
199-
int mid = low + (high - low) / 2;
200-
assert (mid <= n_front);
201-
const double * pmid = front_last[mid];
202-
if (pk[0] < pmid[0])
203-
high = mid;
204-
else if (pk[0] > pmid[0] || (pk[0] == pmid[0] && pk[1] > pmid[1]))
205-
low = mid + 1;
206-
else { // Duplicated points are assigned to the same front.
207-
low = mid;
208-
break;
209-
}
210-
} while (low < high);
211-
assert (low <= n_front);
212-
assert (pk[0] < front_last[low][0]
213-
|| (pk[0] == front_last[low][0]
214-
&& pk[1] == front_last[low][1]));
215-
front_last[low] = pk;
216-
rank[(pk - points)/dim] = low;
217-
} else if (pk[0] == plast[0] && pk[1] == plast[1]) {
218-
front_last[n_front] = pk;
219-
rank[(pk - points)/dim] = n_front;
203+
if (n_front > 0) {
204+
int high = n_front + 1;
205+
do {
206+
int mid = low + (high - low) / 2;
207+
assert(mid <= n_front);
208+
const double pmid = front_last[mid];
209+
// FIXME: When mid == n_front, then pk[0] < pmid, so avoid this test.
210+
if (pk[0] < pmid)
211+
high = mid;
212+
else {
213+
low = mid + 1;
214+
}
215+
} while (low < high);
216+
}
217+
assert(low <= n_front);
218+
assert(pk[0] < front_last[low]);
219+
last_rank = low;
220220
} else {
221221
n_front++;
222-
front_last[n_front] = pk;
223-
rank[(pk - points)/dim] = n_front;
222+
last_rank = n_front;
224223
}
224+
front_last[last_rank] = pk[0];
225+
rank[(pk - points)/dim] = last_rank;
225226
}
226227
free(front_last);
227228
#ifdef PARETO_RANK_2D_DEBUG

0 commit comments

Comments
 (0)