Примечание. Написав этот вопрос, я думаю, что уже нашел ответ. Не стесняйтесь исправлять или дополнять его лучшей версией. Я подумал, что было бы неплохо задокументировать мою проблему. редактировать Я был неправ, мой ответ был неверным.
Рассматривая список целочисленных пар: я хотел бы топологически отсортировать их на основе частичного порядка. Это похоже на является частичным -order, в отличие от total-order, достаточно для создания кучи? , но я бы хотел использовать std::sort вместо std::priority_queue.
Для этого я написал этот фрагмент кода:
#include <iostream>
#include <vector>
#include <algorithm>
struct pair {
int a, b;
pair(int a, int b) : a(a), b(b) {}
std::ostream &print(std::ostream &out) const {
return (out << "(" << a << ", " << b << ")");
}
};
std::ostream &operator<<(std::ostream &out, const pair &p) { return p.print(out); }
struct topological_pair_comparator {
bool operator()(const pair &p, const pair &q) const { return p.a<q.a && p.b<q.b; }
} tpc;
std::vector<pair> pairs = {
pair(1,1),
pair(1,2),
pair(2,1),
pair(3,1),
pair(1,3),
pair(5,5),
pair(2,2),
pair(4,0)
};
int main() {
std::sort(pairs.begin(), pairs.end(), tpc);
for(const pair &p : pairs) std::cout << p << " ";
std::cout << std::endl;
return 0;
}
Источник: http://ideone.com/CxOVO0
В результате чего:
(1, 1) (1, 2) (2, 1) (3, 1) (1, 3) (2, 2) (4, 0) (5, 5)
Который в значительной степени топологически отсортирован (доказательство на примере;).
Однако частичное упорядочение приводит к тому, что !((1,2) ‹ (2,1)) и !((1,2) > (2,1)) в соответствии с tpc, и, следовательно, можно сделать вывод (1,2 ) == (2,1). Однако в параграфе 25.4.3 стандарта С++ (рабочий проект от января 2012 г.) говорится:
Для всех алгоритмов, использующих Compare, существует версия, в которой вместо этого используется оператор‹. То есть comp(*i, *j) != false по умолчанию *i ‹ *j != false. Для правильной работы алгоритмов, отличных от описанных в 25.4.3, comp должен индуцировать строгое слабое упорядочение значений.
Отредактировано: Согласно правильному ответу ecatmur: Частичный порядок не обязательно является строгим слабым порядком; это нарушает транзитивность несопоставимости. Поэтому я хотел бы отказаться от своих рассуждений о том, что частичное упорядочение всегда является строгим слабым упорядочением и связанными с этим вопросами, и добавить вопрос: обречен ли я писать свои собственные алгоритм топологической сортировки или использовать реализацию boost, которая требует от меня построения графика?
Решение. Разумный вариант экатмура:
struct topological_pair_comparator {
bool operator()(const pair &p, const pair &q) const { return (p.a + p.b) < (q.a + q.b); }
} tpc;
Источник: http://ideone.com/uoOXNC
Обратите внимание, что в SO о кучах явно не упоминается, что std::sort сортирует топологически; кроме одного комментария, не подкрепленного аргументацией.
V
). Затем вы можете выполнитьO(V^2)
полный поиск по всем парам вершин и добавить ребро(x, y)
к вашему графу, еслиtpc(x, y)
верно. Затем вы можете запустить топологическую сортировку поO(V + E)
на вашем графике (всегоO(V^2)
). - person TemplateRex   schedule 18.11.2016