Смешанный цикл целочисленного программирования

У меня есть смешанная целочисленная программа с 25 ограничениями с тремя переменными нижнего индекса. Существует два типа переменных: одна целая, а другая двоичная. Целочисленные переменные называются Axyz, а бинарные — Bxyz. Вот моя формулировка:

цель A111 + A112 + A113 + A211 + A212 + A213 + ... A252525 ‹-- Проблема в последнем. Я не могу так выразиться. Поэтому мне нужно было бы изменить их все на трехзначный индекс для одного индекса. Я имею в виду, что A111 становится A001001001, а A252525 становится A025025025, чтобы компилятор мог его прочитать.

ограничения: 1-е ограничение A111 + 90 B111 ‹= 0 A112 + 90 B112 ‹= 0
Здесь будет та же проблема, что и с функцией оптимизации. И как мне сделать вывод этого ограничения.

2-е ограничение: A111 + A112 + A113 + A211 + A212 + A213 + ... A252525 >= 1000 Сделать вывод. Как это закодировать?

Единственный код, который у меня есть, предназначен для цели, и он работает только частично из-за проблемы с A252525. Вот:

from itertools import product

num = "".join(map(str, range(1, 25)))
l = map(lambda x: 'A' + x, (map('1'.join, product(num, num))))

print (" + ".join(l))

Если вы запустите это, вы увидите, что оно начинает повторяться после A119 из-за диапазона. Чтобы понять, чего я хочу, вы должны запустить код.

Я хочу, чтобы результат выглядел точно так же, как показано ниже. И, очевидно, эти ... находятся там, где я этого хочу. На выходе на самом деле будет все, что между ними.

A111 + A112 + A113 + A211 + A212 + A213 + ... A252525
A111 + 90 B111 <= 0 
A112 + 90 B112 <= 0 ... A252525 + 90 B252525 <= 0
A111 + A112 + A113 + A211 + A212 + A213 + ... A252525 >= 1000

ОБНОВЛЕНО:

Вот точный результат, который я хочу:

A010101 + A010102 + A010103 + A010104 + A010105 + A010106 + A010107 + A010108 + A010109 + A010110 + A020101 + A020102 + A020103 + A020104 + A020105 + A020106 + A020107 + A020108 + A020109 + A020110 + A030101 + A030102 + A030103 + A030104 + A030105 + A030106 + A030107 + A030108 + A030109 + A030110 + A010201 + A010202 + ....... + A030210

x представляет день недели (мы предполагаем, что это 3 дня)
y представляет неделю (мы предполагаем, что 2 недели)
z представляет продавца (мы предполагаем, что 10 продавцов)

Это как сказать, что в 1-й день недели 1-й продавец 1 работает и так далее. В выводе, который я хочу, как упоминалось ранее, есть три индекса; xyz. Таким образом, в выводе, который мне нужен, каждый из этих индексов представляет первые два, вторые два и третьи два числа соответственно. Например: для первого члена x равно 01, y равно 01 и z равно 01, а для последнего члена x равно 03, y равно 02 и z равно 10. Я забыл упомянуть, что я хотите, чтобы пользователь ввел значения для x, y и z. Поскольку я хочу, чтобы пользователь ввел x=3,y=2 и z=10 (это то, что представляет последний термин). Я предполагаю, что так оно и будет. «y» 02 начнется только после того, как будут завершены все 01 для «y», что будет A030110. См. это в примере вывода.

Тогда для 1-го набора ограничений это должно быть похоже на:

A010101 + 90 B010101 <= 0
A010102 + 90 B010102 <= 0 

и это будет продолжаться для каждого термина в цели.

Не беспокойтесь о втором наборе ограничений. И вам не нужно знать, что означают ограничения. Здесь вам не нужно знать, что это значит.


person Ted111    schedule 03.03.2017    source источник


Ответы (1)


Я до сих пор не очень понимаю, какова цель того, что вы делаете.

В любом случае, это следующее приведет к точному выводу, который вы хотите. Мне не нравится, как permutations() жестко закодирован, и это хак, но он производит перестановки цифр в том порядке, в котором вы хотели.

def permutations(*args):
    assert len(args) == 3
    for y in args[1]:
        for x in args[0]:
            for z in args[2]:
                yield ''.join([x, y, z])

two_digit_string = lambda x: '{:02d}'.format(x)

NUM_DOW, NUM_WEEK, NUM_SALESMEN = 3, 2, 10
dows = tuple(two_digit_string(x) for x in range(1, NUM_DOW+1))
weeks = tuple(two_digit_string(x) for x in range(1, NUM_WEEK+1))
salesmen = tuple(two_digit_string(x) for x in range(1, NUM_SALESMEN+1))

