Проблема з мінімальними витратами


9

Мережевий потік являє собою орієнтований граф G = (V, E)з вихідної вершиною s ϵ Vі вершиною раковини t ϵ V, і де кожне ребро (u, v) ϵ Eна графіку (вузли підключення u ϵ Vі v ϵ V) мають 2 величин , пов'язані з цим:

  1. c(u, v) >= 0, ємність краю
  2. a(u, v) >= 0, вартість відправки однієї одиниці через край

Ми визначаємо функцію 0 <= f(u, v) <= c(u, v)- кількість одиниць, що проходять через заданий край (u, v). Таким чином, вартість для даного краю (u, v)є a(u, v) * f(u, v). Проблема потоку мінімальної вартості визначається як мінімізація загальної вартості по всіх ребрах для заданої кількості потоку d, задана наступною кількістю:

вартість

Наступні обмеження стосуються проблеми:

  1. Вимоги до ємності : потік через даний край не може перевищувати ємність цього краю ( f(u, v) <= c(u, v)).
  2. Симетрія нахилу : потік, хоча даний край повинен бути антисиметричним, коли напрямок повернено ( f(u, v) = -f(v, u)).
  3. Збереження потоку : чистий потік у будь-який невідтоковий вузол повинен бути 0 (для кожного u ∉ {s, t}, підсумовуючи по всіх w, sum f(u, w) = 0).
  4. Необхідний потік : чистий потік із джерела та чистий потік у мийку повинні одночасно дорівнювати необхідному потоку через мережу (підсумовуючи по всьому u, sum f(s, u) = sum f(u, t) = d).

Враховуючи потокову мережу Gта необхідний потік d, виведіть мінімальну вартість для відправки dодиниць через мережу. Ви можете припустити, що рішення існує. dі вся ємність і витрати будуть невід’ємними цілими числами. Для мережі з Nвершинами, позначеними [0, N-1]вершиною, буде вихідною вершиною, 0а вершиною раковини буде N-1.

Це є , тому найкоротша відповідь (у байтах) виграє. Пам'ятайте, що це змагання як між мовами, так і між мовами, тому не бійтеся розміщувати рішення на багатослівній мові.

Вбудовані дозволені, але вам рекомендується включати рішення без вбудованих програм, або як додаткове рішення в тій самій відповіді, або як незалежна відповідь.

Вхід може бути будь-яким розумним способом, що включає потужність та витрати кожного краю та попит.

Випробування

Тестові приклади надаються у такому форматі:

c=<2D matrix of capacities> a=<2D matrix of costs> d=<demand> -> <solution>

c=[[0, 3, 2, 3, 2], [3, 0, 5, 3, 3], [2, 5, 0, 4, 5], [3, 3, 4, 0, 4], [2, 3, 5, 4, 0]] a=[[0, 1, 1, 2, 1], [1, 0, 1, 2, 3], [1, 1, 0, 2, 2], [2, 2, 2, 0, 3], [1, 3, 2, 3, 0]] d=7 -> 20
c=[[0, 1, 1, 5, 4], [1, 0, 2, 4, 2], [1, 2, 0, 1, 1], [5, 4, 1, 0, 3], [4, 2, 1, 3, 0]] a=[[0, 1, 1, 2, 2], [1, 0, 2, 4, 1], [1, 2, 0, 1, 1], [2, 4, 1, 0, 3], [2, 1, 1, 3, 0]] d=7 -> 17
c=[[0, 1, 4, 5, 4, 2, 3], [1, 0, 5, 4, 3, 3, 5], [4, 5, 0, 1, 5, 5, 5], [5, 4, 1, 0, 3, 2, 5], [4, 3, 5, 3, 0, 4, 4], [2, 3, 5, 2, 4, 0, 2], [3, 5, 5, 5, 4, 2, 0]] a=[[0, 1, 4, 2, 4, 1, 1], [1, 0, 3, 2, 2, 1, 1], [4, 3, 0, 1, 4, 5, 2], [2, 2, 1, 0, 2, 2, 3], [4, 2, 4, 2, 0, 4, 1], [1, 1, 5, 2, 4, 0, 2], [1, 1, 2, 3, 1, 2, 0]] d=10 -> 31
c=[[0, 16, 14, 10, 14, 11, 10, 4, 3, 16], [16, 0, 18, 19, 1, 6, 10, 19, 5, 4], [14, 18, 0, 2, 15, 9, 3, 14, 20, 13], [10, 19, 2, 0, 2, 10, 12, 17, 19, 22], [14, 1, 15, 2, 0, 11, 23, 25, 10, 19], [11, 6, 9, 10, 11, 0, 14, 16, 25, 4], [10, 10, 3, 12, 23, 14, 0, 11, 7, 8], [4, 19, 14, 17, 25, 16, 11, 0, 14, 5], [3, 5, 20, 19, 10, 25, 7, 14, 0, 22], [16, 4, 13, 22, 19, 4, 8, 5, 22, 0]] a=[[0, 12, 4, 2, 9, 1, 1, 3, 1, 6], [12, 0, 12, 16, 1, 2, 9, 13, 2, 3], [4, 12, 0, 2, 2, 2, 2, 10, 1, 1], [2, 16, 2, 0, 2, 1, 8, 4, 4, 2], [9, 1, 2, 2, 0, 5, 6, 23, 5, 8], [1, 2, 2, 1, 5, 0, 13, 12, 12, 1], [1, 9, 2, 8, 6, 13, 0, 9, 4, 4], [3, 13, 10, 4, 23, 12, 9, 0, 13, 1], [1, 2, 1, 4, 5, 12, 4, 13, 0, 13], [6, 3, 1, 2, 8, 1, 4, 1, 13, 0]] d=50 -> 213

