Esempio n. 1
0
    def _create_model(self, job_ids, r_times, p_intervals, m_availabe):
        ## prepare the index for decision variables
        # start time of process
        jobs = tuple(job_ids)
        machines = tuple(range(len(machine_properties)))
        # order of executing jobs: tuple list
        jobPairs = [(i, j) for i in jobs for j in jobs if i < j]
        # assignment of jobs on machines
        job_machinePairs = [(i, k) for i in jobs for k in machines]

        ## parameters model (dictionary)
        # 1. release time
        release_time = dict(zip(jobs, tuple(r_times)))
        # 2. process time
        process_time = dict(zip(jobs, tuple(p_intervals)))
        # 3. machiane available time
        machine_time = dict(zip(machines, tuple(m_availabe)))
        # 4. define BigM
        BigM = np.sum(r_times) + np.sum(p_intervals) + np.sum(m_availabe)

        ## create model
        m = Model('PMSP')
        ## create decision variables
        # 1. assignments of jobs on machines
        z = m.addVars(job_machinePairs, vtype=GRB.BINARY, name='assign')
        # 2. order of executing jobs
        y = m.addVars(jobPairs, vtype=GRB.BINARY, name='order')
        # 3. start time of executing each job
        startTime = m.addVars(jobs, name='startTime')
        ## create objective
        # m.setObjective(quicksum(startTime), GRB.MINIMIZE) # TOTRY

        m._max_complete = m.addVar(1, name='max_complete_time')
        m.setObjective(m._max_complete, GRB.MINIMIZE)  # TOTRY
        m.addConstr((m._max_complete == max_(startTime)), 'minimax')
        ## create constraints
        # 1. job release constraint
        m.addConstrs((startTime[i] >= release_time[i] for i in jobs),
                     'job release constraint')
        # 2. machine available constraint
        m.addConstrs((startTime[i] >= machine_time[k] - BigM * (1 - z[i, k])
                      for (i, k) in job_machinePairs),
                     'machine available constraint')
        # 3. disjunctive constraint
        m.addConstrs((startTime[j] >= startTime[i] + process_time[i] - BigM *
                      ((1 - y[i, j]) + (1 - z[j, k]) + (1 - z[i, k]))
                      for k in machines
                      for (i, j) in jobPairs), 'temporal disjunctive order1')
        m.addConstrs((startTime[i] >= startTime[j] + process_time[j] - BigM *
                      (y[i, j] + (1 - z[j, k]) + (1 - z[i, k]))
                      for k in machines
                      for (i, j) in jobPairs), 'temporal disjunctive order2')
        # 4. one job is assigned to one and only one machine
        m.addConstrs((quicksum([z[i, k] for k in machines]) == 1
                      for i in jobs), 'job non-splitting')

        # set initial solution
        for (i, k) in job_machinePairs:
            if (i, k) in assign_list:
                z[(i, k)].start = 1
            else:
                z[(i, k)].start = 0

        for (i, j) in jobPairs:
            if (i, j) in order_list:
                y[(i, j)].start = 1
            else:
                y[(i, j)].start = 0

        for i in job_ids:
            startTime[i].start = start_times[i]

        return m, z, y, startTime
Esempio n. 2
0
  def _create_model(self, job_ids, r_times, p_intervals, m_availabe, SRPT_MAX):
    ## prepare the index for decision variables
    # start time of process
    jobs = tuple(job_ids)
    machines = tuple(range(len(machine_properties)))
    # define BigM
    # BigM = np.sum(r_times) + np.sum(p_intervals) + np.sum(m_availabe)
    # BigM = np.max(r_times) + np.max(p_intervals) 
    # define possible largest time duration
    # TIME = range(int(BigM))
    TIME = range(int(SRPT_MAX))

    ## parameters model (dictionary)
    # 1. release time
    release_time = dict(zip(jobs, tuple(r_times)))
    # 2. process time
    process_time = dict(zip(jobs, tuple(p_intervals)))
    # 3. machiane available time
    machine_time = dict(zip(machines, tuple(m_availabe)))

    ## create model
    m = Model('PMSP')
    
    # job machine time
    m._MachineJobTime = [(k,j,t) for k in machines for j in jobs for t in TIME]
    
    ## create decision variables
    m._max_complete = m.addVar(1, name='max_complete_time')
    # 1. Chi: job j is processed on Machine i and processed at time t
    m._CHI = m.addVars(m._MachineJobTime, vtype=GRB.BINARY, name='order')
    # 2. complete time of executing each job
    m._completeTime = m.addVars(jobs, name='completeTime')
    
    ## create objective
    m.setObjective(quicksum(m._completeTime), GRB.MINIMIZE) # TOTRY
    # m.setObjective(m._max_complete, GRB.MINIMIZE) # TOTRY
    ## create constraints
    # 1. Each job starts processing on only one machine at only one point in time
    for j in jobs:
      expr = 0
      for k in machines:
        for t in TIME:
          expr += m._CHI[k,j,t]
      m.addConstr((expr == 1), 'time nonsplitting')
    m.update()
    # m.addConstrs((quicksum([m._CHI[k,i,t] for k in machines for t in TIME])==1 for i in jobs),'job machine match')
    # 2. At most one job is processed at any time on any machine 
    for k in machines: 
      for t in TIME[1:]:
        expr = 0
        for j_id in jobs:
          h = max(0, t - process_time[j_id])
          for t_id in range(h, t):
            expr += m._CHI[k,j_id,t_id]
        m.addConstr(expr <= 1)
    m.update()
    # 3. Completion time requirement
    # m.addConstrs((quicksum([(t+process_time[j]+machine_time[i])*m._CHI[i,j,t] for i in machines for t in TIME]) <= m._completeTime[j] for j in jobs), "CT")
    for j in jobs:
      expr = 0
      for i in machines:
        for t in TIME:
          expr += (t + process_time[j])*m._CHI[i,j,t]
      m.addConstr(expr == m._completeTime[j])
    m.update()
    # 4. release time constraint
    # m.addConstrs((quicksum([m._CHI[i,j_id,t] for i in machines for t in range(release_time[j_id])])==0 for j_id in jobs if release_time[j_id]>0),'release')
    for j in jobs:
      if release_time[j] > 0:
        expr = 0
        for i in machines:
          for t in range(release_time[j]):
            expr += m._CHI[i,j,t]
        m.addConstr(expr==0)
    m.update()
    # 5. machine available time
    # m.addConstrs((quicksum([m._CHI[m_id,j,t] for j in jobs for t in range(machine_time[m_id])])==0 for m_id in machines if machine_time[m_id]>0),'available')
    for i in machines:
      if machine_time[i]>0:
        expr = 0
        for j in jobs:
          for t in range(machine_time[i]):
            expr += m._CHI[i,j,t]
        m.addConstr(expr== 0)
    m.update()
    # 6. for minimax
    m.addConstrs((m._max_complete>=m._completeTime[j] for j in jobs),'minimax')

    return m