APS开源源码解读: 排程工具 frepple

这篇具有很好参考价值的文章主要介绍了APS开源源码解读: 排程工具 frepple。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

https://github.com/frePPLe/frepple/tree/master

class OperatorDelete:
    def __init__(self):
        # Initialize the class

    @classmethod
    def initialize(cls):
        # Initialize the metadata and Python class

    @classmethod
    def create(cls, args, kwds):
        try:
            # Create the solver
            s = OperatorDelete()

            # Iterate over extra keywords and set attributes

            return s
        except Exception as e:
            # Handle exceptions
            pass

    @classmethod
    def solve(cls, v):
        # Implement the solve method
        try:
            # Free Python interpreter for other threads
            Py_BEGIN_ALLOW_THREADS

            # Perform the solving logic
            if v is None:
                # Delete all excess
                self.solve()
            elif isinstance(v, Demand):
                # Delete upstream of a single demand
                self.solve_demand(v)
            elif isinstance(v, Buffer):
                # Delete upstream of a single buffer
                self.solve_buffer(v)
            elif isinstance(v, Resource):
                # Delete upstream of a single resource
                self.solve_resource(v)
            elif isinstance(v, OperationPlan):
                # Delete an operation plan
                self.solve_operation_plan(v)

        except Exception as e:
            # Handle exceptions
            pass
        finally:
            # Reclaim Python interpreter
            Py_END_ALLOW_THREADS

    @classmethod
    def solve_operation_plan(cls, o, v):
        # Implement solve for operation plan
        if not o:
            return  # Null argument passed

        # Mark all buffers.
        # The batching solver doesn't like that we push both consumers and producers,
        # but ideally we would pass true for both arguments.
        self.push_buffers(o, True, False)

        # Delete the operation plan
        if o.get_proposed():
            if self.cmds:
                self.cmds.add(CommandDeleteOperationPlan(o))
            else:
                del o

        # Propagate to all upstream buffers
        while buffersToScan:
            curbuf = buffersToScan.pop()
            self.solve_buffer(curbuf)

    @classmethod
    def solve_resource(cls, r, v):
        # Implement solve for a resource
        if self.get_log_level() > 0:
            print(f"Scanning {r} for excess")

        # Loop over all operation plans on the resource
        for op_plan in r.get_load_plans():
            if op_plan.get_event_type() == 1:
                # Add all buffers into which material is produced to the stack
                self.push_buffers(op_plan, False, True)

        # Process all buffers found, and their upstream colleagues
        while buffersToScan:
            cur_buf = buffersToScan.pop()
            self.solve_buffer(cur_buf)

    @classmethod
    def solve_demand(cls, d, v):
        # Implement solve for a demand
        if self.get_log_level() > 1:
            print(f"Scanning {d} for excess")

        # Delete all delivery operation plans.
        while True:
            # Find a candidate operation plan to delete
            candidate = None
            delivery_plans = d.get_delivery()

            for op_plan in delivery_plans:
                if op_plan.get_proposed():
                    candidate = op_plan
                    break

            if not candidate:
                break

            # Push the buffer on the stack in which the deletion creates excess inventory
            self.push_buffers(candidate, True, False)

            # Delete only the delivery, immediately or through a delete command
            if self.cmds:
                self.cmds.add(CommandDeleteOperationPlan(candidate))
            else:
                del candidate

    @classmethod
    def push_buffers(cls, o, consuming, producing):
        # Implement pushing buffers
        # Loop over all flow plans
        for flow_plan in o.get_flow_plans():
            # Skip flow plans we're not interested in
            if not (
                (consuming and flow_plan.get_quantity() < 0)
                or (producing and flow_plan.get_quantity() > 0)
            ):
                continue

            # Check if the buffer is already found on the stack
            found = False
            for buf in buffersToScan:
                if buf == flow_plan.get_buffer():
                    found = True
                    break

            # Add the buffer to the stack if not found
            if not found:
                buffersToScan.append(flow_plan.get_buffer())

        # Recursive call for all sub-operation plans
        for sub_op_plan in o:
            self.push_buffers(sub_op_plan, consuming, producing)

    @classmethod
    def solve_buffer(cls, b, v):
        # Implement solve for a buffer
        if self.get_log_level() > 1:
            print(f"Scanning buffer {b}")

        # Get the list of flow plans for the buffer
        flow_plans = b.get_flow_plans()
        
        fiter = iter(flow_plans)
        fend = None  # Replace with the actual end condition for the flow plans

        if fiter is fend:
            return  # No flow plans in the buffer

        excess = fiter.get_onhand() - fiter.get_min()

        if excess > ROUNDING_ERROR:
            fiter = iter(flow_plans)
            while excess > ROUNDING_ERROR and fiter is not fend:
                if fiter.get_quantity() <= 0:
                    # Not a producer
                    fiter = iter(fiter)
                    continue

                fp = None
                if fiter.get_event_type() == 1:
                    fp = fiter

                if not fp or not fp.get_operation_plan().get_proposed() or \
                        fp.get_operation_plan().get_demand() or \
                        (fp.get_operation_plan().get_owner() and \
                        fp.get_operation_plan().get_owner().get_demand()) or \
                        fp.get_flow().has_type(FlowTransferBatch):
                    # It's locked or a delivery operation plan
                    fiter = iter(fiter)
                    continue

                cur_excess = b.get_excess(iter(fiter))
                if fp:
                    for flow_plan in fp.get_operation_plan().get_flow_plans():
                        if flow_plan.get_quantity() < ROUNDING_ERROR or \
                                flow_plan.get_buffer() == b or \
                                not flow_plan.get_flow().get_quantity():
                            continue
                        my_excess = (b.get_excess(flow_plan) - \
                                flow_plan.get_flow().get_quantity_fixed()) * \
                                fp.get_flow().get_quantity() / \
                                flow_plan.get_flow().get_quantity()
                        if my_excess >= 0.0 and my_excess < cur_excess:
                            cur_excess = my_excess

                if cur_excess < ROUNDING_ERROR:
                    fiter = iter(fiter)
                    continue

                while fiter is not fend and fiter.get_event_type() == 1 and \
                        fiter.get_operation_plan().get_top_owner() == \
                        fp.get_operation_plan().get_top_owner():
                    fiter = iter(fiter)

                new_size_opplan = None  # Calculate the new size as needed
                new_size_flowplan = None  # Calculate the new size as needed

                if cur_excess < fp.get_flow().get_quantity_fixed() + \
                        fp.get_operation().get_size_multiple() * \
                        fp.get_flow().get_quantity():
                    # This excess is unavoidable
                    fiter = iter(fiter)
                    continue
                elif cur_excess >= fiter.get_quantity() - ROUNDING_ERROR:
                    # Completely delete the producer
                    new_size_opplan = 0.0
                    new_size_flowplan = 0.0
                else:
                    # Resize the producer
                    # We need to keep the operation plan start date constant
                    # during the resize
                    # Calculate new sizes and apply them

                if new_size_flowplan < ROUNDING_ERROR:
                    # The complete operation plan is excess
                    excess -= fiter.get_quantity()
                    self.push_buffers(fp.get_operation_plan(), True, False)

                    if self.cmds:
                        self.cmds.add(CommandDeleteOperationPlan(fp.get_operation_plan()))
                    else:
                        del fp.get_operation_plan()
                else:
                    # Reduce the operation plan
                    # Add upstream buffers to the stack
                    self.push_buffers(fp.get_operation_plan(), True, False)
                    excess -= fiter.get_quantity() - new_size_flowplan

                    # Resize operation plan if needed
                    if self.cmds:
                        # TODO: Adjust the command or operation plan resizing logic
                        self.cmds.add(CommandMoveOperationPlan(
                            fp.get_operation_plan(), Date.infinite_past,
                            fp.get_operation_plan().get_end(), new_size_opplan))
                    else:
                        # Set the new size for the operation plan
                        fp.get_operation_plan().set_quantity(new_size_opplan)

                fiter = iter(fiter)

    @staticmethod
    def solve_python(self, args):
        # Implement the solve method with Python-specific code

  • 关键在于理解buffer的含义以及操作。
  • 有consumer和producing, 数量有正负

