[PYTHON] Lösung des Planungsproblems der Krankenschwester (Schichtoptimierung) mit einem genetischen Algorithmus

Dieser Beitrag

Annahme

Krankenschwester Planungsproblem

Dies ist ein Problem, das den Arbeitsplan von Krankenschwestern bestimmt, die in medizinischen Einrichtungen wie Krankenhäusern arbeiten, und ein typisches Beispiel für das Schichtplanungsproblem ist. Aufgrund der komplizierten Schichtarbeit wie Tagschicht, Abendschicht, Nachtschicht und verschiedener Einschränkungen ist es schwierig, den Zeitplan tatsächlich zu finden.

Genetischen Algorithmus

Also, wie man sich bewirbt

Tag Mond Mond Mond Feuer Feuer Feuer Wasser Wasser Wasser Holz Holz Holz Geld Geld Geld Boden Boden Boden Tag Tag Tag
Zeitzone Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht
Mitarbeiter 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0
Mitarbeiter 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0
Mitarbeiter 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0
[0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
 1,1,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0]

Implementiert in Python / deap

Fahren wir konkret mit der Implementierung fort.

Verwendung von Deap

pip install deap

Beispielspezifikationen

Die Spezifikationen dieses Beispiels sind wie folgt.

Mitarbeiter und Schichtwünsche

Tag Mond Mond Mond Feuer Feuer Feuer Wasser Wasser Wasser Holz Holz Holz Geld Geld Geld Boden Boden Boden Tag Tag Tag
Zeitzone Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht
Erforderliche Anzahl von Personen 2 3 3 2 3 3 2 3 3 1 2 2 2 3 3 2 4 4 2 4 4
Mitarbeiter 0
Mitarbeiter 1
Mitarbeiter 2
Mitarbeiter 3
Mitarbeiter 4
Mitarbeiter 5
Mitarbeiter 6
Mitarbeiter 7
Mitarbeiter 8
Mitarbeiter 9

Zwang

Stellen Sie sicher, dass Ihre Punktzahl hoch genug ist, um die folgenden Einschränkungen zu erfüllen. Die Zahlen in Klammern sind Gewichte und stellen die Priorität der Einschränkung dar.

Codeübersicht

Punkt

Mitarbeiterdefinition

class Employee(object):
  def __init__(self, no, name, age, manager, wills):
    self.no = no
    self.name = name
    self.age = age
    self.manager = manager

    #Wille ist der Tag_Zeitzone. 1 ist Morgen, 2 ist Mittag, 3 ist Nacht.
    #Beispiel) mon_1 ist Montagmorgen
    self.wills = wills
...
#Nur am Morgen
e0 = Employee(0, "Yamada", 40, False, ['mon_1', 'tue_1', 'wed_1', 'thu_1', 'fri_1', 'sat_1', 'sun_1'])

#Mo / Mi / Fr
e1 = Employee(1, "Suzuki", 21, False, ['mon_1', 'mon_2', 'mon_3', 'wed_1', 'wed_2', 'wed_3','fri_1', 'fri_2', 'fri_3'])

#Nur an Wochenenden
e2 = Employee(2, "Sato", 18, False, ['sat_1', 'sat_2', 'sat_3', 'sun_1', 'sun_2', 'sun_3'])

#OK überall
e3 = Employee(3, "Tanaka", 35, True, ['mon_1', 'mon_2', 'mon_3',
                                     'tue_1', 'tue_2', 'tue_3',
                                     'wed_1', 'wed_2', 'wed_3',
                                     'thu_1', 'thu_2', 'thu_3',
                                     'fri_1', 'fri_2', 'fri_3',
                                     'sat_1', 'sat_2', 'sat_3',
                                     'sun_1', 'sun_2', 'sun_3'
                                    ])

...

employees = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9]

Definition der Verschiebung (Rahmen)

#Klasse, die Verschiebung darstellt
#Intern 3(Morgen, Tag und Nacht) *Der 7 ..*10 Personen=Besteht aus 210-dimensionalen Taples
class Shift(object):
  #Definition von top
  SHIFT_BOXES = [
    'mon_1', 'mon_2', 'mon_3',
    'tue_1', 'tue_2', 'tue_3',
    'wed_1', 'wed_2', 'wed_3',
    'thu_1', 'thu_2', 'thu_3',
    'fri_1', 'fri_2', 'fri_3',
    'sat_1', 'sat_2', 'sat_3',
    'sun_1', 'sun_2', 'sun_3']

  #Geschätzte Anzahl von Personen in jedem Frame
  NEED_PEOPLE = [
    2,3,3,
    2,3,3,
    2,3,3,
    1,2,2,
    2,3,3,
    2,4,4,
    2,4,4]

  def __init__(self, list):
    if list == None:
      self.make_sample()
    else:
      self.list = list
    self.employees = []

  #Zufällige Daten generieren
  def make_sample(self):
    sample_list = []
    for num in range(210):
      sample_list.append(random.randint(0, 1))
    self.list = tuple(sample_list)