Ці тестові випадки були обчислені з бібліотекою NetworkX Python .



1
Довгий час гольф потім зрозумів, що я граю невірний алгоритм, тому що не можу читати
Квінтек

Відповіді:


3

[R + lpSolve ], 201 186 149 144 байт

function(c,a,d,`^`=rep,N=ncol(c),G=diag(N),P=t(1^N),M=P%x%G+G%x%-P)lpSolve::lp(,a,rbind(M,diag(N*N)),c('=','<')^c(N,N*N),c(d,0^(N-2),-d,c))$objv

Спробуйте в Інтернеті!

Код будує таку лінійну задачу та вирішує її за допомогою lpSolveпакету:

мiнхV уVАх,уfх,усубjеcт то:хVfv,х-fх,v=0vV:v{с,т}хVfс,х-fх,с=гхVfт,х-fх,т=-гfх,бСх,бхV,уV
де:

  • V - це сукупність вершин
  • с s - вершина вершини
  • т s - цільова (або раковина) вершина
  • Ах,у - витрата потоку для краю x -> y
  • fх,у- потік краю x -> yв оптимальному рішенні
  • г - необхідний потік у мийці (тобто потреба при т і виробництво в с)
  • Сх,у - максимальна ємність кромки x -> y

Приємне, лінійне програмування :) На жаль, у більшості мов немає lpSolve... :(
Quintec

Це, на жаль, правда ... До речі, він не доступний на базі-R, це пакет ... Мені довелося попросити встановити на TIO;)
digEmAll

Чомусь я ще не знайшов короткий спосіб змінити MinCostMaxFlow, щоб стати MinCostFlow ... мій мозок смажений хаха, я б хотів, щоб була функція для цього іншими мовами, ніж математика
Квінтек

@Quintec: Ви маєте на увазі конкретну реалізацію (наприклад, певною мовою) MinCostMaxFlow?
digEmAll

Ні, алгоритм, кодований моїми руками
Quintec

1

Мова Вольфрама, 42 байти

FindMinimumCostFlow[#,1,VertexCount@#,#2]&

Тривіальний вбудований. Незабудоване рішення незабаром.


Це приходить через 6-8 тижнів? : P
Квінтек

1

Python 3 + NetworkX , 137 байт

from networkx import*
def f(g,d,z='demand'):N=len(g)**.5//1;G=DiGraph(g);G.node[0][z]=-d;G.node[N-1][z]=d;return min_cost_flow_cost(G)

Немає посилання TryItOnline, оскільки в TIO не встановлена ​​бібліотека NetworkX

Вводить графік як крайовий список з атрибутами місткості та ваги, наприклад:

[(0, 0, {'capacity': 0, 'weight': 0}), (0, 1, {'capacity': 3, 'weight': 1}), (0, 2, {'capacity': 2, 'weight': 1}), (0, 3, {'capacity': 3, 'weight': 2}), (0, 4, {'capacity': 2, 'weight': 1}), (1, 0, {'capacity': 3, 'weight': 1}), (1, 1, {'capacity': 0, 'weight': 0}), (1, 2, {'capacity': 5, 'weight': 1}), (1, 3, {'capacity': 3, 'weight': 2}), (1, 4, {'capacity': 3, 'weight': 3}), (2, 0, {'capacity': 2, 'weight': 1}), (2, 1, {'capacity': 5, 'weight': 1}), (2, 2, {'capacity': 0, 'weight': 0}), (2, 3, {'capacity': 4, 'weight': 2}), (2, 4, {'capacity': 5, 'weight': 2}), (3, 0, {'capacity': 3, 'weight': 2}), (3, 1, {'capacity': 3, 'weight': 2}), (3, 2, {'capacity': 4, 'weight': 2}), (3, 3, {'capacity': 0, 'weight': 0}), (3, 4, {'capacity': 4, 'weight': 3}), (4, 0, {'capacity': 2, 'weight': 1}), (4, 1, {'capacity': 3, 'weight': 3}), (4, 2, {'capacity': 5, 'weight': 2}), (4, 3, {'capacity': 4, 'weight': 3}), (4, 4, {'capacity': 0, 'weight': 0})]

Це версія коду для гольфу, яку я використовував для перевірки тестових випадків.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.