Identify Critical Paths: Start by identifying the critical paths in your scheduling process. Critical paths are sequences of tasks that have the least flexibility in terms of start times. These paths are essential to meeting project deadlines or other constraints.

Determine Buffer Locations: Based on your critical paths, identify locations in your schedule where buffers can be introduced. These locations are typically at the end of a critical path or just before a critical constraint.

Size the Buffer: The buffer’s size depends on factors such as variability in task durations, uncertainty in resource availability, and the desired level of risk mitigation. It’s often calculated based on statistical analysis, like the Critical Chain Project Management (CCPM) method or Monte Carlo simulations.

Set Buffer Policies: Define policies that determine when and how the buffer is consumed. Common buffer policies include:

Start Buffer: This is added at the start of the project. It ensures that the project starts on time.
Resource Buffer: This buffer is used to manage resource constraints. It ensures that critical resources are available when needed.
Feeding Buffer: Placed before critical constraints or dependent tasks, this buffer ensures that inputs are available as needed.
Monitoring and Control: Continuously monitor the progress of your project. If tasks start to encroach on the buffer, take action to bring the project back on track. This might involve reallocating resources, addressing bottlenecks, or resequencing tasks.

Buffer Management: The focus should be on protecting the project buffer. If it starts to be consumed, assess why this is happening and take corrective action.

Project Review: After the project is completed, conduct a review to understand why the buffer was consumed. This can help in making improvements for future projects.

Flexibility: Keep in mind that the buffer provides flexibility, but it’s important to strike a balance. Having too much buffer may result in inefficient resource allocation, while too little buffer might not provide enough protection.

In the context of backward scheduling, the buffer helps to ensure that scheduled tasks can start as soon as possible while accounting for constraints and uncertainties. It’s essentially a cushion that provides protection against delays without compromising the overall project timeline. The goal is to optimize the use of resources and time, minimize disruptions, and ensure that the project is completed on time.文章来源地址https://www.toymoban.com/news/detail-753053.html

