<jupyter_start><jupyter_text>Consideraciones para la implementación:* Se considera velocidad constante para todos los pickeadores* Se considera el tiempo en recoger un producto igual para todos los pickeadores y para todos los productos<jupyter_code>cant_pickeadores=4 #cantidad de pickeadores en el centro de distribución.
tiempo_pickeo=20 #tiempo de pickeo por producto (se considera constante).
velocidad=30 #velocidad de los pickeadores para recorrer el centro.<jupyter_output><empty_output><jupyter_text>Extraccion de datos:<jupyter_code>ots = pd.read_csv("data/ot.csv",sep=',')
ots=ots.sort_values('Pedido')
xlsx_file = "data/layout.xlsx"
layout = pd.read_excel(xlsx_file, sheet_name="layout")
adyacencia=pd.read_excel(xlsx_file, sheet_name="adyacencia")

#ordenes:
ots.head()
#datos sobre cada producto/pasillo
layout.head()
#adyacencia de cada pasillo:
adyacencia.head()
#cantidad de ordenes 
cant_ordenes=len(ots['Pedido'].unique())
cant_ordenes
#array con todos los pasillos:
pasillos=layout['pasillo'].unique()
pasillos
#lista con las ordenes ordenadas 
ordenes_enum=ots["Pedido"].unique()
ordenes_enum=list(ordenes_enum)
ordenes_enum
#arreglo con cada producto pedido por orden
lista=[]
for x in range(cant_ordenes):
    obj=list(ots.loc[ots["Pedido"]==x+1]["Cod.Prod"])
    lista.append(obj)
    ordenes=np.array(lista)
ordenes
#se construye una lista donde cada elemento representa el pedido asignado a cada pickeador
#(inicialmente 0 porque no tienen pedidos asignados)
pickeadores=[]
for x in range(cant_pickeadores):
    pickeadores.append(0)

pickeadores
#se inicializa un dataframe que me dira si un pasillo esta ocupado y que pickeador está en el (pickeador 0 cuando no hay nadie).
l=[]
for pasillo in pasillos:
    l.append([pasillo,False, 0])
pasillo_bool=pd.DataFrame(l,
                          columns=["pasillo","ocupado","pickeador"])

pasillo_bool.head()
#se crea una lista donde cada elemento en la posicion i representa el pasillo actual del pickeador i+1.
pasillo_act=[]
for x in range(cant_pickeadores):
    pasillo_act.append(0)
    
pasillo_act<jupyter_output><empty_output><jupyter_text>Funciones:<jupyter_code>#Funcion para asignar ordenes a los pickeadores, recibe una lista talcomo la que creamos antes "pickeadores"
def asignar_ordenes(pickeadores):
    for x in range(cant_pickeadores):
        if pickeadores[x]==0:
            if len(ordenes_enum)>0:
                pickeadores[x]=ordenes_enum[0]
                ordenes_enum.remove(ordenes_enum[0])
    return pickeadores
#Funcion que retorna True si es que existe ruta desde el pasillo p2 al p1, y False en caso contrario
def existe_ruta(p1,p2):
    ady=adyacencia.loc[adyacencia["pasillo"]==p2]
    
    if p1==p2:
        return True
    
    for x in range(ady.shape[0]):
        if ady.iloc[x,1]==p1:
            return True
        else:
            if ady.iloc[x,1]==-1:
                return False
            else:
                return existe_ruta(p1,ady.iloc[x,1])
#función que entrega el siguiente pasillo a ir en la ruta desde un pasillo a otro.
def next_move(pasillo_a_ir,pasillo_act):
    ady=adyacencia.loc[adyacencia["pasillo"]==pasillo_act]
    for x in range(ady.shape[0]):
        if existe_ruta(pasillo_a_ir,ady.iloc[x,1]):
            return ady.iloc[x,1]
#Función que me devuelve una lista con la ruta a seguir para ir a un pasillo desde el pasillo actual en el que se encuentra un
#pickeador.
def ruta(pasillo_a_ir,pasillo_act):
    x=pasillo_act
    l=[]
    while x!=pasillo_a_ir:
        x=next_move(pasillo_a_ir,x)
        l.append(x)
    return l
#Funcion creada para ordenar por pasillo los elementos dentro de una orden.
def ordenar(orden):
    lista_ordenada=[]
    for pasillo in pasillos:
        for x in range(len(orden)):
        
            if pasillo==objeto_en_pasillo(orden[x]):
                lista_ordenada.append(orden[x])
    return lista_ordenada
