Spyder - Python - Lineare Optimierung ( Snytax Error / expected an indented block)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

Hallo zusammen bin neu hier und auch neu im programmieren.
Es geht um eine lineare Optimierungsaufgabe, den Code habe ich fertig.
Allerdings bekomme ich beim ausführen immer einen Fehler. Code als Screenshot : https://gyazo.com/2cea92bd95e5c8ec130168a08feb178c

Entweder meckert er mit diesem Fehler IndentationError: expected an indented block ,
wenn ich dann Leerzeichen vor bestimmten Zeilen setze ist dieser Fehler weg, dann erscheint aber
ein neuer und zwar ein Syntax Error. Bitte um Hilfe :(




Nochmal der Code :

from gurobipy import *

def solve(zutaten, preis, alkohol, fruchtanteil, kalorien, minAlkohol, maxAlkohol, minFruchtanteil, maxKalorien, minVolumen):
# Modell erzeugen:
model = Model("Cocktailmischung")

# Variablen erzeugen: Zunaechst leeres Dictionary.
z = {}

# Alle Variablen der Liste durchlaufen.
for zutat in zutaten:
# Fuer jede Zutat wird die Variable "x_ZUTAT" angelegt.
z[zutat] = model.addVar(name = ("z_" + zutat), obj = preis[zutat])

# Variablen dem Modell bekannt machen.
model.update()

# Erste Nebenbedingung:
# Bedeutung: Volumen muss mindestens <minVolumen> sein.
# Ungleichung: "Summe aller Variablen >= minVolumen"

model.addConstr(quicksum(z[zutat] for z in zutaten) >= minVolumen )

# Zweite Nebenbedingung:
# Bedeutung: Alkoholgehalt des Cocktails darf maximal <maxAlkohol> betragen
# Ungleichung: "Summe aller (Variablen * jeweiliger Alkoholgehalt der Variable ) <= maxAlkohol * Summe aller Variablen"

model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for z in zutaten) <= maxAlkohol * quicksum(z[zutat] for z in zutaten )

# Dritte Nebenbedingung:
# Bedeutung: Alkoholgehalt des Cocktails muss mindestens <minAlkohol> betragen
# Ungleichung: "Summe aller (Variablen * jeweiliger Alkoholgehalt der Variable ) >= minAlkohol * Summe aller Variablen"

model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for z in zutaten) >= minAlkohol * quicksum(z[zutat] for z in zutaten )

# Vierte Nebenbedingung:
# Bedeutung: Fruchtanteil muss mindestens <minFruchtanteil> sein
# Ungleichung: "Summe aller Variablen >= minFruchtanteil"

model.addConstr(quicksum(fruchtanteil[zutat] * z[zutat] for z in zutaten) >= minFruchtanteil )

# Fuenfte Nebenbedingung:
# Bedeutung: Kalorien dürfen höchstens <maxKalorien> betragen
# Ungleichung: "Summe aller Variablen <= maxKalorien"

model.addConstr(quicksum(kalorien[zutat] * z[zutat] for z in zutaten) <= maxKalorien )


# Nebenbedingungen hinzugefuegt? LP loesen lassen!
model.optimize()

model.write("Cocktailmischung.lp")
# Cocktailpreis und einzelne Mengen ausgeben.
if model.status == GRB.OPTIMAL:
print('\nPreis des Cocktails: %g' % model.ObjVal)
for zutat in zutaten:
print('Menge von %s im Cocktail: %g' % (zutat, z[zutat].x))
else:
print('Keine Optimalloesung gefunden. Status: %i' % (model.status))

# Modell zurueckgeben.
return model
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Einrückungen sind in Python ein wichtiges syntaktisches Element. Die kann man nicht einfach so nach belieben verteilen. Jeder Block wird dabei im 4 Leerzeichen eingerückt, nicht mal 0, 1 oder 2 Leerzeichen. Hier im Forum keine Screenshots posten, sondern den Code in [ python ] - Tags eingefasst hineinkopieren.

Wo ist denn der Syntaxfehler, wenn Du korrekt einrückst?
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

In dieser Zeiler model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for z in zutaten) >= minAlkohol * quicksum(z[zutat] for z in zutaten )

Wenn ich die Zeile ausgraue mit # springt der Fehler zum nächsten Contr. Befehl.

Sorry für den Screenshot, das wusste ich nicht
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Zähl mal die Klammern. Logisch machen die beiden Zeilen auch keinen Sinn.
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