到了这里,关于APS开源源码解读: 排程工具 frepple的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 开源机器人SmallRobotArm机器人源码解读

    开源机器人SmallRobotArm是一个开源的6轴机械臂,都由步进电机驱动,github地址:https://github.com/SkyentificGit/SmallRobotArm  机器人长这个样子 2 欧拉角及姿态变换 由欧拉角求姿态矩阵 源码中用的欧拉角是ZYZ顺组的欧拉角。 已知世界坐标的坐标(x,y,z)和欧拉角(α,β,γ),求出对应的姿

    2024年02月16日
    浏览(39)
  • H5/APP客服端源码/uniapp在线客服系统源码开源了,全源码代码解读及发行安装教程...

    目前,即时通讯在线咨询在网站、APP、小程序中已经是不可获取的功能,尤其是专注于线上营销的商家,迫切需要一套可以随时与访客交流的即时通讯工具。 如果使用市面上的SaaS客服系统,会在功能上受限制,需要开通高级VIP,才能更好的使用,所以这些商家迫切需要可以

    2024年02月05日
    浏览(40)
  • DDR压力测试工具memtester的源码解读和交叉编译

    最近公司的一款产品,核心板上的DDR由工业级的降为民用的,程序运行过程中容易出现内存泄漏的问题。所以再产品测试流程中增加DDR的压力测试。 使用最流行的开源工具 memtester 但是memtester默认测试循环次数太多,完成一次压力测试需要20多分钟不利于生产测试,于是需要

    2024年02月11日
    浏览(50)
  • PyBullet:一种用 Python 构建的开源 3D 物理模拟工具(教程含源码)

    PyBullet 是一种物理引擎,用于模拟刚体动力学并支持创建逼真的 3D 环境。它基于 Bullet Physics Library,并提供易于使用的界面来模拟各种物理现象。在这篇博文中,我们将探讨 PyBullet 中的用例和可用方法。 PyBullet 在各个行业都有广泛的用例。以下是 PyBullet 的一些最常见用例:

    2024年02月04日
    浏览(37)
  • 【宝藏工具】开源组件信息一键查询,快速获取组件来源、版本、源码地址、漏洞补丁、推荐版本!

    铁子们,分享一个开源组件安全检索 免费工具,需要的自取~ 输入组件名,一键查询可以组件版本、来源、安全状态、漏洞详情和推荐版本、修复建议这些。 点这个链接注册后直接就能用:组件安全检索工具   一键查询第三方组件版本、漏洞、所属国家、所属语言、源码链

    2024年02月06日
    浏览(41)
  • Hive执行计划之只有map阶段SQL性能分析和解读

    目录 目录 概述 1.不带函数操作的select-from-where型简单SQL 1.1执行示例 1.2 运行逻辑分析 1.3 伪代码解释 2.带普通函数和运行操作符的普通型SQL执行计划解读 2.1 执行计划解读 2.2 伪代码解释逻辑 可能所有的SQLboy刚接触SQL语句的时候都是select xxx from xxx where xxx。在hive中,我们把这

    2024年02月08日
    浏览(49)
  • Kettle Local引擎使用记录(一)(基于Kettle web版数据集成开源工具data-integration源码)

    在前面对 data-integration 做了一些简单了解,从部署到应用,今天尝试把后端运行作业代码拎出来,去真正运行一下,只有实操之后才会有更深刻的认识,有些看着简单的功能,实操过程中会遇到很多问题,这个时候你的想法也会发生改变,所以很多时候为什么开发人员痛恨做

    2024年02月02日
    浏览(45)
  • 无人机竞赛视觉算法开发流程开源计划(询问大家意见)

    本科中参加过一系列的无人机机器人竞赛,像电赛、工训赛、机器人大赛这些,有一些比较常用的方案打算开源一下。现在读研了,也算是对本科的一个总结,但是还是想看看大家意见,大家有什么需求可以在评论区说,我会多参考,这周我会先整理,下周会放出博客与git

    2024年02月20日
    浏览(38)
  • Android开源计划-一周开发app,webrtc音视频开发

    题目 – 一周开发app计划 首批参与成员 -小巫 -墨香 -梦痕 -边城刀客 -徐cc 要求 – -每位认领者按照开源规范来做,代码规范和Android开发规范 -每位认领者必须拥有github账号,熟练使用git对代码进来管理 -每个人认领一个功能点或模块 -提出完善的解决方案并提供封装良好的库

    2024年04月08日
    浏览(54)
  • uniapp源码+计划任务 台股平台源码 新股申购

    uniapp源码+计划任务 台股平台源码 新股申购 分类后台控制。 简单测试了一下,可以跑起来。测试时没有配置计划任务和WebSocket 。有兴趣的自行研究。 PHP版本7.3,其他版本提示错误。H5版本访问:域名/index.html 后台地址:域名/houtai.php   用户名密码自行到后台替换。 替换p

    2024年04月17日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包