6

Jestem całkiem nowy dla R i próbuję napisać skrypt do tego, co robiłem z Solverem w Excelu. W moich danych poniżej mam listę pracowników z typami pracy A-E. Każdy pracownik ma wynagrodzenie i wskaźnik produkcji. To, co chcę zrobić, to znaleźć maksymalną produkcję, jaką mogę uzyskać od 10 pracowników z łączną pensją < 100 000. Ograniczenia są takie, że potrzebuję dokładnie 10 pracowników i potrzebuję 2 z kategorii stanowisk A-D, 1 z E i 1 każdego rodzaju.Jak używać R do rozwiązywania/wybierania najlepszych ludzi do pracy - z ograniczeniami?

Szukałem i szukałem sposobu na zrobienie tego przy pomocy optymalizacji, IpSolve itp., Ale przy mojej ograniczonej wiedzy nie miałem szczęścia.

Dziękuję za pomoc!

Name Pos Salary Producton 
Joe  A 12001 13.1 
Jim  A 17753 23.5 
Jill A 11447 14.8 
Brian A 11447 14.8 
Sally B 2171 1.2 
Nancy B 4537 2.1 
Francis B 2840 1.8 
Ace  B 2840 1.8 
Bill C 3818 1.6 
Ted  C 11447 0.1 
Henry C 2000 1.1 
Kyle C 3818 1.6 
Sam  D 11447 0.1 
Trevor D 2000 1.1 
John D 4317 11.7 
Jerome D 2000 1.1 
Rebecca E 3818 1.6 
Sunny E 11447 0.1 
Britt E 2000 1.1 
Sara E 4317 11.7 
+0

Tak, minimum 2. Dziękujemy! –

+0

Po prostu myśl: wybierz (20,10) = 184756, więc przetestowanie każdej możliwej kombinacji w tym małym etui nie potrwa długo. O ile, oczywiście, nie jest to praca domowa i * musisz * użyć solver. –

+0

Na szczęście nie jest to praca domowa, ale pełna lista zawiera ponad trzysta osób. Mój błąd, powinienem wspomnieć o tym w oryginalnym poście. –

Odpowiedz

6

Zastosowanie lp w pakiecie lpSolve rozwiązać podstawowy problem programowania całkowitą. Pierwsze 5 ograniczeń dotyczy odpowiednio liczby stanowisk A, B, C, D i E, szósta to liczba pracowników do wyboru, a siódma to łączna pensja. Zakładając DF jest ramka danych przedstawione w pytaniu spróbuj tego:

library(lpSolve) 

obj <- DF$Prod 
con <- rbind(t(model.matrix(~ Pos + 0, DF)), rep(1, nrow(DF)), DF$Salary) 
dir <- c(">=", ">=", ">=", ">=", ">=", "==", "<") 
rhs <- c(2, 2, 2, 2, 1, 10, 100000) 

result <- lp("max", obj, con, dir, rhs, all.bin = TRUE) 

co daje:

> result 
Success: the objective function is 84.7 
> DF[result$solution == 1, ] 
    Name Pos Salary Producton 
2  Jim A 17753  23.5 
3 Jill A 11447  14.8 
4 Brian A 11447  14.8 
6 Nancy B 4537  2.1 
8  Ace B 2840  1.8 
9 Bill C 3818  1.6 
12 Kyle C 3818  1.6 
14 Trevor D 2000  1.1 
15 John D 4317  11.7 
20 Sara E 4317  11.7 

Należy pamiętać, że produkcja jest błędnie w pytaniu czy może że był przeznaczony.

DODANO:

Odnośnie drugiego najlepszego rozwiązania Chodzi o to, aby dodać ograniczenie co sprawia, że ​​najlepszym rozwiązaniem jest nieosiągalne, ale nie wyklucza innych potencjalnych rozwiązań:

con2 <- rbind(con, result$solution) 
dir2 <- c(dir, "<=") 
rhs2 <- c(rhs, 9) 
result2 <- lp("max", obj, con2, dir2, rhs2, all.bin = TRUE) 

W tym przypadku pojawia się następujący który ma taką samą optymalną wartość obiektywną, że najlepszym rozwiązaniem byłoby więc tak dobre: ​​

> result2 
Success: the objective function is 84.7 
> DF[result2$solution == 1, ] 
    Name Pos Salary Producton 
2  Jim A 17753  23.5 
3 Jill A 11447  14.8 
4 Brian A 11447  14.8 
6 Nancy B 4537  2.1 
8  Ace B 2840  1.8 
9 Bill C 3818  1.6 
12 Kyle C 3818  1.6 
15 John D 4317  11.7 
16 Jerome D 2000  1.1 
20 Sara E 4317  11.7 

Istnieją także argumenty lp, które pozwalają na bezpośrednią produkcję wielu rozwiązań; jednak plik pomocy wspomina o niektórych błędach i może być bezpieczniej zastosować powyższe podejście.

+0

Niesamowite, dziękuję bardzo! Jak wisieć na torcie, czy istnieje sposób na uzyskanie drugiego najlepszego rozwiązania? –

+0

Pytanie: Zastanowiłem się nad algorytmem, takim jak: 1) obliczyć wartość merytoryczną, tj. Produkcja/Wynagrodzenie, 2) Zdobąć najwyższego kandydata FOM z każdej wymaganej kategorii (AE), 3) wypełnić pozostałe miejsca z pozostałej części FOM wartości. Czy to właśnie robi 'lpSolve'? –

+0

@Derek, Dodano drugie najlepsze rozwiązanie. @Carl, 'lp' używa algorytmu odgałęzienia i powiązania. –

Powiązane problemy