Ok ich depp ... habe es korrigiert, allerdings läuft es immer noch nicht .
Bekomme nun folgenden Fehler string indices must be integers
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@frozenmaze: Du verwendest zu oft `z` für verschiedene Dinge. In ``z[zutat] for z in zutaten`` ist steht `z` für die einzelnen Zeichenketten aus `zutaten` und nicht für das `z` ausserhalb des Ausdrucks. Wobei selbst das komisch wäre, denn für jedes `z` aus Zutaten wäre ja `zutat` immer gleich. Da ist jetzt auch so ein bisschen die Frage wie Du das mit der Einrückung gelöst hast. Was ist denn alles innerhalb der ersten ``for``-Schleife und was ist nach dieser Schleife?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

True habs gerade gesehen ... hab dies auch korrigiert, nun folgender Fehler Unsupported type (<class 'gurobipy.TempConstr'>) for LinExpr addition argument


Hier der aktuelle Code :

# coding=utf-8

from gurobipy import *

def solve(zutaten, preis, alkohol, fruchtanteil, kalorien, minAlkohol, maxAlkohol, minFruchtanteil, maxKalorien, minVolumen):
# Modell erzeugen:
model = Model("Cocktailmischung")

# Variablen erzeugen: Zunaechst leeres Dictionary.
z = {}

# Alle Variablen der Liste durchlaufen.
for zutat in zutaten:
# Fuer jede Zutat wird die Variable "x_ZUTAT" angelegt.
z[zutat] = model.addVar(name = ("z_" + zutat), obj = preis[zutat])

# Variablen dem Modell bekannt machen.
model.update()

# Erste Nebenbedingung:
# Bedeutung: Volumen muss mindestens <minVolumen> sein.
# Ungleichung: "Summe aller Variablen >= minVolumen"

# Erste Nebenbedingung:
# Bedeutung: Volumen muss mindestens <minVolumen> sein.
# Ungleichung: "Summe aller Variablen >= minVolumen"

model.addConstr(quicksum(z[zutat] for zutat in zutaten) >= minVolumen )

# Zweite Nebenbedingung:
# Bedeutung: Alkoholgehalt des Cocktails darf maximal <maxAlkohol> betragen
# Ungleichung: "Summe aller (Variablen * jeweiliger Alkoholgehalt der Variable ) <= maxAlkohol * Summe aller Variablen"

model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for zutat in zutaten) <= maxAlkohol * quicksum(z[zutat] for zutat in zutaten ))

# Dritte Nebenbedingung:
# Bedeutung: Alkoholgehalt des Cocktails muss mindestens <minAlkohol> betragen
# Ungleichung: "Summe aller (Variablen * jeweiliger Alkoholgehalt der Variable ) >= minAlkohol * Summe aller Variablen"

model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for zutat in zutaten) >= minAlkohol * quicksum(z[zutat] for zutat in zutaten ))

# Vierte Nebenbedingung:
# Bedeutung: Fruchtanteil muss mindestens <minFruchtanteil> sein
# Ungleichung: "Summe aller Variablen >= minFruchtanteil"

model.addConstr(quicksum(fruchtanteil[zutat] * z[zutat] for zutat in zutaten) >= minFruchtanteil )

# Fuenfte Nebenbedingung:
# Bedeutung: Kalorien dürfen höchstens <maxKalorien> betragen
# Ungleichung: "Summe aller Variablen <= maxKalorien"

model.addConstr(quicksum(kalorien[zutat] * z[zutat] for zutat in zutaten) <= maxKalorien )


# Nebenbedingungen hinzugefuegt? LP loesen lassen!
model.optimize()

# Cocktailpreis und einzelne Mengen ausgeben.
if model.status == GRB.OPTIMAL:
print('\nPreis des Cocktails: %g' % model.ObjVal)
for zutat in zutaten:
print('Menge von %s im Cocktail: %g' % (zutat, z[zutat].x))
else:
print('Keine Optimalloesung gefunden. Status: %i' % (model.status))

# Modell zurueckgeben.
return model
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@frozenmaze: Bei welchem Ausdruck denn? Bei Ausnahmen bitte den gesamten Traceback zeigen und nicht nur die letzte Zeile.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

Rest des Codes, sehe leider nirgends nen fettes rot was mir sagt um welchen Ausdruck es geht



from gurobipy import *

# Die ist eine Instanzdatei mit konkreten Daten, Sie muessen diese Datei nicht aendern!

