Ejemplo n.º 1
0
def write_fee_schedule(operations, path, sort=True, n_significant_figures=2):
    if sort:
        operations = sorted(operations, key=lambda x: x.name)

    group_dict = SortedDict()
    for op in operations:
        if op.group is not None and op.get_model_input_size(
        ) == 0 and op.get_n_model_param() == 1:
            if op.group not in group_dict:
                group_dict[op.group] = []

            group_dict[op.group].append(op)

    with open(path, "w") as ofile:
        ofile.write("# Fee Schedule\n")
        ofile.write("\n")
        ofile.write("| Operation | Gas cost |\n")
        ofile.write("|-----------|----------|\n")

        for op in operations:
            expr = op.get_gas_cost_expr(
                n_significant_figures=n_significant_figures)

            if expr is None:
                continue

            ofile.write("| `%s` | `%s` |\n" % (op.name, expr))

        if group_dict:
            ofile.write("\n")
            ofile.write("## Grouped Operations\n")
            ofile.write("\n")
            ofile.write("| Group | Maximum Gas cost |\n")
            ofile.write("|-------|------------------|\n")

            for key, ops in group_dict.items():
                # We should only get operations with 0 input variable and 1
                # parameter at this point

                max_cost = max(op.latest_param[0] for op in ops)
                expr = "{:_}".format(round_up(max_cost, n_significant_figures))

                ofile.write("| `%s` | `%s` |\n" % (key, expr))
Ejemplo n.º 2
0
def recheduleChangePriority(jobsListExportPrevious, rescheduleTime,
                            priorItinerary, machinesList):
    """

    :param jobsListExportPrevious: 初始调度结果
    :param rescheduleTime: 重调度时间
    :param priorItinerary: 优先的任务序号
    :param machinesList: 可用机器列表
    :return: jobsListToExportNew: 重调度方案
    """
    time = {}
    allPreviousOperations = {}
    rescheduleOperations = {}
    rescheduleJobsList = []
    currentTimeOnMachines = {}
    jobsListToExportNew = []
    unchangedOperations = {}
    # 遍历机器,生成每个机器前工序集合和需要重调度的工序集合
    for machine in machinesList:
        allPreviousOperations[machine.name] = [
            job for job in jobsListExportPrevious
            if job.assignedMachine == machine.name
        ]
        allPreviousOperations[machine.name].sort(key=lambda j: j.startTime)
        rescheduleOperations[machine.name] = [
            job for job in jobsListExportPrevious
            if job.assignedMachine == machine.name
            and job.startTime >= rescheduleTime
        ]
        rescheduleOperations[machine.name].sort(key=lambda j: j.startTime)

        # 重调度时刻机器时间更新
        unchangedLength = len(allPreviousOperations[machine.name]) - len(
            rescheduleOperations[machine.name])
        unchangedOperations[machine.name] = allPreviousOperations[
            machine.name][0:unchangedLength]
        currentTimeOnMachines[machine.name] = unchangedOperations[
            machine.name][-1].endTime
        if currentTimeOnMachines[machine.name] < rescheduleTime:
            currentTimeOnMachines[machine.name] = rescheduleTime

        # 初始化各机器时间
        time[currentTimeOnMachines[machine.name]] = {}

        # 更新各机器下重调度工序状态
        unchangedOperations[machine.name][-1].completed = True
        for job in rescheduleOperations[machine.name]:
            job.startTime = 0
            job.completed = False

        # 输出无需重调度的任务结果
        for job in unchangedOperations[machine.name]:
            jobsListToExportNew.append(job)

    for machine in machinesList:
        # 生成重调度列表
        for job in rescheduleOperations[machine.name]:
            if job.idItinerary == priorItinerary:
                job.priority = 5
            rescheduleJobsList.append(job)

    allJobsList = jobsListToExportNew + rescheduleJobsList
    # 调度时间初始化
    time = SortedDict(time)
    while len(jobsListToExportNew) < len(jobsListExportPrevious):
        for t, operations in time.items():
            operations = GetWaitingOperationsSPT(allJobsList, float(t),
                                                 machinesList,
                                                 currentTimeOnMachines)

            for keyMach, tasks in operations.items():
                if len(tasks):
                    if float(t) < currentTimeOnMachines[keyMach]:
                        continue
                    tasks[0].startTime = float(t)
                    tasks[0].completed = True
                    tasks[0].assignedMachine = keyMach
                    jobsListToExportNew.append(tasks[0])

                    currentTimeOnMachines[keyMach] = tasks[0].getEndTime()
                    time[currentTimeOnMachines[keyMach]] = {}

            del time[t]
            break
        time = SortedDict(time)  # chronological order
    return jobsListToExportNew
