У меня есть решение в Python. Базовая концепция c заключается в том, что мы сортируем от наименьшего к наибольшему, выбираем тот, у которого список имеет наибольший первый элемент, а затем перемещаемся по другому списку, суммируя значения, пока у нас не появится транзакция, которая может произойти. Затем мы выполняем транзакцию и удаляем элементы. Псевдокод:
Split into two lists for overstock or understock
Sort from smallest to largest absolute value
Perform easy transactions (i.e. Overstock at one location equals understock at another)
Perform dynamic partial transactions (i.e. Allows totals to be split between multiple locations)
Вот код.
# Test data
current = [
["A", "AAA", 1, "Long", 100],
["B", "AAA", 1, "Long", 150],
["C", "AAA", 1, "Short", -250],
["D", "AAA", 1, "Long", 50],
["E", "AAA", 1, "Short", -50],
]
# Split by Long/Short
over = []
under = []
for line in current:
if line[4] > 0:
over.append(line)
else:
under.append(line)
# Sort by size of value
over = sorted(over, key=lambda x: abs(x[-1]))
under = sorted(under, key=lambda x: abs(x[-1]))
transactions = []
# Perform easy One-to-One transactions
i = 0
j = 0
while (i < len(over) and j < len(under)):
if over[i][4] == abs(under[j][4]):
transactions.append([under[j][0],over[i][0], over[i][4]])
over.remove(over[i])
under.remove(under[i])
else:
if over[i][4] > abs(under[j][4]):
j += 1
else:
i += 1
# Perform dynamic partial transactions
while len(over) > 0 and len(under) > 0:
if over[0][4] == abs(under[0][4]):
transactions.append([under[0][0],over[0][0], over[0][4]])
over.remove(over[0])
under.remove(under[0])
else:
if over[0][4] > abs(under[0][4]):
transactions.append([under[0][0],over[0][0], abs(under[0][4])])
over[0][4] -= abs(under[0][4])
under.remove(under[0])
else:
transactions.append([under[0][0],over[0][0], over[0][4]])
under[0][4] += over[0][4]
over.remove(over[0])
# Show results
for transaction in transactions:
print(transaction)
Вывод:
['E', 'D', 50]
['C', 'A', 100]
['C', 'B', 150]
Надеюсь, это поможет. Не стесняйтесь задавать любые ваши вопросы!