Example #1
0
def reduce_automaton(waut, wvalues, evtdata, num_res, start = None):
    """
    Reduce the weighted automaton.

    @param waut: (Weighted) automaton (the weight is not used).
    @type  waut: L{Automaton}

    @param wvalues: Column matrix data, associated with each state in L{waut}.
    @type  wvalues: L{maxplus.DataCollection}

    @param evtdata: Event information.
    @type  evtdata: L{EventData}

    @param num_res: Number of resources.
    @type  num_res: C{int}

    @param start: Start vector (row-matrix), if specified.
    @type  start: C{None}, or L{maxplus.DataCollection}

    @return: Reduced automaton.
    @rtype:  L{Automaton}
    """
    waut = waut.copy() # Make a copy
    wvalues = dict((st.number, val) for st, val in wvalues.iteritems())

    # Do a breadth-first expansion over the automaton.

    #: Mapping of states to their row matrix value.
    seen_states = set([waut.initial])
    not_done = [waut.initial]

    while len(not_done) > 0:
        # Since we do a breadth-first expansion, make a new 'not_done'
        # from scratch on each iteration.
        new_not = []
        for state in not_done:
            rval = maxplus.make_rowmat(0, num_res)
            sval = maxplus.otimes_mat_mat(rval, wvalues[state.number])

            for edge in list(state.get_outgoing()):
                result = maxplus.otimes_mat_mat(rval,
                                                evtdata[edge.label].matHat)
                cm = maxplus.otimes_mat_mat(result, wvalues[edge.succ.number])
                if cm.get_scalar() <= sval.get_scalar():
                    # Keep the edge.
                    if edge.succ not in seen_states: # It is a new state.
                        seen_states.add(edge.succ)
                        new_not.append(edge.succ)
                else:
                    # Drop the edge.
                    waut.remove_edge(edge)

        # Next iteration.
        not_done = new_not

    waut.reduce(True, True)
    return waut
Example #2
0
def calcpath_mult(auts, eventdata, heap_len):
    pathstatetup = [aut.initial for aut in auts]
    weight = maxplus.matrix_to_vector(maxplus.make_rowmat(0, heap_len))
    wavers = 0
    alphabet = set()
    for aut in auts:
        alphabet.update(aut.alphabet)
    newwaver = None
    #newwaver = aut.collection.events['NewWaver']
    while not (allmarked(pathstatetup) and wavers == 0):
        possibleedges = None
        beststart = None
        cannewwaver = None
        successors = []
        for state in pathstatetup:
            successors.append(
                {edge.label: edge.succ
                 for edge in state.get_outgoing()})
        act_successors = []
        for evt in alphabet:
            successor_tup = []
            for i, dictionary in enumerate(successors):
                if evt not in auts[i].alphabet:
                    successor_tup.append(pathstatetup[i])
                elif evt not in dictionary:
                    successor_tup = None
                    break
                else:
                    successor_tup.append(dictionary[evt])
            if successor_tup:
                act_successors.append((evt, successor_tup))
        for tup in act_successors:
            event, pathstate = tup
            if event == newwaver:
                cannewwaver = tup
                continue
            soonestfire = calcstarttime(weight, eventdata[event].used)
            if beststart == None or soonestfire < beststart:
                soonestfire = beststart
                possibleedges = [tup]
            elif beststart == soonestfire:
                possibleedges.append(tup)
        if wavers != 0 and cannewwaver != None and (
                beststart == None or
                beststart >= calcstarttime(weight, eventdata[newwaver].used)):
            wavers -= 1
            possibleedges = [cannewwaver]
        index = random.randrange(len(possibleedges))
        tup = possibleedges[index]
        event = tup[0]
        pathstatetup = tup[1]
        weight = maxplus.newtimes_vec_vec(weight, eventdata[event].matHat)
        print event
        print weight
    print "weight: " + str(weight)
Example #3
0
def row_vector_compute(plant, req_names, evt_pairs, row_vector_names,
                       operator_class):
    coll = collection.Collection()
    comp_list = weighted_frontend.load_weighted_automata(
        coll, plant, False, True)
    req_list = frontend.load_automata(coll, req_names, False, True)
    evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs)
    result = taskresource.compute_custom_eventdata(comp_list, evt_pairs)
    if result is None:
        common.print_line('Could not compute the event data from the '
                          'components and event pairs\n'
                          'Perhaps they are inconsistent?')
        return

    eventdata, heap_len = result

    plant = weighted_product.n_ary_weighted_product(
        comp_list, algorithm.EQUAL_WEIGHT_EDGES)
    requirement = product.n_ary_unweighted_product(req_list)

    for comp in comp_list:
        comp.clear()
    del comp_list

    wsup = compute_weight.compute_weighted_supremal(plant, requirement)
    if wsup is None:
        return None
    requirement.clear()
    del requirement

    row_zero_mat = maxplus.make_rowmat(0, heap_len)
    row_epsilon_mat = maxplus.make_rowmat(maxplus.INFINITE, heap_len)

    marker_valfn = lambda state: row_zero_mat
    nonmarker_valfn = lambda state: row_epsilon_mat

    row_vecs = compute_state_row_vector(wsup, marker_valfn, nonmarker_valfn,
                                        eventdata, operator_class)

    return row_vecs
