Python 如何重新组织这些数据?
我有以下意见:Python 如何重新组织这些数据?,python,oop,Python,Oop,我有以下意见: A地平线:周期数 一组资源,每个资源都有一个id和一个使用数组编码的可用性。(例如[3,4,…]指第一个周期内的3个资源单位,第二个周期内的4个资源单位等)。阵列的元素数量等于周期数量(即地平线) 一组命令,每个订单都有发布日期、到期日期和一组任务。 订单的任务不能在该订单的发布日期之前开始,也不能在到期日期之后结束。(我的算法将确定任务的开始时间,它不是输入数据,但访问发布日期和到期日期对于正确确定任务的开始时间很重要) 每个任务都有一个持续时间、后续任务(即一组不能在
- A地平线:周期数
- 一组资源,每个资源都有一个id和一个使用数组编码的可用性。(例如[3,4,…]指第一个周期内的3个资源单位,第二个周期内的4个资源单位等)。阵列的元素数量等于周期数量(即地平线)
- 一组命令,每个订单都有发布日期、到期日期和一组任务。 订单的任务不能在该订单的发布日期之前开始,也不能在到期日期之后结束。(我的算法将确定任务的开始时间,它不是输入数据,但访问发布日期和到期日期对于正确确定任务的开始时间很重要)
- 每个任务都有一个持续时间、后续任务(即一组不能在手头的任务之前启动的任务)、资源需求(例如[0,1,3,…]表示任务需要0个单位的第一个资源、1个单位的第二个资源等)
class Problem:
def __init__(self, horizon, comms, resources):
self.horizon = horizon
self.resources = resources
self.comms = comms
使用这种组织数据的方式会出现很多问题(例如,如果我需要访问有关任务的数据,我需要通过通信来确定它属于哪个订单,然后访问该订单的到期日期、发布日期)。数据非常“嵌套”
我曾想过如下定义Task
对象,但存在冗余(信息同时存在于Task
和Order
中)
其他一些问题:
对于继承者
来说,最好只放置任务的ID还是整个对象的ID
对于资源
要求
。假设一个任务需要[0,1,3,…]1个单位的第二个资源,那么我需要以某种方式与适当的资源id关联,以检查其可用性。如何做到这一点?这可能不是你所问的所有问题的完整答案,但限制性太强,无法将其放入评论中
我的想法是这样的,通过使用order.add_task
和order.remove_task
作为创建和销毁任务的方法,处理任务和订单之间的多对一映射,同时在两个方向上提供引用
它还包括一些健全性检查,以便任务中的实际顺序引用存储在私有变量\u order
中,但可以通过getter属性order
进行访问,这包括健全性检查,以便如果在已将任务从其顺序中删除后仍保留对该任务的引用,然后它将引发一个异常
class Order:
def __init__(self, ....):
...
self.tasks = []
...
def add_task(self, *args, **kwargs):
"""
add a task to this order (should be called with the arguments that
Task.__init__ requires, except for 'order' itself)
"""
task = Task(order=self, *args, **kwargs)
self.tasks.append(task)
return task
def has_task(self, task):
return task in self.tasks
def remove_task(self, task):
"""
Remove task from this order. After calling this,
the task is orphaned and the reference to the task
should be discarded.
"""
self.tasks.remove(task)
class Task:
def __init__(self, order:Order, ...):
...
self._order = order
...
@property
def order(self):
"""
Getter for self._order with sanity checking that
the task is not orphaned.
"""
if not self._order.has_task(self):
raise ValueError("orphaned task")
return self._order
因此,基本上,这样做之后,您不会复制
任务
中的任何其他信息,例如通过任务.order.release\u date
访问的发布日期(任务不应该直接具有发布日期
属性),因为您有对订单对象的引用。唯一的重复是任务和订单之间的双向交叉引用。它不是在Task
中使用order\u id
,而是order
,然后不必从id中查找订单,您只需将其作为task.order
直接访问,然后您仍然可以根据需要获取task.order.id
。我不知道您将首先创建任务
和订单
中的哪一个,但您可以允许任务.订单
或订单.任务
在第二个填充的任何一个中无
。至于发布日期
和到期日期
,我猜该怎么做取决于这些任务在一个订单中是独立的还是完全相同的。如果它们都是相同的,那么只需将其作为订单的属性,然后从任务中通过task.order.release\u date
等进行访问。在order
中,您可能需要一个add\u task
方法,该方法将执行类似task=task(order=self,…);self.tasks.append(任务);return task
@alaniwi这种类型的双向依赖(在任务
对象中将顺序
作为属性,在顺序
对象中将任务
作为属性)危险吗?我想你需要决定哪一种依赖可以不存在另一种。因为它是多对一映射,所以我认为应该允许order有空任务列表,但任务必须始终有一个order。我认为,如果您创建任务的唯一方法是调用命令,则应该没有问题。创建\u task
,并且您销毁任务的唯一方法也是调用类似的命令。remove \u task
方法将其从任务列表中删除。。。(后面还有更多…)感谢您的详细回答。我知道该怎么想了。另一个问题,如何对资源需求信息进行编码?假设任务有一个需求[0,1,3,…]。这里它需要1个单位的第二个资源,然后我需要在某种程度上与适当的资源id相关,以便检查其可用性。如何比使用列表[0,1,3..]更正确地执行此操作?@PatrickK。可能是一个字典,键是资源(或资源id),值是数量…假设需求
是一个dict。例如{“R001”:1,“R005”:3}表示一个任务需要1个单位的R001和3个单位的资源R005。问题是,要访问资源可用性,我需要浏览资源列表(在问题
对象中),并查找具有给定id的资源。@alaniwi,如果我有另一个类问题,它同时具有任务列表和订单列表作为属性,是否被视为冗余?我之所以问这个问题,是因为每个任务都必须以其所属的顺序作为属性,而反过来,顺序又以其任务作为属性。你能看一下这里的详细情况吗?
class Comm:
def __init__(self, id:str, r_date, d_date, ta):
self.id = id
self.r_date = r_date
self.d_date = d_date
self.ta = ta
class Task:
def __init__(self, id:str, dur, succ, requ):
self.id = id
self.dur = dur
self.succ = succ
self.requ = requ
class Task:
def __init__(self, id:str, dur, succ, requ,
order_id:str, r_date, d_date):
self.id = id
self.dur = dur
self.succs = succ
self.requ = requ
self.order_id = order_id
self.r_date = r_date
self.d_date = d_date
class Order:
def __init__(self, ....):
...
self.tasks = []
...
def add_task(self, *args, **kwargs):
"""
add a task to this order (should be called with the arguments that
Task.__init__ requires, except for 'order' itself)
"""
task = Task(order=self, *args, **kwargs)
self.tasks.append(task)
return task
def has_task(self, task):
return task in self.tasks
def remove_task(self, task):
"""
Remove task from this order. After calling this,
the task is orphaned and the reference to the task
should be discarded.
"""
self.tasks.remove(task)
class Task:
def __init__(self, order:Order, ...):
...
self._order = order
...
@property
def order(self):
"""
Getter for self._order with sanity checking that
the task is not orphaned.
"""
if not self._order.has_task(self):
raise ValueError("orphaned task")
return self._order