RecursionError: maximum recursion depth exceeded in comparison

135 views
Skip to first unread message

Chris Price

unread,
Jun 12, 2020, 11:32:10 AM6/12/20
to pulp-or-discuss
I have previously posted about a shipping demurrage problem I am working on, and in formulating the problem I am receiving the following error>

The variable and decision variable definitions appear to be sound, so I am confused why I am receiving a recursion error. Code as follows:

# Vessel readiness notification (a list of 6 dates as a string in 'YYYY-MM-DD' format
vessel_notice_of_readiness_date
= dict(

    zip
(demurrage_df.index, demurrage_df['notice_of_readiness_date'])
)




# Decision Variable: Vessel Load Date
load_start_date
= pulp.LpVariable.dicts(
   
'Vessel Load Date',
   
((date, vessel) for date, vessel in demurrage_df.reset_index().set_index(['eta_date', 'vessel_name']).index),
    cat
='Binary',
    lowBound
=0,
    upBound
=1
)


# Instantiate class
model
= pulp.LpProblem('Demurrage Optimisation Test 1', pulp.LpMinimize)


# Objective Function
model
+= pulp.lpSum([
    demurrage_charge_vars
[vessel]
   
for vessel in demurrage_charge_vars]
), 'Minimise Demurrage'


# Omitted full logic for clarity's sake.


# Vessels can only load when material is available
for date, vessel, grade in sales_demand_by_vessel:
  model
+= port_inventory_vars[(date, grade)] >= sales_demand_by_vessel[(date, vessel, grade)] == load_start_date[(date, vessel)]

# Vessels can only load AFTER notice of readiness.
for date, vessel in load_start_date:
  model
+= load_start_date[(date, vessel)] >= vessel_notice_of_readiness_date[vessel]
 model
+= pulp.lpSum(load_start_date[vessel] - vessel_notice_of_readiness_date[vessel] * demurrage_per_day_charges[vessel]) == demurrage_charge_vars[vessel]

Full error received is as follows:

RecursionError Traceback (most recent call last) <ipython-input-567-cabf4432e589> in <module>
 
77 # Vessels can only load AFTER notice of readiness.
 
78 for date, vessel in load_start_date:
---> 79 model += load_start_date[(date, vessel)] >= vessel_notice_of_readiness_date[vessel]
 
80 # model += pulp.lpSum(load_start_date[vessel] - vessel_notice_of_readiness_date[vessel] * demurrage_per_day_charges[vessel]) == demurrage_charge_vars[vessel]


If anyone can see where I am going wrong I would be very grateful! Thank you in advance.


Franco Peschiera

unread,
Jun 13, 2020, 5:45:11 AM6/13/20
to pulp-or-discuss
Can you provide a reproducible example? With all the data in the same python file?

https://stackoverflow.com/help/minimal-reproducible-example

That would really increase the chance of someone helping out since it greatly reduces the time invested for the person who answers.

F.

Message has been deleted
Message has been deleted

Chris Price

unread,
Jun 13, 2020, 7:26:14 AM6/13/20
to pulp-or-discuss
Hi Franco,

Many thanks for your help. 

MRE below: I have not formally formatted it as code as the previous two attempts have resulted in an error. 

# SALES VARS
sales_demand = {
    '2020-05-28': {
        'CEYLON': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'PETER ORDFF': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'BULK JAPAN II': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'XIN FA': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    },
    '2020-05-29': {
        'PACIFIC MAJOR': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'CCSC YASA XI JING': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'XIANG HAI HO': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'ROBUSTO': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    },
    '2020-05-30': {
        'AQUATONIKA': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'ARUNN': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'HARALAMBO': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'CCSC HMMONG': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    },
    '2020-05-31': {
        'SHTP TOW': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'FURIOUS': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'YASA UNITY I': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'OCEAN SILVER': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    },
    '2020-06-01': {
        'PELICAN': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'BAY OF NAPLES': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'TIN CITY': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'MOORING LINE': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    },
    '2020-06-01': {
        'KANG XIN HAI': {
            'MAF': 0, 'PRE': 40000, 'ZBL': 0, 'AFE': 10000, 'AAC': 70000
            },
        'RAHI I': {
            'MAF': 0, 'PRE': 100000, 'ZBL': 0, 'AFE': 0, 'AAC': 0
            },
        'APJ ANGAD II': {
            'MAF': 30000, 'PRE': 0, 'ZBL': 70000, 'AFE': 0, 'AAC': 0
            },
        'CCSC ROBERTS BANK': {
            'MAF': 0, 'PRE': 0, 'ZBL': 9000, 'AFE': 20000, 'AAC': 0
        }
    }
}