Ejemplo n.º 3
0
class TimingDiagram:
    """Two-state (True/False or 1/0) timing diagram with boolean algebra operations."""

    def __init__(self, time_state_pairs):
        """Creates a timing diagram out of a series of (time, state) pairs.

        Notes
        =====
        The input states can be any truthy/falsey values.
        The input times can be any type with a partial ordering.
        The input sequence does not need to be sorted (input is sorted during initialization).
        Compresses duplicate sequential states and stores them in the `timeline` attribute.

        Example
        =======
        >>> diagram = TimingDiagram([(0, True), (1, False), (5, False), (10, True)])
        >>> print(~diagram)
        TimingDiagram([(0, False), (1, True), (10, False)])
        """
        self.timeline = SortedDict(
            _compress(time_state_pairs, key=operator.itemgetter(1))
        )

    def __getitem__(self, item):
        return self.timeline[item]

    def __matmul__(self, time):
        """Alias for at()"""
        return self.at(time)

    def __eq__(self, other):
        """Returns a new timing diagram, True where the two diagrams are equal."""
        return self.compare(other, key=operator.eq)

    def __ne__(self, other):
        """Returns a new timing diagram, True where the two diagrams are equal."""
        return ~(self == other)

    def __and__(self, other):
        """Returns a new timing diagram, True where the two diagrams are both True."""
        return self.compare(other, key=operator.and_)

    def __or__(self, other):
        """Returns a new timing diagram, True where either diagram is True."""
        return self.compare(other, key=operator.or_)

    def __xor__(self, other):
        """Returns a new timing diagram, True where the two diagrams are not equal."""
        return self != other

    def __invert__(self):
        """Returns a new timing diagram with states flipped."""
        return TimingDiagram(((t, not s) for t, s in self.timeline.items()))

    def at(self, time):
        """Returns the state at a particular time. Uses bisection for search (binary search)."""
        idx = max(0, self.timeline.bisect(time) - 1)
        return self.timeline.values()[idx]

    def compare(self, other, key):
        """Constructs a new timing diagram based on comparisons between two diagrams,
        with (time, key(self[time], other[time])) for each time in the timelines.
        """
        # TODO: Implement linear algorithm instead of .at() for each time, which is O(n log n).
        return TimingDiagram(
            (
                (k, key(self.at(k), other.at(k)))
                for k in merge(self.timeline.keys(), other.timeline.keys())
            )
        )

    def __repr__(self):
        return f"{self.__class__.__qualname__}({list(self.timeline.items())})"
Ejemplo n.º 4
0
def recheduleMachineFault(jobsListExportPrevious, rescheduleTime,
                          faultyMachine, machinesList):
    pass
    #TODO

    time = {}
    allPreviousOperations = {}
    rescheduleOperations = {}
    rescheduleJobsList = []
    currentTimeOnMachines = {}
    jobsListToExportNew = []
    unchangedOperations = {}
    unscheduleItinerarys = []

    # 遍历机器,生成每个机器前工序集合和需要重调度的工序集合
    for machine in machinesList:
        allPreviousOperations[machine.name] = [
            job for job in jobsListExportPrevious
            if job.assignedMachine == machine.name
        ]
        allPreviousOperations[machine.name].sort(key=lambda j: j.startTime)
        rescheduleOperations[machine.name] = [
            job for job in jobsListExportPrevious
            if job.assignedMachine == machine.name
            and job.startTime >= rescheduleTime
        ]
        rescheduleOperations[machine.name].sort(key=lambda j: j.startTime)

        # 重调度时刻机器时间更新
        unchangedLength = len(allPreviousOperations[machine.name]) - len(
            rescheduleOperations[machine.name])
        unchangedOperations[machine.name] = allPreviousOperations[
            machine.name][0:unchangedLength]

        #如果故障机器上有未完工任务,则把该任务工艺路线后续任务不参与重调度

        currentTimeOnMachines[machine.name] = unchangedOperations[
            machine.name][-1].endTime
        if currentTimeOnMachines[machine.name] < rescheduleTime:
            currentTimeOnMachines[machine.name] = rescheduleTime

        # 初始化各机器时间
        time[currentTimeOnMachines[machine.name]] = {}

        # 更新各机器下重调度工序状态
        unchangedOperations[machine.name][-1].completed = True
        for job in rescheduleOperations[machine.name]:
            job.completed = False

        # 输出无需重调度的任务结果
        for job in unchangedOperations[machine.name]:
            jobsListToExportNew.append(job)

    # 1.先识别出故障机器前未完工任务(包括正在加工的)
    # 2. 遍历上述任务列表:
    #    如果任务可选机器列表长度为1,则重调度任务列表中不加入该任务;
    #    并且记录该任务的工艺路线号,后续是该工艺路线号的任务不参与调度;
    #    否则将任务加入重调度任务列表

    if unchangedOperations[faultyMachine][-1].endTime > rescheduleTime:
        unscheduleItinerarys.append(
            unchangedOperations[faultyMachine][-1].idItinerary)

    # 生成重调度初始列表
    for machine in machinesList:

        for job in rescheduleOperations[machine.name]:
            rescheduleJobsList.append(job)
    rescheduleJobsList.sort(key=lambda j: j.startTime)

    #得到受影响的工艺路线号
    for job in rescheduleOperations[faultyMachine]:
        if len(job.machine) == 1:
            unscheduleItinerarys.append(job.idItinerary)

    #去除受机器故障影响的任务
    rescheduleJobsListUpdate = []
    for job in rescheduleJobsList:
        if job.idItinerary in unscheduleItinerarys:
            continue
        else:
            rescheduleJobsListUpdate.append(job)
    # 机器列表更新
    machinesAvailableList = [
        machine for machine in machinesList if machine.name != faultyMachine
    ]
    allJobsList = jobsListToExportNew + rescheduleJobsListUpdate

    # 调度时间初始化
    time = SortedDict(time)
    while len(jobsListToExportNew) < len(allJobsList):
        for t, operations in time.items():
            operations = GetWaitingOperationsSPT(allJobsList, float(t),
                                                 machinesAvailableList,
                                                 currentTimeOnMachines,
                                                 faultyMachine)

            for keyMach, tasks in operations.items():
                if len(tasks):
                    if float(t) < currentTimeOnMachines[keyMach]:
                        continue
                    tasks[0].startTime = float(t)
                    tasks[0].completed = True
                    tasks[0].assignedMachine = keyMach
                    jobsListToExportNew.append(tasks[0])

                    currentTimeOnMachines[keyMach] = tasks[0].getEndTime()
                    time[currentTimeOnMachines[keyMach]] = {}

            del time[t]
            break
        time = SortedDict(time)  # chronological order
    return jobsListToExportNew