Эвристикаҳои решавӣ
Эвристикаҳои решавӣ
Эвристикаҳои решагӣ — номи умумии усулҳо ва сохторҳои додаҳо мебошанд, ки ба ин факт такя мекунанд:
агар маҷмӯаро аз элемент ба блокҳо бо элемент ҷудо кунем, пас шумораи блокҳо аз зиёд намешавад.
Эвристикаҳои решавӣ
Эвристикаҳои решагӣ — номи умумии усулҳо ва сохторҳои додаҳо мебошанд, ки ба ин факт такя мекунанд:
агар маҷмӯаро аз элемент ба блокҳо бо элемент ҷудо кунем, пас шумораи блокҳо аз зиёд намешавад.
Идеяи калидӣ:
«объектҳои хурд бисёранд, аммо онҳо хурданд; объектҳои калон каманд»
Мисоли классикӣ — факторизатсия бо реша.
Агар — тақсимкунандаи «калон»-и адади бошад, пас ба он тақсимкунандаи «хурд» мувофиқ меояд:
Яъне тақсимкунандаҳои калон каманд, зеро ба ҳар як калон як хурд мувофиқ аст.
Ин гуна мантиқро аксар вақт ба объектҳои дигар мегузаронанд: сатрҳо, қуллаҳои граф, навъҳои дархостҳо, вазнҳои ашё ва ғ.
Лозим аст онлайн маҷмӯи сатрҳоро нигоҳ дорем ва амалиётҳоро коркард кунем:
Сатрҳоро ҷудо мекунем ба:
Дар ин ҷо ҳамчун интихоб мешавад, ки — дарозии ҷамъии ҳамаи сатрҳост.
Он гоҳ сатрҳои дароз каманд: на бештар аз .
Граф аз қулла ва канор дода шудааст. Лозим аст шумораи даврҳои дарозии 3 (секунҷаҳо)-ро ҳисоб кунем.
Қулла вазнин аст, агар дараҷаи он аз зиёд бошад, вагарна сабук.
Қуллаҳои вазнин каманд: онҳо на бештар аз мебошанд.
Аз рӯйи шумораи қуллаҳои вазнин дар секунҷа ҷудо мекунем:
Қуллаи вазнин нест
Дар секунҷа канори ҳаст, қуллаи сеюм дар буриш/иттиҳоди ҳамсояҳо ҷойгир аст.
Азбаски дараҷаҳо хурданд, маҳдудияти тартиби мегирем.
Як қуллаи вазнин
Монанд: як канори «сабук» ҳаст → баҳодиҳӣ ҳам .
Ду қуллаи вазнин
Канори -ро муқаррар мекунем, роҳҳо .
Қуллаҳои вазнин ҳамагӣ → боз .
Се қуллаи вазнин
Қуллаҳои вазнин каманд, баррасии ҳамаи ҳолатҳо низ ҷо мегирад.
Дар натиҷа секунҷаҳо «он қадар зиёд нестанд»: тартибан .
Қуллаҳоро аз рӯйи (дараҷа, рақам) тартиб медиҳем.
Баъд роҳҳои намуди -ро бо тартиби дуруст мегардонем ва мавҷудияти канори -ро месанҷем.
ашё бо вазнҳои ҳастанд, ва:
Динамикаи стандартӣ бо кор мекунад.
Агар вазни гуногуни мусбат бо суммаи бошад, пас:
аз ин ҷо:
Яъне вазнҳои гуногун на бештар аз мебошанд.
Агар вазни маротиба вохӯрад, -ро ба суммаҳои дараҷаҳои ду таҷзия мекунем ва ин ашёро ба ашёҳои вазнҳои зерин иваз мекунем:
Ҳамин тавр ҳамаи суммаҳои намуди барои нигоҳ дошта мешаванд.
Пас аз чунин табдил шумораи ашёҳо тартибан мешавад, ва баъд динамикаи стандартиро ба кор меандозем.
Эзоҳ: ҳалли рюкзакро метавон бо ёрии bitset хеле тез кард.
long long count_triangles(int n, vector<vector<int>> &g) {
vector<int> deg(n);
for (int v = 0; v < n; v++) deg[v] = (int)g[v].size();
auto better = [&](int a, int b) {
if (deg[a] != deg[b]) return deg[a] < deg[b];
return a < b;
};
// sort vertices by (degree, id)
vector<int> order(n);
iota(order.begin(), order.end(), 0);
sort(order.begin(), order.end(), better);
// sort adjacency lists in the same order
for (int v = 0; v < n; v++) {
sort(g[v].begin(), g[v].end(), better);
}
vector<int> cnt(n, 0);
long long ans = 0;
for (int v : order) {
// mark all "forward" neighbors of v
for (int u : g[v]) {
if (!better(v, u)) break;
cnt[u] = 1;
}
// count triangles v - u - w where v<u<w in this order
for (int u : g[v]) {
if (!better(v, u)) break;
for (int w : g[u]) {
if (!better(u, w)) break;
ans += cnt[w];
}
}
// unmark
for (int u : g[v]) {
if (!better(v, u)) break;
cnt[u] = 0;
}
}
return ans;
}