# Sales demand by vessel, grade in tonnes                              
sales_df = pd.DataFrame.from_records(
    [
        (date, vessel, grade, tonnes)
        for date, vessel in sales_demand.items()
        for vessel, grade in vessel.items()
        for grade, tonnes in grade.items()
    ], columns = ['eta_date', 'vessel_name', 'grade', 'required_tonnes']
).set_index(['eta_date', 'vessel_name', 'grade'])
sales_df.index = sales_df.index.set_levels(
    pd.to_datetime(sales_df.index.levels[0]).strftime('%F'), 
    level=0)

# Demurrage charges
demurrage_df = sales_df.reset_index()[['eta_date', 'vessel_name']].drop_duplicates()
demurrage_df['per_diem_demurrage'] = [np.random.randint(11000, 31000) for i in range(len(demurrage_df))]
demurrage_df = demurrage_df.set_index(['vessel_name'])
demurrage_df['notice_of_readiness_date'] = pd.to_datetime(demurrage_df['eta_date']).apply(pd.DateOffset(1)).dt.strftime('%F')

# Vessels: Vessel Load Date:
load_start_date = pulp.LpVariable.dicts(
    'Vessel Load Date',
    ((date, vessel) for date, vessel in demurrage_df.reset_index().set_index(['eta_date', 'vessel_name']).index),
    cat='Binary',
    lowBound=0,
    upBound=1
)

# Sales Demand by Vessel
sales_demand_by_vessel = dict(zip(sales_df.index, sales_df.required_tonnes))

# Vessels: Demurrage Variable
demurrage_charge_vars = pulp.LpVariable.dicts(
    'Demurrage Charges',
    ((vessel) for vessel in demurrage_df.index),
    cat='Continuous',
    lowBound=0
)

# Demurrage charges by vessel
demurrage_per_day_charges = dict(
    zip(demurrage_df.index, demurrage_df['per_diem_demurrage']))

# Notice of readiness
vessel_notice_of_readiness_date = dict(
    zip(demurrage_df.index, demurrage_df['notice_of_readiness_date'])
)

# Port Inventory
port_inventory_vars = pulp.LpVariable.dicts(
    'Port Inventory Levels',
    ((d, g) for d in dates for g in grades),
    cat='Continuous',
    lowBound=0)

# Instantiate class
model = pulp.LpProblem('Port Inventory Optimisation Test 1', pulp.LpMinimize)

solver = pulp.PULP_CBC_CMD()
solver.tmpDir = 'Users\CPrice2'

# Objective Function
model += pulp.lpSum([
    demurrage_charge_vars[vessel]
    for vessel in demurrage_charge_vars])

     
# Vessels can ony load when material is available 
for date, vessel, grade in sales_demand_by_vessel:
  model += port_inventory_vars[(date, grade)] >= sales_demand_by_vessel[(date, vessel, grade)] == load_start_date[(date, vessel)]

# Vessels can only load AFTER notice of readiness.
for date, vessel in load_start_date:
  model += vessel_notice_of_readiness_date[vessel] <= load_start_date[(date, vessel)]
  model += pulp.lpSum(load_start_date[vessel] - vessel_notice_of_readiness_date[vessel] * demurrage_per_day_charges[vessel]) == demurrage_charge_vars[vessel]


Stuart Mitchell

