def benchmark_random_n_nodes(n, k, iterations=3, step=10, plot=False, path=""):
    """
    Benchmarks the classical algorithm for generalized parity games using a random game arenas generator.
    Arenas of size n with 1 to k priority functions are solved.
    :param n: number of nodes in generated graph.
    :param k: number of priority functions in the generated graph.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(2, k + 1, step):
        g = generators.random_generalized(n, i, n, 1, n/2)
        temp = []
        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                generalized_parity_solver(g)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        total_time += min_recording

        print "Random graph".center(40) + "|" + str(i).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

        # at the end, print total time
    print "-" * 108 + "\n" + "Total time".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"

    if plot:
        plt.grid(True)
        plt.title(u"Random graph of size " + str(100)+" with 1 to "+str(k)+" priority functions")
        plt.xlabel(u'number of nodes')
        plt.ylabel(u'time (s)')
        points, = plt.plot(n_, y, 'g.', label=u"Execution time")
        plt.legend(loc='upper left', handles=[points])
        plt.savefig(path)
        plt.clf()
        plt.close()
예제 #2
0
def benchmark_ladder_wc(n, iterations=3, step=10, plot=False, path="", save_res = False, path_res = "", prt = True):
    """
    Benchmarks the window parity algorithms for strong parity games using the random game generator.
    Calls window parity partial solver on games generated using the random game generator function.
    Games of size 1 to n are solved and a timer records the time taken to get the solution.The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time
    spikes and delays due to system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph (nodes is n due to construction).
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    :param save_res: if True, save the results on a file.
    :param path_res: path to the file in which to write the result.
    :param prt: True if the prints are activated.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (1 to n)
    per_sol = [] # list for the percentage of the game solved

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    not_comp_solved = [] #store the game that are not completely solved

    # print first line of output
    if prt:
        print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "|" + "Percentage solved".center(19) + "|" + "\n" + \
            "-" * 115

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generators.ladder(i)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                (w0, w1) = winningcore.partial_solver(g)  # winning core call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        percent_solved = ((float(len(w0)) + len(w1)) /(i)) * 100
        if percent_solved != 100:
            not_comp_solved.append((g, w0, w1))

        y.append(min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        per_sol.append(percent_solved)
        total_time += min_recording
        

        if prt:
            print "Ladder graph".center(40) + "|" + str(i).center(12) + "|" \
            + str(y[nbr_generated]).center(40) + "|" + str(percent_solved).center(19) + "|" + "\n" + "-" * 115

        nbr_generated += 1  # updating the number of generated mesures


    # at the end, print total time
    if prt:
        print "-" * 115 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
            str(total_time).center(40) + "|" + "\n" + "-" * 115 + "\n"

    if plot:
        fig, ax1 = plt.subplots()
        plt.grid(True)
        plt.title(u"Graphes Ladder de taille 1 à " + str(n))
        plt.xlabel(u'nombre de nœuds')
        # plt.yscale("log") allows logatithmic y-axis
        ax1.plot(n_, y, 'g.', label=u"Temps d'exécution", color='b')
        ax1.tick_params('y', colors='b')
        ax1.set_ylabel("Temps d'execution (s)", color = 'b')

        ax2 = ax1.twinx()
        ax2.plot(n_, per_sol, 'g.', label=u"Pourcentage résolu", color='r')
        ax2.set_ylim([0, 101])
        ax2.set_ylabel("Pourcentage du jeu resolu (%)", color = 'r')
        ax2.tick_params('y', colors='r')
        fig.tight_layout()

        plt.savefig(path+".png", bbox_inches='tight')
        plt.clf()
        plt.close()

    if save_res:
        #computing the percent solved for each player for the games not solved completely
        part_solv = 0
        comp_solv = 0
        percent_solv = []
        for (g, w0, w1) in not_comp_solved:
            #one more game not solved completely
            part_solv += 1
            #checking is the solutions are included to the true solutions. Computing the true sols with Zielonka algorithm
            (sp_w0, sp_w1) = sp(g)
            a =  all(s in sp_w1 for s in w1) #cheking if included
            b =  all(s in sp_w0 for s in w0) #cheking if included
            #if not included stop the algorithm 
            if not a or not b:
                print "Error the solutions found are not included to the true solutions"
                return -1
            #total percentage solved
            percent_solved_total = ((float(len(w0)) + len(w1)) /(len(sp_w0) + len(sp_w1))) * 100 
            #percentage solved for player 0
            if len(sp_w0) > 0:
                percent_solved_0 = (float(len(w0)) /len(sp_w0)) * 100
            else:
                percent_solved_0 = 100
            #percentage solved for player 1
            if len(sp_w1) > 0:
                percent_solved_1 = (float(len(w1)) /len(sp_w1)) * 100
            else:
                percent_solved_1 = 100
            #adding the percentages computed to the list + the size of the game
            percent_solv.append((len(g.get_nodes()), percent_solved_total, percent_solved_0, percent_solved_1))

        comp_solv += n/step - len(not_comp_solved)

        io.write_benchmark_partial_solver(comp_solv, part_solv, percent_solv, path_res+".txt", n_, y, n, 1, -1, False, "")
def benchmark(n, generator, iterations=3, step=10, plot=False, regression=False, order=1, path="", title=""):
    """
    General benchmarking function. Calls weak parity solver on games generated using the provided generator function.
    Games of size 1 to n are solved and a timer records the time taken to get the solution. The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time spikes
    and delays due to system load). The result as well as a regression can be plotted using matplotlib.
    :param n: number of nodes in generated graph.
    :param generator: graph generator function.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param regression: if True, plots a polynomial regression along with the data.
    :param order: order of that regression.
    :param path: path to the file in which to write the result.
    :param title: the title to be used in the plot.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (1 to n)

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n with a certain step
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generator(i)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                weak_parity_solver(g)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        total_time += min_recording

        print generator.__name__.center(40) + "|" + str(i).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

    # at the end, print total time
    print "-" * 108 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"

    # if we need to plot
    if plot:
        plt.grid(True)
        if title != "":
            plt.title(title)
        else:
            plt.title(u"Générateur : " + str(generator.__name__).replace("_", " "))
        plt.xlabel(u'nombre de nœuds')
        plt.ylabel(u'temps (s)')
        if regression:
            coeficients = np.polyfit(n_, y, order)
            polynom = np.poly1d(coeficients)
            points, = plt.plot(n_, y, 'g.', label=u"Temps d'exécution")
            fit, = plt.plot(n_, polynom(n_), 'b--', alpha=0.6, label=u"Régression polynomiale de degré " + str(order))
            plt.legend(loc='upper left', handles=[points, fit])
        else:
            points, = plt.plot(n_, y, 'g.', label=u"Temps d'exécution")
            plt.legend(loc='upper left', handles=[points])

        plt.savefig(path, bbox_inches='tight')
        plt.clf()
        plt.close()
예제 #4
0
def benchmark_worst_case_wp(n, start_lambda = 1, end_lambda = 10, step_lambda = 1, dir = True, v2 = False, iterations=3, step=10, plot=False, path="", save_res = False, path_res = "", prt = True):
    """
    Benchmarks the window parity algorithms for strong parity games using the random game generator.
    Calls window parity partial solver on games generated using the random game generator function.
    Games of size 1 to n are solved and a timer records the time taken to get the solution.The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time
    spikes and delays due to system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph (nodes is n due to construction).
    :param end_lambda: maximum value of lambda.
    :param start_lambda: starting value of lambda.
    :param step_lambda: step to be taken between the different value of lambda.
    :param dir: if True, uses DirFixWP if not, uses FixWP.
    :param v2: if True, uses partial_solver2. If False, uses partial_solver.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    :param save_res: if True, save the results on a file.
    :param path_res: path to the file in which to write the result.
    :param prt: True if the prints are activated.
    :return: Percentage of game solved, size of the games such that we return the time taken to resolve those games.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (5 to 5n)
    per_sol = [] # list for the percentage of the game solved

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    lam = start_lambda #current lambda used by the algorithme

    not_comp_solved = [] #store the game that are not completely solved

    # print first line of output
    if prt:
        print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "|" + "Percentage solved".center(19) + "|" + "\n" + \
          "-" * 115

    #for each value of lambda
    for lam in range(start_lambda, end_lambda + 1, step_lambda):
        #print current value of lambda
        if prt:
            print "lambda value : ".center(40) + str(lam) + "\n" + "-" * 115
        y_temp = [] # stores time recordings for the current value of lambda
        n_temp = [] # stores the size of the game for the current value of lambda 
        per_sol_temp = [] #stores the resolution percentage of the games for the current value of lambda
        nbr_generated = 0      
        # games generated are size 1 to 5*n
        for i in range(1, n + 1, step):
            temp = []  # temp list for #iterations recordings
            g = generators.strong_parity_worst_case(i)  # generated game

            # #iterations calls to the solver are timed
            for j in range(iterations):
                with chrono:
                    if dir:
                        if v2:
                            (w0, w1) = dirfixwp.partial_solver2(g, lam)  # dirfixwp version 2 call
                        else:
                            (w0, w1) = dirfixwp.partial_solver(g, lam)  # dirfixwp call
                    else:
                        if v2:
                            (w0, w1) = fixwp.partial_solver2(g, lam)  # fixwp version 2 call
                        else:
                            (w0, w1) = fixwp.partial_solver(g, lam)  # fixwp call
                temp.append(chrono.interval)  # add time recording

            min_recording = min(temp)
            total_time += min_recording
            percent_solved = ((float(len(w0)) + len(w1)) /(i*5)) * 100
            #checking if completely solved
            if percent_solved != 100:
                not_comp_solved.append((g, w0, w1))

            y_temp.append(min_recording)  # get the minimum out of #iterations recordings
            n_temp.append(5 * i)
            per_sol_temp.append(percent_solved)

            if prt:
                print "Worst-case graph".center(40) + "|" + str(i * 5).center(12) + "|" \
                + str(y_temp[nbr_generated]).center(40) + "|" + str(percent_solved).center(19) + "|" + "\n" + "-" * 115

            nbr_generated += 1  # updating the number of generated mesures

        y.append(y_temp)
        n_.append(n_temp)
        per_sol.append(per_sol_temp)

    # at the end, print total time
    if prt:
        print "-" * 115 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
        str(total_time).center(40) + "|" + "\n" + "-" * 115 + "\n"

    if plot:
        i = 0
        for lam in range(start_lambda, end_lambda + 1, step_lambda):
            fig, ax1 = plt.subplots()
            plt.grid(True)
            plt.title(u"Graphes pires cas de taille 1 à " + str(5*n) + " avec lambda = " + str(lam))
            plt.xlabel(u'nombre de nœuds')
            # plt.yscale("log") allows logatithmic y-axis
            ax1.plot(n_[i], y[i], 'g.', label=u"Temps d'exécution", color='b')
            ax1.tick_params('y', colors='b')
            ax1.set_ylabel("Temps d'execution (s)", color = 'b')

            ax2 = ax1.twinx()
            ax2.plot(n_[i], per_sol[i], 'g.', label=u"Pourcentage résolu", color='r')
            ax2.set_ylim([0, 101])
            ax2.set_ylabel("Pourcentage du jeu resolu (%)", color = 'r')
            ax2.tick_params('y', colors='r')
            fig.tight_layout()

            plt.savefig(path+str(lam)+".png", bbox_inches='tight')
            plt.clf()
            plt.close()
            i = i + 1

    #save the percent solve for each player for each lambda for each size of game in a txt file
    if save_res:
        i = 0
        for lam in range(start_lambda, end_lambda + 1, step_lambda):
            #computing the percent solved for each player for the games not solved completely
            part_solv = 0
            comp_solv = 0
            percent_solv = []
            for (g, w0, w1) in not_comp_solved:
                #one more game not solved completely
                part_solv += 1
                #checking is the solutions are included to the true solutions. Computing the true sols with Zielonka algorithm
                (sp_w0, sp_w1) = sp(g)
                a =  all(s in sp_w1 for s in w1) #cheking if included
                b =  all(s in sp_w0 for s in w0) #cheking if included
                #if not included stop the algorithm 
                if not a or not b:
                    print "Error the solutions found are not included to the true solutions"
                    return -1
                #total percentage solved
                percent_solved_total = ((float(len(w0)) + len(w1)) /(len(sp_w0) + len(sp_w1))) * 100 
                #percentage solved for player 0
                if len(sp_w0) > 0:
                    percent_solved_0 = (float(len(w0)) /len(sp_w0)) * 100
                else:
                    percent_solved_0 = 100
                #percentage solved for player 1
                if len(sp_w1) > 0:
                    percent_solved_1 = (float(len(w1)) /len(sp_w1)) * 100
                else:
                    percent_solved_1 = 100
                #adding the percentages computed to the list + the size of the game
                percent_solv.append((len(g.get_nodes()), percent_solved_total, percent_solved_0, percent_solved_1))
    
            comp_solv += 5*n/step - len(not_comp_solved)

            io.write_benchmark_partial_solver(comp_solv, part_solv, percent_solv, path_res+"_"+str(lam)+".txt", n_[i], y[i], 5*n, 1, lam, False, "")
예제 #5
0
def benchmark_random_wp(n, start_lambda = 1, end_lambda = 10, step_lambda = 1, dir = True, v2 = False, iterations=3, step=10, ret = False, plot=False, path="", prt = True):
    """
    Benchmarks the window parity algorithms for strong parity games using the random game generator.
    Calls window parity partial solver on games generated using the random game generator function.
    Games of size 1 to n are solved and a timer records the time taken to get the solution.The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time
    spikes and delays due to system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph (nodes is n due to construction).
    :param end_lambda: maximum value of lambda.
    :param start_lambda: starting value of lambda.
    :param step_lambda: step to be taken between the different value of lambda.
    :param dir: if True, uses DirFixWP if not, uses FixWP.
    :param v2: if True, uses partial_solver2. If False, uses partial_solver.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param ret: if True, return the winning region of the games that were not completely solved.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    :param prt: True if the prints are activated.
    :return: Percentage of game solved, size of the games such that we return the time taken to resolve those games.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (1 to n)
    per_sol = [] # list for the percentage of the game solved

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    lam = start_lambda #current lambda used by the algorithme

    not_comp_solved = [] #store the game that are not completely solved

    # print first line of output
    if prt:
        print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "|" + "Percentage solved".center(19) + "|" + "\n" + \
            "-" * 115

    #for each value of lambda
    for lam in range(start_lambda, end_lambda + 1, step_lambda):
        #print current value of lambda
        if prt:
            print "lambda value : ".center(40) + str(lam) + "\n" + "-" * 115
        y_temp = [] # stores time recordings for the current value of lambda
        n_temp = [] # stores the size of the game for the current value of lambda 
        per_sol_temp = [] #stores the resolution percentage of the games for the current value of lambda
        nbr_generated = 0
        # games generated are size 1 to n
        for i in range(1, n + 1, step):
            temp = []  # temp list for #iterations recordings
            prio = randint(0, i)  # number of priorities
            min_out = randint(1, i) # minimum number of out edges
            max_out = randint(min_out, i) #maximum number of out edges
            g = generators.random(i, prio, min_out, max_out)  # generated game

            # #iterations calls to the solver are timed
            for j in range(iterations):
                with chrono:
                    if dir:
                        if v2:
                            (w0, w1) = dirfixwp.partial_solver2(g, lam)  # dirfixwp version 2 call
                        else:
                            (w0, w1) = dirfixwp.partial_solver(g, lam)  # dirfixwp call
                    else:
                        if v2:
                            (w0, w1) = fixwp.partial_solver2(g, lam)  # fixwp version 2 call
                        else:
                            (w0, w1) = fixwp.partial_solver(g, lam)  # fixwp call
                temp.append(chrono.interval)  # add time recording

            min_recording = min(temp)
            percent_solved = ((float(len(w0)) + len(w1)) /(i)) * 100
            #checking if completely solved
            if percent_solved != 100:
                not_comp_solved.append((g, w0, w1))

            y_temp.append(min_recording)  # get the minimum out of #iterations recordings
            n_temp.append(i) 
            per_sol_temp.append(percent_solved)
            total_time += min_recording
            

            if prt:
                print "Random graph".center(40) + "|" + str(i).center(12) + "|" \
                + str(y_temp[nbr_generated]).center(40) + "|" + str(percent_solved).center(19) + "|" + "\n" + "-" * 115

            nbr_generated += 1  # updating the number of generated mesures
        y.append(y_temp)
        n_.append(n_temp)
        per_sol.append(per_sol_temp)


    # at the end, print total time
    if prt:
        print "-" * 115 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "|" + "\n" + "-" * 115 + "\n"

    if plot:
        i = 0
        for lam in range(start_lambda, end_lambda + 1, step_lambda):
            fig, ax1 = plt.subplots()
            plt.grid(True)
            plt.title(u"Graphes aléatoires de taille 1 à " + str(n) + " avec lambda = " + str(lam))
            plt.xlabel(u'nombre de nœuds')
            # plt.yscale("log") allows logatithmic y-axis
            ax1.plot(n_[i], y[i], 'g.', label=u"Temps d'exécution", color='b')
            ax1.tick_params('y', colors='b')
            ax1.set_ylabel("Temps d'execution (s)", color = 'b')

            ax2 = ax1.twinx()
            ax2.plot(n_[i], per_sol[i], 'g.', label=u"Pourcentage résolu", color='r')
            ax2.set_ylim([0, 101])
            ax2.set_ylabel("Pourcentage du jeu resolu (%)", color = 'r')
            ax2.tick_params('y', colors='r')
            fig.tight_layout()

            plt.savefig(path+str(lam)+".png", bbox_inches='tight')
            plt.clf()
            plt.close()
            i = i + 1

    if ret:
        return (not_comp_solved, (n_, y))
예제 #6
0
def compare_algorithms3(algo1,
                        algo2,
                        algo3,
                        generator,
                        n,
                        preprocess1=None,
                        preprocess2=None,
                        preprocess3=None,
                        iterations=3,
                        step=10,
                        plot=False,
                        path="",
                        title="Comparison",
                        label1="Algorithm 1",
                        label2="Algorithm2",
                        label3="Algorithm3"):
    """
            Benchmarks the recursive algorithm for strong parity games using the worst case generator which yields an
            exponential complexity. Calls strong parity solver on games generated using the worst case generator function.
            Games of size 5 to 5*n are solved and a timer records the time taken to get the solution.The solver can be timed
            several times and the minimum value is selected using optional parameter iterations (to avoid recording time
            spikes and delays due to system load). The result can be plotted using matplotlib.
            :param n: number of nodes in generated graph (nodes is 5*n due to construction).
            :param iterations: number of times the algorithm is timed (default is 3).
            :param step: step to be taken in the generation.
            :param plot: if True, plots the data using matplotlib.
            :param path: path to the file in which to write the result.
            """

    y1 = []  # list for the time recordings of algorithm 1
    n1 = []  # list for the x values of algorithm 1
    y2 = []  # list for the time recordings of algorithm 2
    n2 = []  # list for the x values of algorithm 2
    y3 = []  # list for the time recordings of algorithm 3
    n3 = []  # list for the x values of algorithm 3

    chrono = timer.Timer(verbose=False)  # Timer object

    # games generated are size 1 to n
    for i in range(5, n, step):
        temp1 = []  # temp list for #iterations recordings of algorithm 1
        g1 = generator(i)  # game generation
        g2 = copy.deepcopy(g1)
        g3 = copy.deepcopy(g1)

        if preprocess1 is not None:
            g1 = preprocess1(g1)

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                solution_regular = algo1(g1)
            temp1.append(chrono.interval)  # add time recording

        min_recording = min(temp1)
        y1.append(
            min_recording)  # get the minimum out of #iterations recordings
        n1.append(i)

        if preprocess2 is not None:
            g2 = preprocess2(g2)

        g2, nbr_nodes = transform_graph_into_c_spec(g2)

        temp2 = []
        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                #algo2(u[0],u[1],u[2],u[3])  # solver call
                solution_symbolic = algo2(g2, nbr_nodes, 0)
            temp2.append(chrono.interval)  # add time recording

        min_recording = min(temp2)
        y2.append(
            min_recording)  # get the minimum out of #iterations recordings
        n2.append(i)

        temp3 = []  # temp list for #iterations recordings of algorithm 1
        if preprocess3 is not None:
            g3 = preprocess3(g3)
        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                solution_third = algo3(g3)
            temp3.append(chrono.interval)  # add time recording

        min_recording = min(temp3)
        y3.append(
            min_recording)  # get the minimum out of #iterations recordings
        n3.append(i)

        #print("symb "+str(solution_symbolic[0])+" "+str(solution_symbolic[1]))
        #print("reg  "+str(solution_regular[0])+" "+str(solution_regular[1]))

    if plot:
        plt.grid(True)
        plt.title(title)
        plt.xlabel(u'number of nodes')
        plt.ylabel(u'time')

        # plt.yscale("log") allows logatithmic y-axis
        points, = plt.plot(n1, y1, 'g.', label=label1)
        points2, = plt.plot(n2, y2, 'r.', label=label2)
        points3, = plt.plot(n3, y3, 'b.', label=label3)

        plt.legend(loc='upper left', handles=[points, points2, points3])
        plt.savefig(path, bbox_inches='tight')
        plt.clf()
        plt.close()
예제 #7
0
def benchmark_random_wc(n, iterations=3, step=10, ret = False, plot=False, path="", prt = True):
    """
    Benchmarks the window parity algorithms for strong parity games using the random game generator.
    Calls window parity partial solver on games generated using the random game generator function.
    Games of size 1 to n are solved and a timer records the time taken to get the solution.The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time
    spikes and delays due to system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph (nodes is n due to construction).
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param ret: if True, return the winning region of the games that were not completely solved.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    :param prt: True if the prints are activated.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (1 to n)
    per_sol = [] # list for the percentage of the game solved

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    not_comp_solved = [] #store the game that are not completely solved

    # print first line of output
    if prt:
        print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "|" + "Percentage solved".center(19) + "|" + "\n" + \
            "-" * 115

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        prio = randint(0, i)  # number of priorities
        min_out = randint(1, i) # minimum number of out edges
            max_out = randint(min_out, i) #maximum number of out edges
        g = generators.random(i, prio, min_out, max_out)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                (w0, w1) = winningcore.partial_solver(g)  # winning core call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        percent_solved = ((float(len(w0)) + len(w1)) /(i)) * 100
        if percent_solved != 100:
            not_comp_solved.append((g, w0, w1))

        y.append(min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        per_sol.append(percent_solved)
        total_time += min_recording
        

        if prt:
            print "Random graph".center(40) + "|" + str(i).center(12) + "|" \
            + str(y[nbr_generated]).center(40) + "|" + str(percent_solved).center(19) + "|" + "\n" + "-" * 115

        nbr_generated += 1  # updating the number of generated mesures
def benchmark_worst_case(n, iterations=3, step=10, plot=False, path=""):
    """
    Benchmarks the recursive algorithm for strong parity games using the worst case generator which yields an
    exponential complexity. Calls strong parity solver on games generated using the worst case generator function.
    Games of size 5 to 5*n are solved and a timer records the time taken to get the solution.The solver can be timed
    several times and the minimum value is selected using optional parameter iterations (to avoid recording time
    spikes and delays due to system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph (nodes is 5*n due to construction).
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (5 to 5n)

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generators.strong_parity_worst_case(i)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                strong_parity_solver(g)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(
            min_recording)  # get the minimum out of #iterations recordings
        n_.append(5 * i)
        total_time += min_recording

        print "Worst-case graph".center(40) + "|" + str(i * 5).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

        # at the end, print total time
    print "-" * 108 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"

    if plot:
        plt.grid(True)
        plt.title(u"Graphes 'pire cas' de taille 5 à " + str(5 * n))
        plt.xlabel(u'nombre de nœuds')
        plt.ylabel(u'temps (s)')
        # plt.yscale("log") allows logatithmic y-axis
        points, = plt.plot(n_, y, 'g.', label=u"Temps d'exécution")
        plt.legend(loc='upper left', handles=[points])
        plt.savefig(path, bbox_inches='tight')
        plt.clf()
        plt.close()
def benchmark_worst_case_removed_optimization(n,
                                              iterations=3,
                                              step=10,
                                              plot=False,
                                              path=""):
    """
        Analyzes the influence of the removed list optimization on the recursive algorithm for worst-case graphs.

        :param n: number of nodes in generated graph (nodes is 5*n due to construction).
        :param iterations: number of times the algorithm is timed (default is 3).
        :param step: step to be taken in the generation.
        :param plot: if True, plots the data using matplotlib.
        :param path: path to the file in which to write the result.
        """

    y = []  # list for the time recordings
    n_ = []  # list for the x values (5 to 5n)
    y2 = []  # list for the time recordings
    n_2 = []  # list for the x values (5 to 5n)
    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s)"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generators.strong_parity_worst_case(i)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                strong_parity_solver(g)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(
            min_recording)  # get the minimum out of #iterations recordings
        n_.append(5 * i)
        total_time += min_recording

        temp = []
        # #iterations calls to the solver are timed
        for j in range(iterations):
            removed = bitarray([False] + ([False] * len(g.nodes)))
            with chrono:
                strong_parity_solver_non_removed(g, removed)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y2.append(
            min_recording)  # get the minimum out of #iterations recordings
        n_2.append(5 * i)

        min_recording = min(temp)

        print "Worst-case graph".center(40) + "|" + str(i * 5).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

        # at the end, print total time
    print "-" * 108 + "\n" + "Total (s)".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"
    if plot:
        plt.grid(True)
        plt.title(
            u"Recursive algorithm runtime comparison : worst-case graphs of size 1 to "
            + str(5 * n))
        plt.xlabel(u'number of nodes')
        plt.ylabel(u'time (s)')

        # plt.yscale("log") allows logatithmic y-axis
        points, = plt.plot(n_, y, 'g.', label=u"Regular")
        points2, = plt.plot(n_2,
                            y2,
                            'r.',
                            label=u"Without sub-game construction")

        plt.legend(loc='upper left', handles=[points, points2])
        plt.savefig(path, bbox_inches='tight')
        plt.clf()
        plt.close()
def benchmark_random_reduction(n, iterations=3, step=10, plot=False, path=""):
    """
    Benchmarks the reduction to safety algorithm for strong parity games using a random generator. Games of size 1 to n
    are solved and a timer records the time taken to get the solution. The solver can be timed several times and the
    minimum value is selected using optional parameter iterations (to avoid recording time spikes and delays due to
    system load). The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step to be taken in the generation.
    :param plot: if True, plots the data using matplotlib.
    :param path: path to the file in which to write the result.
    """

    y = []  # list for the time recordings
    n_ = []  # list for the x values

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(5, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generators.random(i, i, 1, (i / 2))  # generated game
        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                reduction_to_safety_parity_solver(g)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(
            min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        total_time += min_recording

        print "Random graphs".center(40) + "|" + str(i).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

        # at the end, print total time
    print "-" * 108 + "\n" + "Total time".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"

    if plot:
        plt.grid(True)
        plt.title(u"Random graphs of size 1 to " + str(n))
        plt.xlabel(u'number of nodes')
        plt.ylabel(u'time (s)')
        points, = plt.plot(n_, y, 'g.', label=u"Execution time")
        plt.legend(loc='upper left', handles=[points])
        plt.savefig(path, bbox_inches='tight')
        plt.clf()
        plt.close()
예제 #11
0
def benchmark_complete_targetset(n,
                                 iterations=3,
                                 step=10,
                                 plot=False,
                                 regression=False,
                                 path=""):
    """
    Unused. This was made to compare execution time between players on graphs where the target set is the set of nodes.
    Calls reachability solver for player 1 on complete graphs where the target set is the set of all nodes. This makes
    the algorithm add all nodes to the queue and all predecessor lists are iterated over.
    Games of size 1 to n by step of #step are solved and a timer records the time taken to get the solution. The solver
    can be timed several times and the minimum value is selected depending on the value of optional parameter iterations
    (to avoid recording time spikes and delays due to system load). Time to solve the game is recorded and printed to
    the console in a formatted way. The result can be plotted using matplotlib.
    :param n: number of nodes in generated graph.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step between two sizes of graphs generated.
    :param plot: if True, plots the data using matplotlib.
    :param regression: if True, plots a polynomial regression.
    :param path: path to the file in which to write the result.
    """
    y = []  # list for the time recordings
    n_ = []  # list for the x values (1 to n)

    total_time = 0  # accumulator to record total time

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    info = "Time to solve (s), player " + str(
        1) + ", target set : V"  # info about the current benchmark

    # print first line of output
    print u"Generator".center(40) + "|" + u"Nodes (n)".center(12) + "|" + info.center(40) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp = []  # temp list for #iterations recordings
        g = generators.complete_graph(i)  # generated game

        # #iterations calls to the solver are timed

        target = range(1, i + 1)  # target set is the set of all nodes

        for j in range(iterations):
            with chrono:
                reachability_solver(g, target, 1)  # solver call
            temp.append(chrono.interval)  # add time recording

        min_recording = min(temp)
        y.append(
            min_recording)  # get the minimum out of #iterations recordings
        n_.append(i)
        total_time += min_recording

        print "Complete graph".center(40) + "|" + str(i).center(12) + "|" \
              + str(y[nbr_generated]).center(40) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

        # at the end, print total time
    print "-" * 108 + "\n" + "Total time".center(40) + "|" + "#".center(12) + "|" + \
          str(total_time).center(40) + "\n" + "-" * 108 + "\n"

    if plot:
        plt.grid(True)
        plt.title(u"Graphes complets de taille 1 à " + str(n))
        plt.xlabel(u'nombre de nœuds')
        plt.ylabel(u'temps (s)')
        if regression:
            coeficients = np.polyfit(n_, y, 2)
            polynom = np.poly1d(coeficients)
            points, = plt.plot(n_,
                               y,
                               'g.',
                               label=u"Temps d'exécution,\nensemble cible : V")
            fit, = plt.plot(n_,
                            polynom(n_),
                            'b--',
                            label=u"Régression polynomiale de degré 2")
            plt.legend(loc='upper left', handles=[points, fit])
        else:
            points, = plt.plot(n_,
                               y,
                               'g.',
                               label=u"Temps d'exécution,\nensemble cible : V")
            plt.legend(loc='upper left', handles=[points])
        plt.savefig(path + "complete_graph" + "_" + str(n) +
                    "nodes_targetallnodes" + ".png",
                    bbox_inches='tight')
        plt.clf()
        plt.close()
예제 #12
0
def benchmark_worst_case(n,
                         iterations=3,
                         step=10,
                         plot=False,
                         regression=False,
                         path=""):
    """
    Unused. This was made to compare execution time between players on worst case graphs.
    Calls reachability solver for both players and target set [1] on games generated using the worst case graph
    generator. Games of size 1 to n by step of #step are solved and a timer records the time taken to get the solution.
    The solver can be timed several times and the minimum value is selected depending on the value of optional parameter
    iterations (to avoid recording time spikes and delays due to system load). Time to solve the game for both players
    is recorded and printed to the console in a formatted way. Both results can be plotted using matplotlib.
    :param n: number of nodes in generated graph.
    :param iterations: number of times the algorithm is timed (default is 3).
    :param step: step between two sizes of graphs generated.
    :param plot: if True, plots the data using matplotlib.
    :param regression: if True, plots a polynomial regression.
    :param path: path to the file in which to write the result.
    """
    y_p0 = []  # list for the time recordings of player 0
    y_p1 = []  # list for the time recordings of player 1
    acc_p0 = 0  # accumulator for total time of player 0
    acc_p1 = 0  # accumulator for total time of player 1

    n_ = []  # list for the x values (1 to n)

    nbr_generated = 0  # conserving the number of generated mesures (used to get the index of a mesure)

    chrono = timer.Timer(verbose=False)  # Timer object

    # print first line of output
    print u"Generator".center(30) + "|" + u"Nodes (n)".center(12) + "|" + "Edges (m)".center(10) + "|" \
          + u"Time to solve, player 0".center(28) + "|" + u"Time to solve, player 1".center(28) + "\n" + \
          "-" * 108

    # games generated are size 1 to n
    for i in range(1, n + 1, step):
        temp_p0 = []  # temp list for #iterations recordings player 0
        temp_p1 = []  # temp list for #iterations recordings player 0

        g = generators.reachability_worst_case(i)  # generated game

        # #iterations calls to the solver are timed
        for j in range(iterations):
            with chrono:
                (W_0, sigma_0), (W_1, sigma_1) = reachability_solver(
                    g, [1], 0)  # solver call player 0
            temp_p0.append(chrono.interval)  # add time recording

        for j in range(iterations):
            with chrono:
                (W_1, sigma_1), (W_0, sigma_0) = reachability_solver(
                    g, [1], 1)  # solver call player 1
            temp_p1.append(chrono.interval)  # add time recording

        min_recording_p0 = min(temp_p0)
        y_p0.append(
            min_recording_p0
        )  # get the minimum out of #iterations recordings of player 0
        acc_p0 += min_recording_p0

        min_recording_p1 = min(temp_p1)
        y_p1.append(
            min_recording_p1
        )  # get the minimum out of #iterations recordings of player 1
        acc_p1 += min_recording_p1

        n_.append(i)

        print "Worst-case graph".center(30) + "|" + str(i).center(12) + "|" + str((i * (i + 1)) / 2).center(10) \
              + "|" + str(y_p0[nbr_generated]).center(28) + "|" + str(y_p1[nbr_generated]).center(28) + "\n" + "-" * 108

        nbr_generated += 1  # updating the number of generated mesures

    # at the end, print total time
    print "-" * 108 + "\n" + "Total time".center(30) + "|" + "#".center(12) + "|" + "#".center(10) + "|" + \
          str(acc_p0).center(28) + "|" + str(acc_p1).center(28) + "\n" + "-" * 108 + "\n"

    if plot:
        if regression:
            plt.grid(True)
            plt.title(u"Graphes 'pire cas' de taille 1 à " + str(n))
            plt.xlabel(u'nombre de nœuds')
            plt.ylabel(u'temps (s)')
            coeficients = np.polyfit(n_, y_p0, 2)
            polynom = np.poly1d(coeficients)
            points0, = plt.plot(
                n_,
                y_p0,
                'g.',
                label=u"Temps d'exécution, joueur 0,\nensemble cible {v1}")
            fit0, = plt.plot(n_,
                             polynom(n_),
                             'b--',
                             label=u"Régression polynomiale de degré 2")
            plt.legend(loc='upper left', handles=[points0, fit0])
            plt.savefig(path + "worstCase_" + str(n) + "nodes_player0.png",
                        bbox_inches='tight')
            plt.clf()
            plt.close()

            plt.grid(True)
            plt.title(u"Graphes 'pire cas' de taille 1 à " + str(n))
            plt.xlabel(u'nombre de nœuds')
            plt.ylabel(u'temps (s)')
            coeficients = np.polyfit(n_, y_p1, 1)
            polynom = np.poly1d(coeficients)
            points1, = plt.plot(
                n_,
                y_p1,
                'g.',
                label=u"Temps d'exécution, joueur 1,\nensemble cible {v1}")
            fit1, = plt.plot(
                n_, polynom(n_), 'b--', label=u"Régression linéaire"
            )  # \\\\"+str(coeficients[0])+u"$x^2 +$"+str(coeficients[1])+u"x +"+str(coeficients[2]))
            plt.legend(loc='upper left', handles=[points1, fit1])
            plt.savefig(path + "worstCase_" + str(n) + "nodes_player1.png",
                        bbox_inches='tight')
            plt.clf()
            plt.close()
        else:
            plt.grid(True)
            plt.title(u"Graphes pire cas de taille 1 à " + str(n))
            plt.xlabel(u'nombre de nœuds')
            plt.ylabel(u'temps (s)')
            points0, = plt.plot(
                n_,
                y_p0,
                'g.',
                label=u"Temps d'exécution, joueur 0,\nensemble cible {v1}")
            plt.legend(loc='upper left', handles=[points0])
            plt.savefig(path + "worstCase_" + str(n) + "nodes_player0.png",
                        bbox_inches='tight')
            plt.clf()
            plt.close()

            plt.grid(True)
            plt.title(u"Graphes pire cas de taille 1 à " + str(n))
            plt.xlabel(u'nombre de nœuds')
            plt.ylabel(u'temps (s)')
            points1, = plt.plot(
                n_,
                y_p1,
                'g.',
                label=u"Temps d'exécution, joueur 1,\nensemble cible {v1}")
            plt.legend(loc='upper left', handles=[points1])
            plt.savefig(path + "worstCase_" + str(n) + "nodes_player1.png",
                        bbox_inches='tight')
            plt.clf()
            plt.close()