#Funcion que recibe un codigo de producto y retorna el pasillo en el que se encuentra
def objeto_en_pasillo(cod_prod):
    l=layout.loc[layout["Producto"]==cod_prod]
    pasillo=l.iloc[0,2]
    return pasillo
#Funcion que recibe un pasillo y retorna True si es que este esta ocupado o False en el caso contrario.
def ocupado(pasillo):
    p=pasillo_bool.loc[pasillo_bool["pasillo"]==pasillo]
    return p.iloc[0,1]<jupyter_output><empty_output><jupyter_text>Función final:<jupyter_code>def tiempo(ordenes,pickeadores):
    print("cant pickeadores:", cant_pickeadores)
    for x in range(len(ordenes)):
        ordenes[x]=ordenar(ordenes[x])
    
    t_recorrido=0
    t_wait=0
    t_pick=0
    contador=[]
    for y in range(cant_pickeadores):
        contador.append(0)
        
    while len(ordenes_enum)>0:
        
        asignar_ordenes(pickeadores)
        for x in range(cant_pickeadores):
            if pickeadores[x] !=0: 
                if contador[x]==-1:
                    next_move=-1
                else:
                    next_move=objeto_en_pasillo(ordenes[pickeadores[x]-1][contador[x]])
                if len(ruta(next_move,pasillo_act[x]))==0:
                    if pasillo_act[x]==-1:
                        contador[x]=0
                        pickeadores[x]=0
                        pasillo_act[x]=0
                    
                    else:
                        t_pick+=tiempo_pickeo
                        if contador[x]+1<len(ordenes[pickeadores[x]-1]):
                            contador[x]+=1
                        else:
                            contador[x]=-1
                else:
                    route=ruta(next_move,pasillo_act[x])
                    if route[0]==-1:
                        pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==pasillo_act[x]].index,1]=False
                        pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==pasillo_act[x]].index,2]=0
                        t_recorrido+=1/velocidad
                        pasillo_act[x]=route[0]
                        pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==route[0]].index,1]=True
                        pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==route[0]].index,2]=x+1
                    
                    else:
                        if ocupado(route[0]):
                            t_wait+=tiempo_pickeo
                        else:
                            if pasillo_act[x]>0:
                                largo_pasillo=layout.loc[layout["pasillo"]==pasillo_act[x]].iloc[0,9]
                                t_recorrido+=largo_pasillo/velocidad
                            distancia_df=adyacencia.loc[(adyacencia["pasillo"]==pasillo_act[x]) & (adyacencia["adyacente"]==route[0])]
                            distancia=distancia_df.iloc[0,2]
                            pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==pasillo_act[x]].index,1]=False
                            pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==pasillo_act[x]].index,2]=0
                            t_recorrido+=distancia/velocidad
                            pasillo_act[x]=route[0]
                            pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==route[0]].index,1]=True
                            pasillo_bool.iloc[pasillo_bool.loc[pasillo_bool["pasillo"]==route[0]].index,2]=x+1
            
    print ("tiempo de espera:", t_wait)
    print("tiempo en hacer recorridos:", t_recorrido)
    print("tiempo de pickeo:", t_pick)
    
    return t_recorrido+t_wait+t_pick

tiempo(ordenes,pickeadores)<jupyter_output>cant pickeadores: 4
tiempo de espera: 500
tiempo en hacer recorridos: 66001.2333333335
tiempo de pickeo: 1360<jupyter_text>Problemas:* Al momento de escoger la cantidad de pickeadores mayor igual a las ordenes totales (20 en el caso de prueba) surge un error en el que el tiempo de pickeo de productos es 0, lo que nos dice que no recogerian productos los pickeadores.* La función ruta, no retorna la ruta mas corta entre 2 pasillos, por ejemplo devuelve rutas de 6 pasillos cuando el pasillo esta a 2.<jupyter_code>#Notar que el pasillo 51 es adyacente al pasillo 0 entonces solo basta un movimiento para ir, en cambio la funcion retorna:
ruta(51,0)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10006071645415908, 'fraction_numerical': 0.014329083181542197, 'mean_word_length': 2.750455373406193, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '169885', 'license': 'MIT', 'n_tokens_mistral': 2863, 'n_tokens_neox': 2813, 'n_words': 612, 'path': 'Implementación/warehouse.ipynb', 'repo_name': 'sergio825/lab_modelacion_2020', 'size': '8235'}