diff --git a/Probas.py b/Probas.py old mode 100644 new mode 100755 index 240a19e..ccfa45e --- a/Probas.py +++ b/Probas.py @@ -1,11 +1,16 @@ +#!/usr/bin/python3 from random import random -from math import floor, sqrt +from math import floor, sqrt, factorial from statistics import mean, variance -# from matplotlib import pyplot +from matplotlib import pyplot as plt +from pylab import * +import numpy as np +import matplotlib.pyplot as pt + def simulate_NFBP(N): """ - Tries to simulate T_i, V_i and H_n for N boxes of random size. + Tries to simulate T_i, V_i and H_n for N items of random size. """ i = 0 # Nombre de boites R = [0] # Remplissage de la i-eme boite @@ -16,7 +21,7 @@ def simulate_NFBP(N): size = random() if R[i] + size >= 1: # Il y n'y a plus de la place dans la boite pour le paquet. - # On passe à la boite suivante (qu'on initialise) + # On passe a la boite suivante (qu'on initialise) i += 1 R.append(0) T.append(0) @@ -28,20 +33,15 @@ def simulate_NFBP(N): V[i] = size H.append(i) - return { - "i": i, - "R": R, - "T": T, - "V": V, - "H": H - } + return {"i": i, "R": R, "T": T, "V": V, "H": H} +# unused def stats_NFBP(R, N): """ - Runs R runs of NFBP (for N packages) and studies distribution, variance, mean... + Runs R runs of NFBP (for N items) and studies distribution, variance, mean... """ - print("Running {} NFBP simulations with {} packages".format(R, N)) + print("Running {} NFBP simulations with {} items".format(R, N)) I = [] H = [[] for _ in range(N)] # List of empty lists @@ -51,42 +51,136 @@ def stats_NFBP(R, N): for n in range(N): H[n].append(sim["H"][n]) - print("Mean number of boxes : {} (variance {})".format(mean(I), variance(I))) + print("Mean number of bins : {} (variance {})".format(mean(I), variance(I))) for n in range(N): print("Mean H_{} : {} (variance {})".format(n, mean(H[n]), variance(H[n]))) + def stats_NFBP_iter(R, N): """ - Runs R runs of NFBP (for N packages) and studies distribution, variance, mean... + Runs R runs of NFBP (for N items) and studies distribution, variance, mean... Calculates stats during runtime instead of after to avoid excessive memory usage. """ - print("Running {} NFBP simulations with {} packages".format(R, N)) + P = R * N # Total number of items + print("## Running {} NFBP simulations with {} items".format(R, N)) + # number of bins ISum = 0 IVarianceSum = 0 + # index of the bin containing the n-th item HSum = [0 for _ in range(N)] HSumVariance = [0 for _ in range(N)] + # number of items in the i-th bin + Sum_T = [0 for _ in range(N)] + # size of the first item in the i-th bin + Sum_V = [0 for _ in range(N)] for i in range(R): sim = simulate_NFBP(N) ISum += sim["i"] - IVarianceSum += sim["i"]**2 + IVarianceSum += sim["i"] ** 2 for n in range(N): HSum[n] += sim["H"][n] - HSumVariance[n] += sim["H"][n]**2 + HSumVariance[n] += sim["H"][n] ** 2 + T = sim["T"] + V = sim["V"] + # ensure that T, V have the same length as Sum_T, Sum_V + for i in range(N - sim["i"]): + T.append(0) + V.append(0) + Sum_T = [x + y for x, y in zip(Sum_T, T)] + Sum_V = [x + y for x, y in zip(Sum_V, V)] - I = ISum/R - IVariance = sqrt(IVarianceSum/(R-1) - I**2) + Sum_T = [x / R for x in Sum_T] + Sum_V = [round(x / R, 2) for x in Sum_V] + # print(Sum_V) + I = ISum / R + IVariance = sqrt(IVarianceSum / (R - 1) - I**2) + print("Mean number of bins : {} (variance {})".format(I, IVariance), "\n") + # TODO clarify line below + print(" {} * {} iterations of T".format(R, N), "\n") + + for n in range(min(N, 10)): + Hn = HSum[n] / R # moyenne + HVariance = sqrt(HSumVariance[n] / (R - 1) - Hn**2) # Variance + print( + "Index of bin containing the {}th item (H_{}) : {} (variance {})".format( + n, n, Hn, HVariance + ) + ) + HSum = [x / R for x in HSum] + # print(HSum) + # Plotting + fig = plt.figure() + # T plot + x = np.arange(N) + # print(x) + ax = fig.add_subplot(221) + ax.bar( + x, + Sum_T, + width=1, + label="Empirical values", + edgecolor="blue", + linewidth=0.7, + color="red", + ) + ax.set( + xlim=(0, N), xticks=np.arange(0, N), ylim=(0, 3), yticks=np.linspace(0, 3, 5) + ) + ax.set_ylabel("Items") + ax.set_xlabel("Bins (1-{})".format(N)) + ax.set_title("T histogram for {} items (Number of items in each bin)".format(P)) + ax.legend(loc="upper left", title="Legend") + # V plot + bx = fig.add_subplot(222) + bx.bar( + x, + Sum_V, + width=1, + label="Empirical values", + edgecolor="blue", + linewidth=0.7, + color="orange", + ) + bx.set( + xlim=(0, N), xticks=np.arange(0, N), ylim=(0, 1), yticks=np.linspace(0, 1, 10) + ) + bx.set_ylabel("First item size") + bx.set_xlabel("Bins (1-{})".format(N)) + bx.set_title("V histogram for {} items (first item size of each bin)".format(P)) + bx.legend(loc="upper left", title="Legend") + # H plot + # We will simulate this part for a asymptotic study + cx = fig.add_subplot(223) + cx.bar( + x, + HSum, + width=1, + label="Empirical values", + edgecolor="blue", + linewidth=0.7, + color="green", + ) + cx.set( + xlim=(0, N), xticks=np.arange(0, N), ylim=(0, 10), yticks=np.linspace(0, N, 5) + ) + cx.set_ylabel("Bin ranking of n-item") + cx.set_xlabel("n-item (1-{})".format(N)) + cx.set_title("H histogram for {} items".format(P)) + xb = linspace(0, N, 10) + yb = Hn * xb / 10 + wb = HVariance * xb / 10 + cx.plot(xb, yb, label="Theoretical E(Hn)", color="brown") + cx.plot(xb, wb, label="Theoretical V(Hn)", color="purple") + cx.legend(loc="upper left", title="Legend") + plt.show() - print("Mean number of boxes : {} (variance {})".format(I, IVariance)) - for n in range(n): - Hn = HSum[n]/R - HVariance = sqrt(HSumVariance[n]/(R-1) - Hn**2) - print("Index of box containing the {}th package (H_{}) : {} (variance {})".format(n, n, Hn, HVariance)) def simulate_NFDBP(N): """ - Tries to simulate T_i, V_i and H_n for N boxes of random size. + Tries to simulate T_i, V_i and H_n for N items of random size. + Next Fit Dual Bin Packing : bins should overflow """ i = 0 # Nombre de boites R = [0] # Remplissage de la i-eme boite @@ -95,83 +189,185 @@ def simulate_NFDBP(N): H = [] # Rang de la boite contenant le n-ieme paquet for n in range(N): size = random() - R[i] += size - T[i] += 1 - if R[i] + size >= 1: + if R[i] >= 1: # Il y n'y a plus de la place dans la boite pour le paquet. - # On passe à la boite suivante (qu'on initialise) + # On passe a la boite suivante (qu'on initialise). i += 1 R.append(0) T.append(0) V.append(0) - if V[i] == 0: # C'est le premier paquet de la boite V[i] = size H.append(i) + R[i] += size + T[i] += 1 - return { - "i": i, - "R": R, - "T": T, - "V": V, - "H": H - } + return {"i": i, "R": R, "T": T, "V": V, "H": H} -def stats_NFDBP(R, N): +def stats_NFDBP(R, N, t_i): """ - Runs R runs of NFDBP (for N packages) and studies distribution, variance, mean... + Runs R runs of NFDBP (for N items) and studies distribution, variance, mean... """ - print("Running {} NFDBP simulations with {} packages".format(R, N)) + print("## Running {} NFDBP simulations with {} items".format(R, N)) + # TODO comment this function + P = N * R # Total number of items I = [] H = [[] for _ in range(N)] # List of empty lists - Tmean=[] + T = [] + Tk = [[] for _ in range(N)] + Ti = [] + T_maths = [] + # First iteration to use zip after + sim = simulate_NFDBP(N) + Sum_T = [0 for _ in range(N)] for i in range(R): sim = simulate_NFDBP(N) I.append(sim["i"]) + for k in range(N): + T.append(0) + T = sim["T"] for n in range(N): H[n].append(sim["H"][n]) + Tk[n].append(sim["T"][n]) + Ti.append(sim["T"]) + Sum_T = [x + y for x, y in zip(Sum_T, T)] + Sum_T = [x / R for x in Sum_T] # Experimental [Ti=k] + Sum_T = [ + x * 100 / (sum(Sum_T)) for x in Sum_T + ] # Pourcentage de la repartition des items - for k in range(sim["i"]): - # for o in range(sim["i"]): - Tmean+=sim["T"] - print("Mean number of boxes : {} (variance {})".format(mean(I), variance(I))) + print("Mean number of bins : {} (variance {})".format(mean(I), variance(I))) for n in range(N): print("Mean H_{} : {} (variance {})".format(n, mean(H[n]), variance(H[n]))) - for k in range(int(mean(I))+1): - print(Tmean[7]) - # print("Mean T_{} : {} (variance {})".format(k, mean(Tmean[k]), variance(Tmean[k]))) + # TODO variance for T_k doesn't see right + print("Mean T_{} : {} (variance {})".format(k, mean(Sum_T), variance(Sum_T))) + # Loi math + for u in range(N): + u = u + 2 + T_maths.append(1 / (factorial(u - 1)) - 1 / factorial(u)) + E = 0 + sigma2 = 0 + # print(T_maths) + for p in range(len(T_maths)): + E = E + (p + 1) * T_maths[p] + sigma2 = ((T_maths[p] - E) ** 2) / (len(T_maths) - 1) + print( + "Mathematical values : Empiric mean T_{} : {} Variance {})".format( + t_i, E, sqrt(sigma2) + ) + ) + T_maths = [x * 100 for x in T_maths] + # Plotting + fig = plt.figure() + # T plot + x = np.arange(N) + print(x) + print(Sum_T) + ax = fig.add_subplot(221) + ax.bar( + x, + Sum_T, + width=1, + label="Empirical values", + edgecolor="blue", + linewidth=0.7, + color="red", + ) + ax.set( + xlim=(0, N), xticks=np.arange(0, N), ylim=(0, 20), yticks=np.linspace(0, 20, 2) + ) + ax.set_ylabel("Items(n) in %") + ax.set_xlabel("Bins (1-{})".format(N)) + ax.set_title( + "Items percentage for each bin and {} items (Number of items in each bin)".format( + P + ) + ) + ax.legend(loc="upper right", title="Legend") -N = 10 ** 1 -sim = simulate_NFBP(N) + # TODO fix the graph below + # Mathematical P(Ti=k) plot. It shows the Ti(t_i) law with the probability of each number of items. + print(len(Tk[t_i])) + bx = fig.add_subplot(222) + bx.hist( + Tk[t_i], + bins=10, + width=1, + label="Empirical values", + edgecolor="blue", + linewidth=0.7, + color="red", + ) + bx.set( + xlim=(0, N), + xticks=np.arange(0, N), + ylim=(0, len(Tk[t_i])), + yticks=np.linspace(0, 1, 1), + ) + bx.set_ylabel("P(T{}=i)".format(t_i)) + bx.set_xlabel("Bins i=(1-{}) in %".format(N)) + bx.set_title( + "T{} histogram for {} items (Number of items in each bin)".format(t_i, P) + ) + bx.legend(loc="upper right", title="Legend") -print("Simulation NFBP pour {} packaets. Contenu des boites :".format(N)) -for j in range(sim["i"] + 1): - remplissage = floor(sim["R"][j] * 100) - print("Boite {} : Rempli à {} % avec {} paquets. Taille du premier paquet : {}".format(j, remplissage, sim["T"][j], - sim["V"][j])) + # Loi mathematique + print(T_maths) + cx = fig.add_subplot(224) + cx.bar( + x, + T_maths, + width=1, + label="Theoretical values", + edgecolor="blue", + linewidth=0.7, + color="red", + ) + cx.set( + xlim=(0, N), + xticks=np.arange(0, N), + ylim=(0, 100), + yticks=np.linspace(0, 100, 10), + ) + cx.set_ylabel("P(T{}=i)".format(t_i)) + cx.set_xlabel("Bins i=(1-{})".format(N)) + cx.set_title("Theoretical T{} values in %".format(t_i)) + cx.legend(loc="upper right", title="Legend") + plt.show() -print() -stats_NFBP(10 ** 4, 10) -N = 10 ** 1 -sim = simulate_NFDBP(N) -print("Simulation NFDBP pour {} packaets. Contenu des boites :".format(N)) -for j in range(sim["i"] + 1): - remplissage = floor(sim["R"][j] * 100) - print("Boite {} : Rempli à {} % avec {} paquets. Taille du premier paquet : {}".format(j, remplissage, - sim["T"][j], - sim["V"][j])) +# unused +def basic_demo(): + N = 10**1 + sim = simulate_NFBP(N) -print() -stats_NFDBP(10 ** 4, 10) -stats_NFBP_iter(10**6, 10) + print("Simulation NFBP pour {} packaets. Contenu des boites :".format(N)) + for j in range(sim["i"] + 1): + remplissage = floor(sim["R"][j] * 100) + print( + "Boite {} : Rempli a {} % avec {} paquets. Taille du premier paquet : {}".format( + j, remplissage, sim["T"][j], sim["V"][j] + ) + ) -# -# pyplot.plot([1, 2, 4, 4, 2, 1], color = 'red', linestyle = 'dashed', linewidth = 2, -# markerfacecolor = 'blue', markersize = 5) -# pyplot.ylim(0, 5) -# pyplot.title('Un exemple') + print() + stats_NFBP(10**3, 10) + N = 10**1 + sim = simulate_NFDBP(N) + print("Simulation NFDBP pour {} packaets. Contenu des boites :".format(N)) + for j in range(sim["i"] + 1): + remplissage = floor(sim["R"][j] * 100) + print( + "Boite {} : Rempli a {} % avec {} paquets. Taille du premier paquet : {}".format( + j, remplissage, sim["T"][j], sim["V"][j] + ) + ) + + +stats_NFBP_iter(10**3, 10) +print("\n\n") +stats_NFDBP(10**3, 10, 1)