...

Wertung und Gewichtung

creator.create("FitnessPeopleCount", base.Fitness, weights=(-10.0, -100.0, -1.0, -100.0, -10.0))
creator.create("Individual", list, fitness=creator.FitnessPeopleCount)

...

def evalShift(individual):
  s = Shift(individual)
  s.employees = employees

  #Unterschied zwischen der erwarteten Anzahl von Personen und der zugewiesenen Anzahl von Personen
  people_count_sub_sum = sum(s.abs_people_between_need_and_actual()) / 210.0
  #Anzahl der Zuordnungen zu Zeiten, in denen Sie sich nicht bewerben
  not_applicated_count = s.not_applicated_assign() / 210.0
  #Anzahl der Mitarbeiter mit weniger als der Hälfte der Anzahl der Aufgaben
  few_work_user = len(s.few_work_user()) / 10.0
  #Anzahl der Frames ohne Administrator
  no_manager_box = len(s.no_manager_box()) / 21.0
  #Zugewiesen an alle Morgen, Mittag und Nacht
  three_box_per_day = len(s.three_box_per_day()) / 70.0
  return (not_applicated_count, people_count_sub_sum, few_work_user, no_manager_box, three_box_per_day)

toolbox.register("evaluate", evalShift)

Geben Sie die Anzahl der Entwicklungen usw. an.

    pop = toolbox.population(n=300)
    CXPB, MUTPB, NGEN = 0.6, 0.5, 500 #Kreuzungswahrscheinlichkeit, Mutationswahrscheinlichkeit, Anzahl der Schleifen in der Evolutionsberechnung

Lauf

$ python nurse_scheduling_by_ga.py 
Die Evolution begann
Bewerten Sie 300 Personen
--0 Generation--
Bewerten Sie 245 Personen
*Parameter 1
  Min 0.242857142857
  Max 0.242857142857
  Avg 0.242857142857
  Std 2.2660056242e-08
*Parameter 2
  Min 0.247619047619
  Max 0.247619047619
  Avg 0.247619047619
  Std 9.49766396283e-09
*Parameter 3
  Min 0.0
  Max 0.0
  Avg 0.0
  Std 0.0
*Parameter 4
  Min 0.142857142857
  Max 0.142857142857
  Avg 0.142857142857
  Std 1.66600046866e-08
*Parameter 5
  Min 0.114285714286
  Max 0.114285714286
  Avg 0.114285714286
  Std 1.19267483008e-08
--1 Generation--
Bewerten Sie 235 Personen
*Parameter 1
  Min 0.238095238095
  Max 0.238095238095
  Avg 0.238095238095
  Std 2.45699769971e-08
*Parameter 2
  Min 0.228571428571
  Max 0.228571428571
  Avg 0.228571428571
  Std 2.38534966016e-08
*Parameter 3
  Min 0.1
  Max 0.1
  Avg 0.1
  Std 1.31048702444e-08
*Parameter 4
  Min 0.047619047619
  Max 0.047619047619
  Avg 0.047619047619
  Std 4.46646616171e-09
*Parameter 5
  Min 0.1
  Max 0.1
  Avg 0.1
  Std 1.31048702444e-08

(snip)

--499 Generationen--
Bewerten Sie 219 Personen
*Parameter 1
  Min 0.0333333333333
  Max 0.0333333333333
  Avg 0.0333333333333
  Std 2.98168707519e-09
*Parameter 2
  Min 0.0714285714286
  Max 0.0714285714286
  Avg 0.0714285714286
  Std 8.33000234328e-09
*Parameter 3
  Min 0.1
  Max 0.1
  Avg 0.1
  Std 1.31048702444e-08
*Parameter 4
  Min 0.0952380952381
  Max 0.0952380952381
  Avg 0.0952380952381
  Std 8.93293232343e-09
*Parameter 5
  Min 0.0428571428571
  Max 0.0428571428571
  Avg 0.0428571428571
  Std 4.56253018749e-09
--Ende der Evolution--
Die beste Person: [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1], (0.0, 0.0, 0.2, 0.047619047619047616, 0.1)
0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
0,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1
1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,1,1,0,0,1
0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0
1,1,1,1,1,1,1,1,1,0,0,1,0,1,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1
0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,1,1
0	0	0	1	0	0	0	0	0	0	0	0	0	0	0	1	0	0
0	1	0	0	0	0	1	1	0	0	0	0	1	1	1	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	1
1	0	1	0	1	1	0	0	1	0	1	0	1	0	1	0	1	1
0	0	0	0	0	1	0	0	1	0	0	1	0	0	1	0	0	0
1	1	1	1	1	1	1	1	1	0	0	1	0	1	0	0	0	0
0	0	0	0	0	0	0	0	0	0	0	0	0	1	0	0	1	1
0	1	0	0	1	0	0	1	0	0	1	0	0	0	0	0	1	0
0	0	1	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0
0	0	0	0	0	0	0	0	0	1	0	0	0	0	0	1	1	1

