songwenas12 / fjsp-drl

Apache License 2.0
188 stars 53 forks source link

Questions about "start_time, proc_time, end_time" for every operations in the running results #7

Closed ZhaoKe1024 closed 7 months ago

ZhaoKe1024 commented 7 months ago

I ran your code and made modifications to the test.py file to print the start and end times of each operations, similar to a Gantt chart. However, I found that the durations of different operations within the same job have overlapping. Specifically, I found that operations within the same job can have overlapping processing times when executed on different machines. In the FJSP problem, the subsequent operation cannot begin until the previous one has finished. I would like to know, if there is an error in my code or if I misunderstood your code. My modified code is as follows, with the addition of a printing section:

def schedule(env, model, memories, flag_sample=False):
    # Get state and completion signal
    state = env.state
    dones = env.done_batch
    done = False  # Unfinished at the beginning

    biases = env.num_ope_biases_batch[0]
    proc_time = env.schedules_batch[0]
    # operation list for every machine
    res = [[] for _ in range(env.num_mas)]
    last_time = time.time()
    i = 0
    while ~done:
        i += 1
        with torch.no_grad():
            actions = model.policy_old.act(state, memories, dones, flag_sample=flag_sample, flag_train=False)
            # print("actions:", actions)
            injob_index = copy.deepcopy(actions[0][0])  # operation global index
            st = round(proc_time[injob_index][2].item(), 3)  # start time
            et = round(proc_time[injob_index][3].item(), 3)  # end time
            # The following code obtains the index of an operation within the job
            if injob_index > biases[-1]:
                injob_index -= biases[-1]
            for j, k in enumerate(biases):
                if injob_index > k:
                        continue
                elif injob_index < k:
                    injob_index -= biases[j-1]
                    break
                else:
                    if j==0:
                        break
                    else:
                        injob_index = 0
                        break
            # print(f"Machine:{actions[1][0]} ; Task({actions[2][0]}-{injob_index})")
            # Task(job_id - operation_id_in_job)[start_time - end_time]
            res[actions[1][0]].append(f"Task({actions[2][0]}-{injob_index})[{st},{et}]")
            # As printed below
            # Machine0: Task(0-0)[0.0,4.5]||Task(4-1)[5.0,9.0]||Task(10-1)[5.0,7.0]||...
            # Machine1: Task(1-0)[0.0,6.0]||Task(4-2)[6.0,12.0]||Task(2-0)[0.0,6.0]||Task(3-1)[13.0,19.0]||...
            # ...
        state, rewards, dones = env.step(actions)  # environment transit
        done = dones.all()
    for i, ma in enumerate(res):
        # print(f"Machine {i}", end=': ')
        for ta in ma:
            print(ta, end='||')
        print()
    spend_time = time.time() - last_time  # The time taken to solve this environment (instance)
    # print("spend_time: ", spend_time)

    # Verify the solution
    gantt_result = env.validate_gantt()[0]
    if not gantt_result:
        print("Scheduling Error!!!!!!")
    return copy.deepcopy(env.makespan_batch), spend_time
ZhaoKe1024 commented 7 months ago

I ran your code and made modifications to the test.py file to print the start and end times of each operations, similar to a Gantt chart. However, I found that the durations of different operations within the same job have overlapping. Specifically, I found that operations within the same job can have overlapping processing times when executed on different machines. In the FJSP problem, the subsequent operation cannot begin until the previous one has finished. I would like to know, if there is an error in my code or if I misunderstood your code. My modified code is as follows, with the addition of a printing section:

def schedule(env, model, memories, flag_sample=False):
    # Get state and completion signal
    state = env.state
    dones = env.done_batch
    done = False  # Unfinished at the beginning

    biases = env.num_ope_biases_batch[0]
    proc_time = env.schedules_batch[0]
    # operation list for every machine
    res = [[] for _ in range(env.num_mas)]
    last_time = time.time()
    i = 0
    while ~done:
        i += 1
        with torch.no_grad():
            actions = model.policy_old.act(state, memories, dones, flag_sample=flag_sample, flag_train=False)
            # print("actions:", actions)
            injob_index = copy.deepcopy(actions[0][0])  # operation global index
            st = round(proc_time[injob_index][2].item(), 3)  # start time
            et = round(proc_time[injob_index][3].item(), 3)  # end time
            # The following code obtains the index of an operation within the job
            if injob_index > biases[-1]:
                injob_index -= biases[-1]
            for j, k in enumerate(biases):
                if injob_index > k:
                        continue
                elif injob_index < k:
                    injob_index -= biases[j-1]
                    break
                else:
                    if j==0:
                        break
                    else:
                        injob_index = 0
                        break
            # print(f"Machine:{actions[1][0]} ; Task({actions[2][0]}-{injob_index})")
            # Task(job_id - operation_id_in_job)[start_time - end_time]
            res[actions[1][0]].append(f"Task({actions[2][0]}-{injob_index})[{st},{et}]")
            # As printed below
            # Machine0: Task(0-0)[0.0,4.5]||Task(4-1)[5.0,9.0]||Task(10-1)[5.0,7.0]||...
            # Machine1: Task(1-0)[0.0,6.0]||Task(4-2)[6.0,12.0]||Task(2-0)[0.0,6.0]||Task(3-1)[13.0,19.0]||...
            # ...
        state, rewards, dones = env.step(actions)  # environment transit
        done = dones.all()
    for i, ma in enumerate(res):
        # print(f"Machine {i}", end=': ')
        for ta in ma:
            print(ta, end='||')
        print()
    spend_time = time.time() - last_time  # The time taken to solve this environment (instance)
    # print("spend_time: ", spend_time)

    # Verify the solution
    gantt_result = env.validate_gantt()[0]
    if not gantt_result:
        print("Scheduling Error!!!!!!")
    return copy.deepcopy(env.makespan_batch), spend_time

In addition, if possible, we can have a detailed discussion. My email address is zhaoke22@mails.ucas.ac.cn , and we can communicate in Chinese.