Я упростил версию проблемы, которую я пытаюсь смоделировать, где я использую Simpy для описания движения путешественников по пути.
Путь представлен набором Node()
объектов, гдекаждый узел содержит Simpy.Resource
.Каждый узел связан со следующим узлом в пути с помощью атрибута connected_to
.В примере кода я создал список из 10 узлов, где каждый узел в списке связан с предыдущим узлом в списке.
Когда создается экземпляр путешественника (представленного объектом Occupier()
), этовыделил ресурс узла.Затем путешественник перемещается по узлам, делая шаг только при наличии следующего узла.Моя цель состоит в том, чтобы путешественник одновременно выделил свой конечный узел и освободил узел, где он был ранее расположен.
import simpy
class Node(object):
def __init__(self, env):
self.env = env
self.resource = simpy.Resource(self.env)
self.up_connection = None
self.travel_delay = 5
class Occupier(object):
def __init__(self, env):
self.env = env
self.location = None
self.destination = None
self.requests = []
def travel(self, instantiation_loc):
self.requests.append(instantiation_loc.resource.request())
yield(self.requests[-1])
self.location = instantiation_loc
self.destination = instantiation_loc.up_connection
yield self.env.timeout(self.location.travel_delay)
node_occupancy(nodes)
while self.destination.up_connection != None:
self.requests.append(self.destination.resource.request())
yield self.requests[-1]
self.location.resource.release(self.requests[0])
self.requests.pop(0)
self.location = self.destination
self.destination = self.location.up_connection
yield self.env.timeout(self.location.travel_delay)
node_occupancy(nodes)
def node_occupancy(nodes):
print([node.resource.count for node in nodes])
env = simpy.Environment()
nodes = [Node(env) for i in range(10)]
for i in range(len(nodes) - 1):
nodes[i].up_connection = nodes[i + 1]
env.process(Occupier(env).travel(nodes[0]))
env.run()
Если я запускаю приведенный выше код с одним путешественником, кажется,работает нормально, получая следующий вывод:
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
Однако, если создать экземпляр второго путешественника, вы можете увидеть, что есть моменты времени, когда один путешественник занимает два ресурса, когда он должен занимать только один:
env.process(Occupier(env).travel(nodes[3]))
env.process(Occupier(env).travel(nodes[0]))
соответствующий вывод:
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 1, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 1, 1, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 1, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 1, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 1, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 1, 1, 0]
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0]
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0]
Для моего моделирования важно, чтобы путешественник занимал только один ресурс, так как атрибуты узлов часто изменяются на основе этого.
Есть ли способ предотвратить такое поведение, когда путешественник никогда не занимает более одного ресурса?т.е. ресурс освобождается одновременно, когда путешественнику выделяется новый ресурс