Ergebnis

Tag Mond Mond Mond Feuer Feuer Feuer Wasser Wasser Wasser Holz Holz Holz Geld Geld Geld Boden Boden Boden Tag Tag Tag Anzahl der Aufgaben Gewünschte Nummer Zuweisungsrate
Zeitzone Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht Morgen Mittag Nacht
Erforderliche Anzahl von Personen 2 3 3 2 3 3 2 3 3 1 2 2 2 3 3 2 4 4 2 4 4
Genehmigte Nummer 2 3 3 2 3 3 2 3 3 1 2 2 2 3 3 2 4 4 2 4 4
Unterschied 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Mitarbeiter 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 5 7 71.4%
Mitarbeiter 1 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 6 9 66.7%
Mitarbeiter 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 4 6 66.7%
[Tube]Mitarbeiter 3 0 1 0 0 1 0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 7 21 33.3%
Mitarbeiter 4 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 5 7 71.4%
[Tube]Mitarbeiter 5 1 0 1 1 1 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 8 15 53.3%
Mitarbeiter 6 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 5 9 55.6%
Mitarbeiter 7 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0 6 7 85.7%
Mitarbeiter 8 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 4 7 57.1%
[Tube]Mitarbeiter 9 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 1 1 1 7 12 58.3%
Anzahl der Administratoren 1 1 1 1 2 1 1 1 0 1 1 2 1 1 1 0 1 1 1 2 1

Am Ende

Recommended Posts

Lösung des Planungsproblems der Krankenschwester (Schichtoptimierung) mit einem genetischen Algorithmus
Suche nach einer Lösung für das N-Queen-Problem mit einem genetischen Algorithmus (2)
Suche nach einer Lösung für das N-Queen-Problem mit einem genetischen Algorithmus (1)
Lösen von Planungsproblemen für Krankenschwestern mit Kombinationsoptimierung
Lösen des N Queen-Problems mit kontinuierlicher / kombinierter Optimierung
Lösen des N Queen-Problems mit Kombinationsoptimierung
Lösen Sie das Python-Rucksackproblem mit dem Greedy-Algorithmus
Versuchen Sie, das Problem des Handlungsreisenden mit einem genetischen Algorithmus zu lösen (Theorie)
Versuchen Sie, das Problem des Handlungsreisenden mit einem genetischen Algorithmus (Python-Code) zu lösen.
Versuchen Sie, das Problem des Handlungsreisenden mit einem genetischen Algorithmus zu lösen (Ausführungsergebnis)
Lösung des Problems des Handlungsreisenden mit dem genetischen Algorithmus (GA) und seiner Bibliothek (vcopt)
Finden Sie den optimalen Wert der Funktion mit einem genetischen Algorithmus (Teil 2)
Lösen Sie das Problem der parabolischen Minimierung mit OpenMDAO
Durchsuche das Labyrinth mit dem Python A * -Algorithmus
Wie man die anfängliche Population mit einem genetischen Algorithmus unter Verwendung von DEAP fixiert
Lösen des Irisproblems mit scikit-learn ver1.0 (logistische Regression)
[Python] Versuchen Sie, die FX-Systolenparameter mit einem genetischen Algorithmus zu optimieren
Ich habe versucht, das Problem der Kombinationsoptimierung mit Qiskit zu lösen
Eine Geschichte über den Umgang mit dem CORS-Problem
Ein Memo, das das Rucksackproblem mit der gierigen Methode löste
Ich habe versucht, "einen genetischen Algorithmus (GA) in Python zu implementieren, um das Problem des Handlungsreisenden (TSP) zu lösen".
Lösen des Labyrinths mit Python-Ergänzung zu Kapitel 6 der Algorithmus-Kurzreferenz-
Ich wollte das ABC164 A ~ D-Problem mit Python lösen
Fehler mit pip: Beim Bestätigen des SSL-Zertifikats ist ein Problem aufgetreten
Lösen Sie das Python-Rucksackproblem mit der Branch-and-Bound-Methode
Lösen von Rucksackproblemen mit den OP-Tools von Google - Üben der Grundlagen von Kombinationsoptimierungsproblemen
Ich habe versucht, das Schichtplanungsproblem mit verschiedenen Methoden zu lösen
Finden Sie den optimalen Wert der Funktion mit einem genetischen Algorithmus (Teil 1)
Lösen Sie Teilsummenprobleme mit der vollständigen Suche in Python
Lösen Sie ein 4-Farben-Problem mit Kombinationsoptimierung
Bereiten Sie die Straße mit Kombinationsoptimierung
Spieltheorie mit Kombinationsoptimierung lösen
Berechnen Sie die kürzeste Route eines Diagramms mit der Dyxtra-Methode und Python