Как подобрать переменную, состоящую из 18 элементов? Переменная должна удовлетворять нескольким условиям
Суть задачи - найти минимальную допустимую итоговую цену. Для этого нужно подобрать переменную из 18 элементов. Как это сделать?
#вводные:
prices = [124200 91000 124200 67500 96500 70500 114400 83200 75000 57600
45600 30200 30200 30000 30000 30000 30000 30000]
budget_split = [0.20419895 0.2017904 0.19960125 0.00869134 0.02313767 0.00428459
0.21892543 0.04802103 0.05803968 0.01338142 0.00342614 0.00233065
0.00138871 0.00095321 0.0017216 0.00311734 0.0023248 0.00466578]
aff = [0.93972462 0.82758114 0.94904232 0.55632674 1.1949657 0.43475197
0.92143587 1.18005534 1.02297964 1.71846277 1.2283596 0.58841192
2.20166106 0.97470404 1.2394015 0.65835301 0.58835556 1.93003018]
#prices - цены, Const
#budget_split- процентное распределение бюджета
#aff - спец. коэф, Const
#prices,aff,budget_split- каждый состоит из 18 элементов
#Итоговая цена определяется по формуле:
n = budget_split
m = (1 / (prices / aff))
price_general = sum(n) / sum(n * m)
#При использовании базового budget_split итоговая цена составит 103300.99270623508
#Нужно подобрать все возможные вариации budget_split_new в рамках заданных условий и подставить в уравнение.
budget_split_new = (x0,x1,x2,x3,...,x16,x17)
#При этом есть 3 обязательных условия для подбираемого budget_split_new:
#1)
#условия для сумм некоторых элементов budget_split_new:
#x0+x1+x2+x3+x4+x5+x16+x17 = 0.64869478 #это первые 6 элементов и последние 2
#x0+x1+x2+x6 = 0.82451603
#условие для суммы всех элементов budget_split_new:
#sum(budget_split_new) = 1
#2)В то же время, каждый из 18 элементов budget_split_new находится в заданном диапазоне (+-50% от соответствующих значений budget_split)
#0.001 – это шаг перебора возможных вариантов
x0 = np.array(np.arange((budget_split[0] * 0.5), (budget_split[0] * 1.5), 0.001))
x1 = np.array(np.arange((budget_split[1] * 0.5), (budget_split[1] * 1.5), 0.001))
x2 = np.array(np.arange((budget_split[2] * 0.5), (budget_split[2] * 1.5), 0.001))
x3 = np.array(np.arange((budget_split[3] * 0.5), (budget_split[3] * 1.5), 0.001))
x4 = np.array(np.arange((budget_split[4] * 0.5), (budget_split[4] * 1.5), 0.001))
x5 = np.array(np.arange((budget_split[5] * 0.5), (budget_split[5] * 1.5), 0.001))
x6 = np.array(np.arange((budget_split[6] * 0.5), (budget_split[6] * 1.5), 0.001))
x7 = np.array(np.arange((budget_split[7] * 0.5), (budget_split[7] * 1.5), 0.001))
x8 = np.array(np.arange((budget_split[8] * 0.5), (budget_split[8] * 1.5), 0.001))
x9 = np.array(np.arange((budget_split[9] * 0.5), (budget_split[9] * 1.5), 0.001))
x10 = np.array(np.arange((budget_split[10] * 0.5), (budget_split[10] * 1.5), 0.001))
x11 = np.array(np.arange((budget_split[11] * 0.5), (budget_split[11] * 1.5), 0.001))
x12 = np.array(np.arange((budget_split[12] * 0.5), (budget_split[12] * 1.5), 0.001))
x13 = np.array(np.arange((budget_split[13] * 0.5), (budget_split[13] * 1.5), 0.001))
x14 = np.array(np.arange((budget_split[14] * 0.5), (budget_split[14] * 1.5), 0.001))
x15 = np.array(np.arange((budget_split[15] * 0.5), (budget_split[15] * 1.5), 0.001))
x16 = np.array(np.arange((budget_split[16] * 0.5), (budget_split[16] * 1.5), 0.001))
x17 = np.array(np.arange((budget_split[17] * 0.5), (budget_split[17] * 1.5), 0.001))
#Что я пробовал
#1) Сразу нашёл способ решения через itertools, но он не подойдёт.
z=m[0:4] #сделал из m список из 4х элементов
A = np.array(np.arange(0, 1, 0.05))
for i in itertools.combinations_with_replacement(A, 4):
n = np.array(i)
if budget_split[0]*0.5<=n[0]<=budget_split[0]*1.5\
and sum(n)==1\
and (n[0]+n[1])==0.4\
and (n[0]+n[3]==0.5):
y = sum(n) / sum(n * z)
print(n)
print(y)
#Для примера решение для n из 4х элементов с шагом 0.05 - и он срабатывает.
#А нужно подобрать возможные n из 18 элементов с шагом 0.001 - и тут случается неудача.
#Если я правильно понял, перебираемых вариантов получается слишком много - в результате инструмент бесконечно что-то делает, но ничего не показывает.
#Если указать условия, ситуация не облегчится.
#2) пытался подобрать n через 18-тикратные вложения (для каждого из 18 элементов):
for i0 in itertools.combinations_with_replacement(x0, 1):
d0 = np.array(i0)
for i1 in itertools.combinations_with_replacement(x1, 1):
d1 = np.array(i1)
и т.д.
#работает немногим лучше, чем itertools. Но как мне тут сказали, так делать глупо.
#вдобавок, стоит добавить условия для сумм некоторых элементов - компьютер погружается в вечные вычисления.
#Пожалуйста, подскажите, что я упускаю?
#есть ли способ выполнить данную задачу оптимально?
#возможно ли решить её используя Пайтон? или нужно что-то другое? потому что за Пайтон я взялся только из-за данной задачи :|.
#Если есть ссылки на полезную инфу - буду рад.
#Если понадобятся уточнения по условиям - пишите.
#Заранее Благодарю.
Ответы (1 шт):
Не было сил читать какие-то комментарии к какой-то программе с описанием мук творчества ее автора. Но из того, что удалось понять, бегло просмотрев простыню каких-то фрагментов какого-то кода могу предположить, что автор пытается изобрести велосипед, который называется "задача линейного программирования" и для решения которой в Python и библиотеке scipy существует чудесная функция scipy.stats.linregress. И извращаться с восемнадцатикратным (!!!! - первый раз в своей достаточно долгой программистской карьере вижу такое "чудо") вложением цикла не надо.
Если же я ошибся и это не линейное программирование, хотелось бы услышать от автора, чем же его задача отличается от этой классической постановки.