Программирование алгебраического уравнения

в другом посте MSN дал мне хорошее руководство по решению моей проблемы с алгеброй (Расчет цены предложения от общая стоимость). Теперь, несмотря на то, что я могу вычислить это вручную, я полностью застрял в том, как написать это в псевдокоде или коде. Кто-нибудь может дать мне быстрый намек? Кстати, я хочу рассчитать ставку с учетом конечной стоимости.

usage cost(bid) = PIN(bid*0.10, 10, 50)
seller cost(bid) = bid*.02
added cost(bid) = PIN(ceiling(bid/500)*5, 5, 10) + PIN(ceiling((bid - 1000)/2000)*5, 0, 10)
storing cost(bid) = 100
So the final cost is something like:

final cost(bid) = PIN(bid*.1, 10, 50) + pin(ceiling(bid/500)*5, 5, 20) + PIN(ceiling((bid - 1000)/2000)*10, 0, 20) + bid*.02 + 100 + bid
Solve for a particular value and you're done.

For example, if you want the total cost to be $2000:

2000 = PIN(bid*.1, 10, 50) + pin(ceiling(bid/500)*5, 5, 10) + PIN(ceiling((bid - 1000)/2000)*5, 0, 10) + bid*.02 + 100 + bid.
Bid must be at least > 1500 and < 2000, which works out nicely since we can make those PIN sections constant:

2000 = 50 + 10 + 5 + 100 + bid*1.02
1835 = bid*1.02
bid = 1799.0196078431372549019607843137

person fbernier    schedule 13.03.2009    source источник
comment
Если бы вы использовали Haskell, ваш псевдокод потребовал бы очень незначительных изменений, прежде чем он стал бы настоящим, работающим кодом :) Имена функций не могут иметь пробелов, а параметры не нуждаются в скобках.   -  person Daniel Pratt    schedule 13.03.2009
comment
Вы можете явно указать, что хотите рассчитать ставку с учетом конечной стоимости (т.е. вам нужна обратная функция final cost()). Не все будут читать ваш оригинальный вопрос.   -  person mweerden    schedule 13.03.2009
comment
@mweerden: хороший звонок; Я полностью пропустил то, что он пытался сделать в первый раз (и я даже прочитал исходный вопрос :-/)   -  person Daniel LeCheminant    schedule 13.03.2009
comment
мой плохой для путаницы, мой вопрос, вероятно, был плохо сформирован. Спасибо за ответ, теперь я лучше понимаю.   -  person fbernier    schedule 13.03.2009


Ответы (2)


Функция упрощается до:

                  / 1.02 * bid + 115   bid <   100
                  | 1.12 * bid + 105   bid <=  500
final cost(bid) = | 1.02 * bid + 160   bid <= 1000
                  | 1.02 * bid + 165   bid <= 3000
                  \ 1.02 * bid + 170   otherwise

Если рассматривать каждую часть как отдельную функцию, то их можно инвертировать:

bid_a(cost) = (cost - 115) / 1.02
bid_b(cost) = (cost - 105) / 1.12
bid_c(cost) = (cost - 160) / 1.02
bid_d(cost) = (cost - 165) / 1.02
bid_e(cost) = (cost - 170) / 1.02

Если вы подставите свою стоимость в каждую функцию, вы получите оценочное значение ставки для этого диапазона. Вы должны убедиться, что это значение действительно находится в допустимом диапазоне этой функции.

Пример:

cost = 2000

bid_a(2000) = (2000 - 115) / 1.02 = 1848  Too big! Need to be < 100
bid_b(2000) = (2000 - 105) / 1.12 = 1692  Too big! Need to be <= 500
bid_c(2000) = (2000 - 160) / 1.02 = 1804  Too big! Need to be <= 1000
bid_d(2000) = (2000 - 165) / 1.02 = 1799  Good. It is <= 3000
bid_e(2000) = (2000 - 170) / 1.02 = 1794  Too small! Need to be > 3000

Just to check:

final cost(1799) = 1.02 * 1799 + 165 = 2000   Good!

Поскольку исходная функция строго возрастает, самое большее одна из этих функций даст приемлемое значение. Но для некоторых входов ни один из них не даст хорошего значения. Это связано с тем, что исходная функция перескакивает через эти значения.

final cost(1000) = 1.02 * 1000 + 160 = 1180
final cost(1001) = 1.02 * 1001 + 165 = 1186

Таким образом, ни одна функция не даст приемлемого значения, например, для cost = 1182.

person Markus Jarderot    schedule 13.03.2009
comment
Ты опередил меня на 32 секунды! Ваше объяснение, вероятно, немного яснее, и просто вычислить все значения вместо того, чтобы сначала выяснить одну или две наиболее важные функции, вероятно, также проще. +1 - person mweerden; 13.03.2009
comment
Один нюанс: вы написали bid вместо cost в определениях bid_X. - person mweerden; 13.03.2009

Из-за использования PIN и ceiling я не вижу простого способа инвертировать вычисление. Предполагая, что bid имеет фиксированную точность (я думаю, два десятичных знака после точки), вы всегда можете использовать двоичный поиск (поскольку функции монотонны).

Редактировать: подумав еще немного, я заметил, что, взяв x = bid*1.02 + 100, мы получаем, что окончательные затраты находятся между x + 15 (исключительно) и x + 70 (включительно) (т.е. x+15 < final cost < x+70). Учитывая размер этого диапазона (70-15=55) и тот факт, что специальные значения (см. примечание ниже) для bid различаются больше, чем это, вы можете взять x+15 = final cost и x+70 = final cost, получить правильные случаи/значения использования и дополнительные затраты и просто решить это уравнение (в котором больше нет ни PIN, ни ceiling).

Для иллюстрации пусть окончательная стоимость будет 222. Из x+15 = 222 следует, что bid = 107/1.02 = 104.90. Тогда у нас есть затраты на использование, равные bid*0.1, и дополнительные затраты, равные 5. Другими словами, мы получаем final cost = bid*0.1 + bid*0.02 + 5 + 100 + bid = bid*1.12 + 105 и, следовательно, bid = (222-105)/1.12 = 104.46. Поскольку это значение bid означает, что были взяты правильные значения для использования и дополнительных затрат, мы знаем, что это решение.

Однако если бы мы сначала посмотрели на x+70 = 222, то получили бы следующее. Сначала мы получаем, что для этого предположения, что bid = 52/1.02 = 50.98. Это означает, что затраты на использование составляют 10, а дополнительные затраты составляют 5. Итак, мы получаем final costs = 10 + bid*0.02 + 5 + 100 + bid = bid*1.02 + 115 и, следовательно, bid = (222-115)/1.02 = 104.90. Но если bid равно 104.90, то затраты на использование составляют не 10, а bid*0.1, так что это неправильное решение.

Надеюсь, я объяснил это достаточно ясно. Если нет, пожалуйста, дайте мне знать.

N.B.: Под специальными значениями я подразумеваю те, для которых изменяется функция, определяющая значения использования и добавленных затрат. Например, для стоимости использования эти значения равны 100 и 500: ниже 100 используется 10, выше 500 используется 50, а между ними используется bid*0.1.

person mweerden    schedule 13.03.2009
comment
отличное объяснение. Спасибо за ваше время! Грустно то, что MizardX сделал идеальный .. :P - person fbernier; 13.03.2009
comment
Без проблем. Я просто поплачу неделю, а потом, наверное, обо всем забуду. ;) - person mweerden; 13.03.2009