def get_qhull(self, neg_points=[]): """ From a Petrinet, gets it's representationas a Convex Hull """ # Create an empty Convex Hull qhull = Qhull(neg_points=neg_points) # La normal por defaul para cada facet dim = len(self.transitions) tmpl_normal = [0]*dim # Each transition corresponds to one dimension # transition.label -> dimension number transitions = self.event_dictionary # Each facet corresponds to one place # place.id -> {normal->[arc.value], offset->marking} facets_dict = {} # Iteramos sobre los arcos for arc in self.arcs: # No debería haber arcos nulos if not arc.value: logger.error('We found a zero arc: %s',arc) raise Exception('We found a zero arc: %s',arc) # NOTE recordar que nuestra representación interna de HS es # al revés que el paper (usamos <= 0 en lguar de >= 0) if isinstance(arc.source,Transition): # Si el arco sale de una transition el coeficiente es < 0 coef = -1*arc.value transition = arc.source place = arc.destination else: # Si el arco sale de un place el coeficiente es > 0 coef = arc.value place = arc.source transition = arc.destination x = transitions.setdefault(transition.label,len(transitions)) facet = facets_dict.setdefault(place.id,{'normal':list(tmpl_normal), 'in_transitions':[], 'out_transitions':[], 'offset': -1*place.marking, 'id':place.id}) if coef < 0: facet['in_transitions'].append(transition.label) else: facet['out_transitions'].append(transition.label) if facet['normal'][x]: logger.debug('Coeficient already loaded. Dummy place') coef = 0 facet['normal'][x] = coef facets = [] for pl_id, facet in facets_dict.items(): # Do not create the facet for dummy places if not any(facet['normal']): continue # Values are always integer hs = Halfspace(facet['normal'], facet['offset'], integer_vals=False) logger.debug('Adding facet %s',hs) facets.append(hs) qhull.dim = dim qhull.facets = facets return qhull
def get_qhull(self, neg_points=[], allow_dummy=False): """ From a Petrinet, gets it's representationas a Convex Hull """ # Create an empty Convex Hull qhull = Qhull(neg_points=neg_points) # Default normal for every facet dim = len(self.transitions) tmpl_normal = [0]*dim # Each transition corresponds to one dimension # transition.label -> dimension number transitions = self.event_dictionary # Each facet corresponds to one place # place.id -> {normal->[arc.value], offset->marking} facets_dict = {} for arc in self.arcs: # No arc should have zero weight if not arc.value: logger.error('We found a zero arc: %s',arc) raise Exception('We found a zero arc: %s'%arc) # NOTE internal representation for Half Spaces # is A.x <= 0 instead of A.x >= 0 if isinstance(arc.source,Transition): # If the arc starts in a transition, coefficient should be < 0 coef = -1*arc.value transition = arc.source place = arc.destination else: # If the arc starts in a place, coefficient should be > 0 coef = arc.value place = arc.source transition = arc.destination x = transitions.setdefault(transition.label,len(transitions)) facet = facets_dict.setdefault(place.id,{'normal':list(tmpl_normal), 'in_transitions':[], 'in_loop': False, 'out_transitions':[], 'offset': -1*place.marking, 'id':place.id}) if coef < 0: facet['in_transitions'].append(transition.label) else: facet['out_transitions'].append(transition.label) # If coefficient for this facet has already been loaded, # It means we are in a loop. And once we go loop, we never go back if (facet['normal'][x] and allow_dummy) or facet['in_loop']: logger.debug('Coeficient already loaded. Loop found for place %s and transition %s! Dummy place?'%(place,transition)) facet['in_loop'] = True coef = 0 elif facet['normal'][x]: raise Exception('Loop found in place %s and transition %s'%(place,transition)) else: facet['normal'][x] = coef facets = [] for pl_id, facet in facets_dict.items(): # Do not create the facet for dummy places if not any(facet['normal']): continue # Values are always integer hs = Halfspace(facet['normal'], facet['offset'], integer_vals=False) logger.debug('Adding facet %s',hs) facets.append(hs) # Remove duplicate facets facets = list(set(facets)) qhull.dim = dim qhull.facets = facets return qhull