l = ('A'+''.join(digits) for digits in permutations(dows, weeks, salesmen))
print(' + '.join(l))

Выход:

A010101 + A010102 + A010103 + A010104 + A010105 + A010106 + A010107 + A010108 + A010109 + A010110 +
A020101 + A020102 + A020103 + A020104 + A020105 + A020106 + A020107 + A020108 + A020109 + A020110 +
A030101 + A030102 + A030103 + A030104 + A030105 + A030106 + A030107 + A030108 + A030109 + A030110 +
A010201 + A010202 + A010203 + A010204 + A010205 + A010206 + A010207 + A010208 + A010209 + A010210 +
A020201 + A020202 + A020203 + A020204 + A020205 + A020206 + A020207 + A020208 + A020209 + A020210 +
A030201 + A030202 + A030203 + A030204 + A030205 + A030206 + A030207 + A030208 + A030209 + A030210
person martineau    schedule 04.03.2017
comment
Это ничего не делает. Он просто запускает код. Выхода нет вообще. - person Ted111; 05.03.2017
comment
Есть вызов функции print(), который будет отображать что-то вроде того, что показано. Если нет, вы что-то изменили. - person martineau; 05.03.2017
comment
Я ничего не изменил. Вы запустили этот код, и он у вас сработал? - person Ted111; 05.03.2017
comment
Да, именно так был сгенерирован результат, показанный в моем ответе. Просто сделал это снова (используя Python 2.7.13). Однако, похоже, ничего не происходит при запуске с Python 3.6.0. Что вы используете? - person martineau; 05.03.2017
comment
Для Python 3.x используйте num = list(map(lambda x: format(x, '02d'), range(1, 26))) - person martineau; 05.03.2017
comment
Да сэр. Вот что это было. Я использую питон 3.6 - person Ted111; 05.03.2017
comment
Как и в моем вопросе, как бы я сделал 1-е ограничение с этим неравенством. Итак, A111 + 90 B111 <= 0 ‹-- это первая строка, вторая строка будет следующей, и так далее для остальных. Но все они на разных линиях. - person Ted111; 05.03.2017
comment
Извините, не понимаю, что вы хотите. О каких вы говорите? Что такое ограничение? - person martineau; 05.03.2017
comment
Вывод по-прежнему неверный. В цели нам нужны A010101 + A010102. Это нормально до A010125 на выходе, но после этого должно быть A020101, и у вас есть A010201. И я хочу, чтобы он поднялся до A050425. - person Ted111; 05.03.2017
comment
Именно так работает функция product(). Вы можете проверить эквивалентный код Python для него в документации. Используя это и мой ответ в качестве примера, возможно, вы сейчас сами это поймете. - person martineau; 05.03.2017
comment
Только один последний вопрос. Что такое num,num,num в коде. Что он печатает? - person Ted111; 05.03.2017
comment
Это три вещи, которые product() производят во всех перестановках. - person martineau; 05.03.2017
comment
Я сбит с толку. Мне придется добавить намного больше в ваш код, чтобы делать то, что я хочу. Это вернуться к исходной точке. Я оказался там, где был до того, как ты мне помог. Я был бы признателен, если бы вы могли мне помочь - person Ted111; 05.03.2017
comment
Я работаю над ответом на другой вопрос в данный момент. Возможно, вы могли бы отредактировать свой вопрос и объяснить, какие именно входы и выходы вам нужны. Я сильно подозреваю, что упоминание об ограничениях не дает много информации (во всяком случае, большинству людей) в отношении написания некоторого кода для выполнения задачи. - person martineau; 05.03.2017
comment
Хорошо. Я максимально изменю вопрос. Спасибо - person Ted111; 05.03.2017
comment
Как вы думаете, вы могли бы также сказать мне, как сделать 1-е ограничение? - person Ted111; 07.03.2017
comment
Вероятно. Чтобы было ясно: вы просто хотите вывести отдельные строки с A111 + 90 B111 <= 0, за которыми следует A112 + 90 B112 <= 0 последовательно до A242424 + 90 B242424 <= 0 и, наконец, A252525 + 90 B252525 <= 0? Во-первых, кажется, что они должны быть в форме что-то вроде A111 + 90 * B111 <= 0, чтобы быть допустимыми условными выражениями Python. Кроме того, как насчет двухзначных индексов? - person martineau; 07.03.2017
comment
На самом деле, я прокомментирую здесь через несколько дней и дам вам знать об этом. - person Ted111; 07.03.2017