/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* This file is part of the HiGHS linear optimization suite */ /* */ /* Written and engineered 2008-2022 at the University of Edinburgh */ /* */ /* Available as open-source under the MIT License */ /* */ /* Authors: Julian Hall, Ivet Galabova, Leona Gottwald and Michael */ /* Feldmeier */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /**@file util/HighsSort.cpp * @brief Sorting routines for HiGHS */ #include "util/HighsSort.h" #include using std::vector; void addToDecreasingHeap(HighsInt& n, HighsInt mx_n, vector& heap_v, vector& heap_ix, const double v, const HighsInt ix) { HighsInt cd_p, pa_p; if (n < mx_n) { // The heap is not full so put the new value at the bottom of the // heap and let it rise up to its correct level. n++; cd_p = n; pa_p = cd_p / 2; for (;;) { if (pa_p > 0) { if (v < heap_v[pa_p]) { heap_v[cd_p] = heap_v[pa_p]; heap_ix[cd_p] = heap_ix[pa_p]; cd_p = pa_p; pa_p = pa_p / 2; continue; } } break; } heap_v[cd_p] = v; heap_ix[cd_p] = ix; } else if (v > heap_v[1]) { // The heap is full so replace the least value with the new value // and let it sink down to its correct level. pa_p = 1; cd_p = pa_p + pa_p; for (;;) { if (cd_p <= n) { if (cd_p < n) { if (heap_v[cd_p] > heap_v[cd_p + 1]) cd_p++; } if (v > heap_v[cd_p]) { heap_v[pa_p] = heap_v[cd_p]; heap_ix[pa_p] = heap_ix[cd_p]; pa_p = cd_p; cd_p = cd_p + cd_p; continue; } } break; } heap_v[pa_p] = v; heap_ix[pa_p] = ix; } // Set heap_ix[0]=1 to indicate that the values form a heap. heap_ix[0] = 1; return; } void sortDecreasingHeap(const HighsInt n, vector& heap_v, vector& heap_ix) { HighsInt fo_p, srt_p; HighsInt cd_p, pa_p; HighsInt ix; double v; if (n <= 1) return; if (heap_ix[0] != 1) { // The data are assumed to be completely unordered. A heap will be formed // and sorted. fo_p = n / 2 + 1; srt_p = n; } else { // The data are assumed to form a heap which is to be sorted. fo_p = 1; srt_p = n; } for (;;) { if (fo_p > 1) { fo_p = fo_p - 1; v = heap_v[fo_p]; ix = heap_ix[fo_p]; } else { v = heap_v[srt_p]; ix = heap_ix[srt_p]; heap_v[srt_p] = heap_v[1]; heap_ix[srt_p] = heap_ix[1]; srt_p--; if (srt_p == 1) { heap_v[1] = v; heap_ix[1] = ix; return; } } pa_p = fo_p; cd_p = fo_p + fo_p; for (;;) { if (cd_p <= srt_p) { if (cd_p < srt_p) { if (heap_v[cd_p] > heap_v[cd_p + 1]) cd_p = cd_p + 1; } if (v > heap_v[cd_p]) { heap_v[pa_p] = heap_v[cd_p]; heap_ix[pa_p] = heap_ix[cd_p]; pa_p = cd_p; cd_p = cd_p + cd_p; continue; } } break; } heap_v[pa_p] = v; heap_ix[pa_p] = ix; } return; } void maxheapsort(HighsInt* heap_v, HighsInt n) { buildMaxheap(heap_v, n); maxHeapsort(heap_v, n); } void maxheapsort(HighsInt* heap_v, HighsInt* heap_i, HighsInt n) { buildMaxheap(heap_v, heap_i, n); maxHeapsort(heap_v, heap_i, n); } void maxheapsort(double* heap_v, HighsInt* heap_i, HighsInt n) { buildMaxheap(heap_v, heap_i, n); maxHeapsort(heap_v, heap_i, n); } void buildMaxheap(HighsInt* heap_v, HighsInt n) { HighsInt i; for (i = n / 2; i >= 1; i--) { maxHeapify(heap_v, i, n); } } void buildMaxheap(HighsInt* heap_v, HighsInt* heap_i, HighsInt n) { HighsInt i; for (i = n / 2; i >= 1; i--) { maxHeapify(heap_v, heap_i, i, n); } } void buildMaxheap(double* heap_v, HighsInt* heap_i, HighsInt n) { HighsInt i; for (i = n / 2; i >= 1; i--) { maxHeapify(heap_v, heap_i, i, n); } } void maxHeapsort(HighsInt* heap_v, HighsInt n) { HighsInt temp_v; HighsInt i; for (i = n; i >= 2; i--) { temp_v = heap_v[i]; heap_v[i] = heap_v[1]; heap_v[1] = temp_v; maxHeapify(heap_v, 1, i - 1); } } void maxHeapsort(HighsInt* heap_v, HighsInt* heap_i, HighsInt n) { HighsInt temp_v; HighsInt i, temp_i; for (i = n; i >= 2; i--) { temp_v = heap_v[i]; heap_v[i] = heap_v[1]; heap_v[1] = temp_v; temp_i = heap_i[i]; heap_i[i] = heap_i[1]; heap_i[1] = temp_i; maxHeapify(heap_v, heap_i, 1, i - 1); } } void maxHeapsort(double* heap_v, HighsInt* heap_i, HighsInt n) { double temp_v; HighsInt i, temp_i; for (i = n; i >= 2; i--) { temp_v = heap_v[i]; heap_v[i] = heap_v[1]; heap_v[1] = temp_v; temp_i = heap_i[i]; heap_i[i] = heap_i[1]; heap_i[1] = temp_i; maxHeapify(heap_v, heap_i, 1, i - 1); } } void maxHeapify(HighsInt* heap_v, HighsInt i, HighsInt n) { HighsInt temp_v; HighsInt j; temp_v = heap_v[i]; j = 2 * i; while (j <= n) { if (j < n && heap_v[j + 1] > heap_v[j]) j = j + 1; if (temp_v > heap_v[j]) break; else if (temp_v <= heap_v[j]) { heap_v[j / 2] = heap_v[j]; j = 2 * j; } } heap_v[j / 2] = temp_v; return; } void maxHeapify(HighsInt* heap_v, HighsInt* heap_i, HighsInt i, HighsInt n) { HighsInt temp_v; HighsInt j, temp_i; temp_v = heap_v[i]; temp_i = heap_i[i]; j = 2 * i; while (j <= n) { if (j < n && heap_v[j + 1] > heap_v[j]) j = j + 1; if (temp_v > heap_v[j]) break; else if (temp_v <= heap_v[j]) { heap_v[j / 2] = heap_v[j]; heap_i[j / 2] = heap_i[j]; j = 2 * j; } } heap_v[j / 2] = temp_v; heap_i[j / 2] = temp_i; return; } void maxHeapify(double* heap_v, HighsInt* heap_i, HighsInt i, HighsInt n) { double temp_v; HighsInt j, temp_i; temp_v = heap_v[i]; temp_i = heap_i[i]; j = 2 * i; while (j <= n) { if (j < n && heap_v[j + 1] > heap_v[j]) j = j + 1; if (temp_v > heap_v[j]) break; else if (temp_v <= heap_v[j]) { heap_v[j / 2] = heap_v[j]; heap_i[j / 2] = heap_i[j]; j = 2 * j; } } heap_v[j / 2] = temp_v; heap_i[j / 2] = temp_i; return; } bool increasingSetOk(const vector& set, const HighsInt set_entry_lower, const HighsInt set_entry_upper, bool strict) { HighsInt set_num_entries = set.size(); bool check_bounds = set_entry_lower <= set_entry_upper; HighsInt previous_entry; if (check_bounds) { if (strict) { previous_entry = set_entry_lower - 1; } else { previous_entry = set_entry_lower; } } else { previous_entry = -kHighsIInf; } for (HighsInt k = 0; k < set_num_entries; k++) { HighsInt entry = set[k]; if (strict) { if (entry <= previous_entry) return false; } else { if (entry < previous_entry) return false; } if (check_bounds && entry > set_entry_upper) return false; previous_entry = entry; } return true; } bool increasingSetOk(const vector& set, const double set_entry_lower, const double set_entry_upper, bool strict) { HighsInt set_num_entries = set.size(); bool check_bounds = set_entry_lower <= set_entry_upper; double previous_entry; if (check_bounds) { if (strict) { if (set_entry_lower < 0) { previous_entry = (1 + kHighsTiny) * set_entry_lower; } else if (set_entry_lower > 0) { previous_entry = (1 - kHighsTiny) * set_entry_lower; } else { previous_entry = -kHighsTiny; } } else { previous_entry = set_entry_lower; } } else { previous_entry = -kHighsInf; } for (HighsInt k = 0; k < set_num_entries; k++) { double entry = set[k]; if (strict) { if (entry <= previous_entry) return false; } else { if (entry < previous_entry) return false; } if (check_bounds && entry > set_entry_upper) return false; previous_entry = entry; } return true; } void sortSetData(const HighsInt num_entries, vector& set, const double* data0, const double* data1, const double* data2, double* sorted_data0, double* sorted_data1, double* sorted_data2) { if (num_entries <= 0) return; vector sort_set_vec(1 + num_entries); vector perm_vec(1 + num_entries); HighsInt* sort_set = &sort_set_vec[0]; HighsInt* perm = &perm_vec[0]; for (HighsInt ix = 0; ix < num_entries; ix++) { sort_set[1 + ix] = set[ix]; perm[1 + ix] = ix; } maxheapsort(sort_set, perm, num_entries); for (HighsInt ix = 0; ix < num_entries; ix++) { set[ix] = sort_set[1 + ix]; if (data0 != NULL) sorted_data0[ix] = data0[perm[1 + ix]]; if (data1 != NULL) sorted_data1[ix] = data1[perm[1 + ix]]; if (data2 != NULL) sorted_data2[ix] = data2[perm[1 + ix]]; } } void sortSetData(const HighsInt num_entries, vector& set, const HighsVarType* data0, HighsVarType* sorted_data0) { if (num_entries <= 0) return; vector sort_set_vec(1 + num_entries); vector perm_vec(1 + num_entries); HighsInt* sort_set = &sort_set_vec[0]; HighsInt* perm = &perm_vec[0]; for (HighsInt ix = 0; ix < num_entries; ix++) { sort_set[1 + ix] = set[ix]; perm[1 + ix] = ix; } maxheapsort(sort_set, perm, num_entries); for (HighsInt ix = 0; ix < num_entries; ix++) { set[ix] = sort_set[1 + ix]; if (data0 != NULL) sorted_data0[ix] = data0[perm[1 + ix]]; } }