6

Ich bin ziemlich neu in R und ich versuche, ein Skript für das zu schreiben, was ich früher mit Solver in Excel gemacht habe. In meinen Daten unten habe ich eine Liste von Arbeitern mit den Auftragstypen A-E. Jeder Arbeiter hat ein Gehalt und eine Produktionsrate. Was ich tun soll ist, die maximale Produktion zu finden, die ich von 10 Arbeitern mit einem kumulativen Gehalt < 100.000 bekommen kann. Die Einschränkungen sind, dass ich eine genaue Summe von 10 Arbeitern benötige und ich brauche 2 von Job-Typen A-D, 1 von E und 1 von jedem Typ.Wie benutzt man R, um die besten Leute für einen Job zu finden/auszuwählen - mit Einschränkungen?

Ich habe gesucht und suchte nach einer Möglichkeit, dies mit optim, IpSolve, etc. zu tun, aber mit meinem begrenzten Wissen hatte ich nicht viel Glück.

Vielen Dank für Ihre Hilfe!

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

Ja, ein Minimum von 2. Vielen Dank! –

+0

Nur ein Gedanke: wähle (20,10) = 184756, es dauert also nicht lange, alle möglichen Kombinationen in diesem kleinen Fall zu testen. Es sei denn, das sind Hausaufgaben, und Sie müssen einen Löser benutzen. –

+0

Zum Glück sind es keine Hausaufgaben, aber die ganze Liste hat mehr als dreihundert Leute. Mein Fehler, ich hätte das im Originalbeitrag erwähnen sollen. –

Antwort

6

Verwenden lp im lpSolve Paket, um das darunter liegende ganzzahlige Programmierungsproblem zu lösen. Die ersten 5 Einschränkungen beziehen sich auf die Anzahl der A-, B-, C-, D- und E-Positionen, die 6. bezieht sich auf die Anzahl der zu wählenden Mitarbeiter und die 7. bezieht sich auf das Gesamtgehalt. Unter der Annahme, DF ist der Datenrahmen in der Frage gezeigt, dass dies versuchen:

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) 

die gibt:

> 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 

Hinweis, dass die Produktion in der Frage falsch geschrieben ist oder vielleicht war das gedacht.

ZUSÄTZLICH:

Im Hinblick auf die zweitbeste Lösung die Idee, eine Einschränkung hinzuzufügen, die die beste Lösung undurchführbar macht aber schließt andere mögliche Lösungen:

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

In diesem Fall wird die folgende erhalten die den gleichen optimalen Zielwert als die beste Lösung hat so wäre es nur so gut sein:

> 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 

es gibt auch Argumente zu lp, die es ermöglichen, mehrere Lösungen direkt zu produzieren; Die Hilfedatei erwähnt jedoch einige Fehler und es ist möglicherweise sicherer, den obigen Ansatz zu verwenden.

+0

Erstaunlich, vielen Dank! Als i-Tüpfelchen, gibt es eine Möglichkeit, die zweitbeste Lösung zu bekommen? –

+0

Frage: Ich dachte an einen Algorithmus wie: 1) Berechne eine Gütezahl, dh Produktion/Gehalt, 2) Nimm den obersten FOM-Kandidaten aus jeder benötigten Kategorie (AE), 3) fülle die verbleibenden Plätze mit dem obersten verbleibenden FOM Werte. Ist das im Wesentlichen was "lpSolve" macht? –

+0

@Derek, habe eine zweitbeste Lösung hinzugefügt. @Carl, 'lp' verwendet den Branch-and-Bound-Algorithmus. –