zutaten, preis, alkohol, fruchtanteil, kalorien = multidict({
"Rum": [1.57, 0.45, 0, 154],
"Aprikosensaft": [1.41, 0, 65, 243],
"Grenadine": [1.21, 0, 40, 87],
"Orangennektar": [1.21, 0, 50, 47],
"Amaretto": [1.32, 0.28, 0, 284],
"Gurkensaft":[1.25, 0, 35, 110],
"Els": [1.34, 0.31, 5, 112],
"Kirschlikoer": [2.7, 0.16, 20, 150],
"Limonade":[0.87, 0, 25, 180]
})

# zutaten: Liste der Zutaten als Strings (str).
# preis: Dictionary, das jede Zutat Ihrem Preis zuordnet, also z.B. preis['Rum']
# alkohol: Dictionary, das jede Zutat Ihrem Alkoholanteil zuordnet.
# fruchtanteil: Dictionary, das jede Zutat Ihren Fruchtanteil in g/100 ml zuordnet, also z.B. minFruchtanteil['Rum']
# kalorien: Dictionary, das jede Zutat Ihrer Kalorienmenge je 100 ml zuordnet, also z.B. preis['Rum']

maxAlkohol = 0.45 # 45%
minAlkohol = 0.35 # 35%
minFruchtanteil = 25 # in g/100ml
maxKalorien = 400
minVolumen = 2.5 # in 100 ml

import cocktailmodel

model = cocktailmodel.solve(zutaten, preis, alkohol, fruchtanteil, kalorien, minAlkohol, maxAlkohol, minFruchtanteil, maxKalorien, minVolumen)

if not isinstance(model, Model):
print("solve-Funktion gibt kein Gurobi-Modell zurueck!")
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Den Traceback sollst du komplett zeigen. Das ist das was mit dem Wort Traceback beginnt und mit der Meldung die Du gezeigt hast endet. Also das ``Unsupported type …``, wobei da sicher noch ein ``TypeError`` davor steht. Am Traceback sieht man die Aufrufe an denen die Ausnahme vorbei kam.

Und verwende doch bitte Python-Tags wenn Du Python-Code zeigst, damit der mindestens richtig eingerückt angezeigt wird und vielleicht sogar korrekt bunt. :-) Da ist so ein Button auf dem „Python“ steht, über dem Texteingabefeld im (vollständigen) Editor.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

Sorry bin etwas überfordert. Wo genau in steht das mit Python in Spyder? Arbeite wirklich zum ersten mal damit.
Hab dir jetzt nochmal alles aus der Console geschickt. Falls das nicht reicht oder du mehr Info brauchst sag Bescheid,
dann schau ich nochmal ... Sorry und Danke



runfile('C:/Users/max/Desktop/Neuer Ordner/cocktaildata1.py', wdir='C:/Users/max/Desktop/Neuer Ordner')
Reloaded modules: cocktailmodel
Traceback (most recent call last):

File "<ipython-input-2-9ef771d50d32>", line 1, in <module>
runfile('C:/Users/max/Desktop/Neuer Ordner/cocktaildata1.py', wdir='C:/Users/max/Desktop/Neuer Ordner')

File "C:\Users\max\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\Users\max\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/max/Desktop/Neuer Ordner/cocktaildata1.py", line 27, in <module>
model = cocktailmodel.solve(zutaten, preis, alkohol, fruchtanteil, kalorien, minAlkohol, maxAlkohol, minFruchtanteil, maxKalorien, minVolumen)

File "C:\Users\max\Desktop\Neuer Ordner\cocktailmodel.py", line 34, in solve
model.addConstr(quicksum(minAlkohol <= z[zutat] * alkohol[zutat] for zutat in zutaten) <= maxAlkohol * quicksum(z[zutat] for zutat in zutaten ))

File "gurobi.pxi", line 2709, in gurobipy.quicksum (../../src/python/gurobipy.c:128361)

File "linexpr.pxi", line 457, in gurobipy.LinExpr.__iadd__ (../../src/python/gurobipy.c:34821)

File "linexpr.pxi", line 173, in gurobipy.LinExpr.add (../../src/python/gurobipy.c:31302)

GurobiError: Unsupported type (<class 'gurobipy.TempConstr'>) for LinExpr addition argument
frozenmaze
User
Beiträge: 7
Registriert: Sonntag 24. Juni 2018, 12:45

Ok hab es zum laufen bekommen danke
Antworten