unread,
Jun 13, 2020, 8:14:21 AM6/13/20
to pulp-or...@googlegroups.com
Remove the pulp.lpsum on line 80

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to the Google Groups "pulp-or-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or-discu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pulp-or-discuss/d3459c8a-d11f-4752-8fc6-f85b971a397do%40googlegroups.com.

Chris Price

unread,
Jun 13, 2020, 12:11:13 PM6/13/20
to pulp-or...@googlegroups.com
No change - still receiving same error?

Chris Price

unread,
Jun 14, 2020, 3:50:46 PM6/14/20
to pulp-or-discuss
Is it possible that the date format is causing the error? Line 80 is comparing date strings in YYYY-MM-DD format - should I use an integer for comparing the dates?



On Saturday, June 13, 2020 at 5:11:13 PM UTC+1, Chris Price wrote:
No change - still receiving same error?

On Sat, Jun 13, 2020 at 1:14 PM 'Stuart Mitchell' via pulp-or-discuss <pulp-or-discuss@googlegroups.com> wrote:
Remove the pulp.lpsum on line 80

To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or-discuss+unsubscribe@googlegroups.com.

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to the Google Groups "pulp-or-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or-discuss+unsubscribe@googlegroups.com.

Franco Peschiera

unread,
Jun 14, 2020, 4:22:26 PM6/14/20
to pulp-or...@googlegroups.com

your code is still missing the dates and grades python variables to be defined.
Also, the the pandas, pulp and numpy library imports.


On Sun, Jun 14, 2020 at 9:50 PM 'Chris Price' via pulp-or-discuss <pulp-or...@googlegroups.com> wrote:
Is it possible that the date format is causing the error? Line 80 is comparing date strings in YYYY-MM-DD format - should I use an integer for comparing the dates?



On Saturday, June 13, 2020 at 5:11:13 PM UTC+1, Chris Price wrote:
No change - still receiving same error?

On Sat, Jun 13, 2020 at 1:14 PM 'Stuart Mitchell' via pulp-or-discuss <pulp-or...@googlegroups.com> wrote:
Remove the pulp.lpsum on line 80

To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or-discu...@googlegroups.com.

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to the Google Groups "pulp-or-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or-discu...@googlegroups.com.

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to a topic in the Google Groups "pulp-or-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pulp-or-discuss/GqDc8xI-Iyk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pulp-or-discu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pulp-or-discuss/98d9af14-50f6-4eb4-a440-ce2369a61ea7o%40googlegroups.com.

Chris Price

unread,
Jun 15, 2020, 3:56:42 AM6/15/20
to pulp-or-discuss
Apologies - thank you for pointing out Franco, please see below:

import datetime
import numpy as np
import pandas as pd
import pulp as pulp
# Dates
dates = [
    d.strftime('%F') 
    for d in pd.date_range(plan_start_date, planning_horizon_max)]

# Get all grades
grades = [g for g in port_inventory_df.index]
To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or...@googlegroups.com.

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to the Google Groups "pulp-or-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pulp-or...@googlegroups.com.

--
New posters to this group are moderated which can take up to 48 hours, so please be patient if your first post takes a while to turn up.
---
You received this message because you are subscribed to a topic in the Google Groups "pulp-or-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pulp-or-discuss/GqDc8xI-Iyk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pulp-or...@googlegroups.com.

Franco Peschiera

unread,
Jun 15, 2020, 4:43:39 PM6/15/20
to pulp-or...@googlegroups.com

You’re still missing variables (plan_start_date, port_inventory_df, planning_horizon_max). I suggest you copy the whole code into a new python file and try to execute it by itself until you reproduce the original problem with pulp. Please read the stackoverflow link I sent, they probably talk about this and how to do it properly.
Until you manage to reproduce your pulp problem in a MWE and then share it, it will be very hard to help you further.

regards,

F.

To unsubscribe from this group and all its topics, send an email to pulp-or-discu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pulp-or-discuss/06ecd79b-1254-4da6-acfa-6d7f3b46a985o%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages