2016-09-02 1 views
0

В настоящее время я пытаюсь работать на какой-то код, который я надеюсь, будет в состоянии сделать две вещи для данных, выглядит следующим образом (около ~ 100 наблюдений):Как создать уникальные комбинации случаев, чтобы максимизировать значение при минимизации другого?

Lines <- " key  error money 
1 7224 0.5500000 2483118 
2 7223 0.5200000 2451469 
3 7222 1.6600000 2425693 
4 7247 0.6400000 2324070 
5 7256 0.4400000 1785569 
6 7248 0.2541168 1476720" 
DF <- read.table(text = Lines) 

Я хочу, чтобы написать функцию, которая будет создайте различные комбинации «ключа» (возможно, с возможностью порога для n случаев), чтобы максимизировать «деньги» (возможно, в произвольной сумме, скажем> = 50 000 или < = 30 000) при минимизации суммы «ошибки». Хороший способ подумать о том, что я хочу создавать различные портфолио этих ключей «на лету».

Я все еще как-то новичок R, поэтому я понимаю, что это может быть сложная функция - я бы хотел, чтобы вы начали, но я тоже доволен полным объяснением. Спасибо!

+0

Как сочетаются различные ключи? И как сочетаются соответствующие ошибки и деньги? Или посредством * «комбинаций ключа» * вы имеете в виду * «значения ключа» *? – Gregor

+0

@ Gregor Что я имел в виду, так это то, что комбинациями будут различные комбинации случаев с помощью 'key', суммы которых' error' и 'money' будут минимизированы и максимизированы для установки пороговых значений. @ZheyuanLi благодарим вас за отзыв! Я начал смотреть на «combn», и это абсолютно лучшее место для начала. Я подозреваю, что мне придется использовать часть «FUN = x», чтобы делать то, что я хочу. – heesemonster

+0

С этим пояснением, похоже, у вас есть проблема оптимизации [htps://en.wikipedia.org/wiki/Linear_programming]. Если вы ищете вокруг SO или Интернета, есть несколько пакетов, которые разрешат вам это. – Gregor

ответ

3

Если проблема заключается в том, чтобы найти подмножество строк, сумма ошибок которых минимизирована при условии, что сумма денег больше или равна некоторой известной константе M, тогда она может быть выражена как 0-1 целочисленное линейное программирование проблема:

минимизировать error'x субъекту money'x> = М и х представляет собой вектор 0 и 1.

в терминах R код:

library(lpSolve) 
M <- 4000000 
res <- lp("min", DF$error, t(DF$money), ">=", M, all.bin = TRUE) 

res 
## Success: the objective function is 0.96 

DF$key[res$solution == 1] 
## [1] 7223 7256 

N Лучшие осуществимые решения посредством num.bin.solns аргумента

Предлагаемое решение называется осуществимо, если он удовлетворяет ограничениям. Чтобы получить N наилучших возможных решений, должно работать следующее, но, похоже, это немного неправильно. ?lp действительно предупреждает об этом. Было бы целесообразно попробовать его на вашей проблеме, если он действительно работает.

N <- 3 
res <- lp("min", DF$error, t(DF$money), ">=", M, all.bin = TRUE, 
      num.bin.solns = N, use.rw = TRUE) 

N Лучшие осуществимые решения посредством режущих плоскостей

Еще одна возможность для N лучших возможных решений является то, что для решения Ith отрезать первые I-1 решений, добавив ограничение, что исключает их и повторно -run:

res <- list(objval = 0) 
N <- 3 # no of solutions desired 

for(i in 1:N) { 
    res <- lp("min", DF$error, rbind(DF$money, DF$error), ">=", c(M, res$objval * 1.0001), 
      all.bin = TRUE) 
    print(res) 
    print(DF$key[res$solution == 1]) 
} 

даяние:

Success: the objective function is 0.96 
[1] 7223 7256 
Success: the objective function is 0.99 
[1] 7224 7256 
Success: the objective function is 1.07 
[1] 7224 7223 

Одно из предостережений заключается в том, что этот метод будет возвращать только одно из множества возможных решений, которые дают одно и то же объективное значение (или объективные значения очень близко друг к другу). Например, если бы было две комбинации, у которых было объективное значение 0,96, то первая итерация цикла найдет одну из них, а вторая итерация будет искать объективные значения> = 0,96 * 1,0001, следовательно, она устранит их оба из дальнейшее рассмотрение.

Примечание: вход DF воспроизводимой форма:

Lines <- " key  error money 
1 7224 0.5500000 2483118 
2 7223 0.5200000 2451469 
3 7222 1.6600000 2425693 
4 7247 0.6400000 2324070 
5 7256 0.4400000 1785569 
6 7248 0.2541168 1476720" 
DF <- read.table(text = Lines) 
+0

Это в основном это - и я ценю ясность, что это иллюстрирует. Мое намерение состояло в том, чтобы не находить подмножества строк, а находить различные возможные комбинации строк, чтобы иметь опции/выбор этих «ключевых» портфелей. Тем не менее, это потрясающий старт, как заявил Грегор, поскольку я не знал правильной терминологии (линейное программирование). – heesemonster

+1

См. Дополнительную информацию, добавленную к сообщению. –