示例#1
0
文件: petrinet.py 项目: Macuyiko/PacH
    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
示例#2
0
    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