Example #4
0
def make_greedy_time_optimal_supervisor_row_vectors(comp_names, req_names,
                                                    evt_pairs, sup_name,
                                                    row_vectors, operator):
    """
    Compute a greedy time optimal supervisor.

    @param comp_names: Available components (weighted automata).
    @type  comp_names: C{list} of L{str}

    @param req_names: Available requirements (unweighted automata).
    @type  req_names: C{list} of L{str}

    @param evt_pairs: Additional event pairs (eg "{(a, b), (c, e)}", "type1",
                      or "type2")
    @type  evt_pairs: C{str}

    @param sup_name: Name of the resulting supervisor.
    @type  sup_name: C{str}
    """
    common.print_line("Started greedy time optimal supervisor "
                      "computation (version %s)" % automata.version)
    coll = collection.Collection()
    comp_list = load_weighted_automata(coll, comp_names, False, True)
    req_list = frontend.load_automata(coll, req_names, False, True)

    evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs)

    result = taskresource.compute_custom_eventdata(comp_list, evt_pairs)
    if result is None:
        common.print_line('Could not compute the event data from the '
                          'components and event pairs\n'
                          'Perhaps they are inconsistent?')
        return

    eventdata, heap_len = result
    result = compute_weight.compute_greedy_time_optimal_supervisor(
        comp_list, req_list, eventdata, heap_len, row_vectors, operator)
    if result is None:
        common.print_line('Could not compute the weighted supervisor')
        return

    wsup, wmap = result
    one = maxplus.make_rowmat(0, heap_len)
    one = maxplus.otimes_mat_mat(one, wmap[wsup.initial])
    biggest = one.get_scalar()
    common.print_line("Sub-optimal makespan is %s" % biggest)

    wsup = weighted_supervisor.reduce_automaton_row_vecors(
        wsup, wmap, eventdata, heap_len, row_vectors)

    frontend.dump_stats("Computed weighted supervisor", wsup)
    save_weighted_automaton(wsup, "Supervisor is saved in %s\n", sup_name)
Example #5
0
def enhanced_row_vector_compute(plant, req_names, evt_pairs, row_vector_names,
                                operator_class):
    coll = collection.Collection()
    comp_list = weighted_frontend.load_weighted_automata(
        coll, plant, False, True)
    req_list = frontend.load_automata(coll, req_names, False, True)
    evt_pairs = taskresource.process_event_pairs(coll, req_list, evt_pairs)
    result = taskresource.compute_custom_eventdata(comp_list, evt_pairs)
    if result is None:
        common.print_line('Could not compute the event data from the '
                          'components and event pairs\n'
                          'Perhaps they are inconsistent?')
        return

    eventdata, heap_len = result

    plant = do_n_ary_product_map(comp_list)
    for comp in comp_list:
        comp.clear()
    del comp_list

    wsup = plant.get_automaton()
    if wsup is None:
        return None

    row_zero_mat = maxplus.make_rowmat(0, 1)
    row_epsilon_mat = maxplus.make_rowmat(maxplus.INFINITE, 1)

    marker_valfn = lambda state: row_zero_mat
    nonmarker_valfn = lambda state: row_epsilon_mat

    row_vecs = enhance_compute_state_row_vector(wsup, marker_valfn,
                                                nonmarker_valfn, eventdata,
                                                operator_class)

    return row_vecs
Example #6
0
def calcpath(aut, eventdata, heap_len, num):
    pathstate = aut.initial
    weight = maxplus.matrix_to_vector(maxplus.make_rowmat(0, heap_len))
    wavers = num
    #newwaver = aut.collection.events["R1-pick-C"]
    if "NewWaver" in aut.collection.events:
        newwaver = aut.collection.events["NewWaver"]
    else:
        newwaver = None
    procevent = aut.collection.events["R1-drop-C"]
    processed = 0
    #newwaver = None
    while not (pathstate.marked and wavers == 0):
        possibleedges = None
        beststart = None
        cannewwaver = None
        for edge in pathstate.get_outgoing():
            if edge.label == newwaver:
                cannewwaver = edge
                continue
            pathstate = edge.succ
            event = edge.label
            soonestfire = calcstarttime(weight, eventdata[event].used)
            if beststart == None or soonestfire < beststart:
                soonestfire = beststart
                possibleedges = [edge]
            elif beststart == soonestfire:
                possibleedges.append(edge)
        if wavers != 0 and cannewwaver != None and (
                beststart == None or
                beststart >= calcstarttime(weight, eventdata[newwaver].used)):
            wavers -= 1
            possibleedges = [cannewwaver]
        index = random.randrange(len(possibleedges))
        edge = possibleedges[index]
        event = edge.label
        #print event
        pathstate = edge.succ
        weight = maxplus.newtimes_vec_vec(weight, eventdata[event].matHat)
        if event == procevent:
            processed += 1
    print "weight: " + str(weight) + " processed: num"
Example #7
0
def heap_unfold_product(aut_list, eventdata, heap_len, distances_to_marker, shortest_path):
    result_alphabet = set()
    for aut in aut_list:
        result_alphabet.update(aut.alphabet)
    plant = data_structure.Automaton(result_alphabet, aut_list[0].collection)
    mapping = {}
    heap_map = {}
    aut_resource_usage = calc_resource_usage(aut_list, eventdata, heap_len)
    initial_state_mapping = tuple(aut.initial for aut in aut_list)
    initial_state = plant.add_new_state(marker_calc(initial_state_mapping))
    plant.set_initial(initial_state)
    mapping[initial_state] = initial_state_mapping
    heap_map[initial_state] = maxplus.make_rowmat(0, heap_len)
    shortest_path_max = 0
    for comp, path in shortest_path.items():
        if path > shortest_path_max:
            shortest_path_max = path
    
    traverse(comp_list, plant, initial_state, mapping, heap_map, eventdata, aut_resource_usage, distances_to_marker, shortest_path_max)
    return plant