예제 #1
0
파일: golomb.py 프로젝트: poitou/facile
def golomb(n):

    # On peut majorer la taille de la règle par 2 ** n. En effet, si
    # ticks[i] vaut 2**i alors tous les ticks[i] - ticks[j] = 2**i - 2**j
    # = 2**j * (2**(i-j) - 1) qui sont tous différents.
    # On a donc au moins cette solution.

    n2 = 2 ** n
    
    ticks = [facile.variable(0, n2) for i in range(n)]

    # First tick at the start of the ruler
    facile.constraint(ticks[0] == 0)

    # Ticks are ordered
    for i in range(n-1):
        facile.constraint(ticks[i] < ticks[i+1])

    # All distances
    distances = []
    for i in range(n-1):
        for j in range(i + 1, n):
            distances.append(ticks[j] - ticks[i])
    facile.constraint(facile.alldifferent(distances))

    for d in distances:
        facile.constraint(d > 0)

    # Breaking the symmetry
    size = len(distances)
    facile.constraint(distances[size - 1] > distances[0])

    return (facile.minimize(ticks, ticks[n-1])[1])
예제 #2
0
def golomb(n: int) -> facile.Solution:
    ticks = [facile.variable(range(2**n)) for i in range(n)]

    # First tick at the start of the ruler
    facile.constraint(ticks[0] == 0)

    # Ticks are ordered
    for i in range(n - 1):
        facile.constraint(ticks[i] < ticks[i + 1])

    # All distances
    distances = []
    for i in range(n - 1):
        for j in range(i + 1, n):
            distances.append(facile.variable(ticks[j] - ticks[i]))
    facile.constraint(facile.alldifferent(distances))

    for d in distances:
        facile.constraint(d > 0)

    # Breaking the symmetry
    size = len(distances)
    facile.constraint(distances[size - 1] > distances[0])

    return facile.minimize(ticks,
                           ticks[n - 1],
                           backtrack=True,
                           on_solution=print)
예제 #3
0
def test_broadcast() -> None:
    c = np.array([
        [13, 21, 20, 12, 8, 26, 22, 11],
        [12, 36, 25, 41, 40, 11, 4, 8],
        [35, 32, 13, 36, 26, 21, 13, 37],
        [34, 54, 7, 8, 12, 22, 11, 40],
        [21, 6, 45, 18, 24, 34, 12, 48],
        [42, 19, 39, 15, 14, 16, 28, 46],
        [16, 34, 38, 3, 34, 40, 22, 24],
        [26, 20, 5, 17, 45, 31, 37, 43],
    ])

    var = facile.Array.binary(c.shape)

    for i in range(c.shape[0]):
        facile.constraint(var[:, i].sum() == 1)
        facile.constraint(var[i, :].sum() == 1)

    # TODO (var * c).sum()
    sol = facile.minimize(list(var), (var * c.ravel()).sum())

    assert sol.solved
    assert sol.evaluation == 76
    assert (np.array(sol.solution).reshape(c.shape) == np.array(  # noqa: W503
        [
            [1, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 1],
            [0, 0, 0, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 1, 0, 0, 0],
            [0, 1, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 1, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, 0, 0, 0],
        ])).all()
예제 #4
0
def solver(cost, OWA):
    assert OWA in ['utilitarism', 'egalitarism', 'gini']

    n_task = cost.shape[1]
    n_agent = cost.shape[0]

    boolean_variable = np.array([
        facile.array([facile.variable([0, 1]) for i in range(n_task)])
        for j in range(n_agent)
    ])

    # Every task must be complete, by only one agent !
    for j in range(n_task):
        facile.constraint(sum(boolean_variable[:, j]) == 1)

    how_does_it_cost = facile.array([
        np.matmul(cost[i, :], facile.array(boolean_variable[i, :]))
        for i in range(n_agent)
    ])

    if OWA == 'utilitarism':
        weights = np.array([1 for i in range(n_agent)])
    elif OWA == 'egalitarism':
        # as we only have the .sort() method for desutilities, weights must be in reverse order because the 'desutilities' should be sorted in descending order
        weights = np.array([0 for i in range(n_agent)])
        weights[-1] = 1
    else:
        # as we only have the .sort() method for desutilities, weights must be in reverse order because the 'desutilities' should be sorted in descending order
        weights = np.flip(
            np.array([2 * (n_agent - i) + 1 for i in range(1, n_agent + 1)]))

    print(weights)
    to_minimize = np.matmul(weights, how_does_it_cost.sort())

    vars = []

    for i in range(n_agent):
        for j in range(n_task):
            vars.append(boolean_variable[i, j])

    res = np.array(facile.minimize(vars, to_minimize).solution)
    boolean_res = res > 0

    tasks = np.array([list(string.ascii_lowercase)[0:n_task]])

    for i in range(n_agent):
        boolean_res[i:i + n_task]
        print(i + 1, ' does : ',
              tasks[:, boolean_res[n_task * i:n_task * (i + 1)]][0])
예제 #5
0
파일: coins.py 프로젝트: poitou/facile
def coins(values, maxval):
    """
    Which coins do you need to give back change for any amount between 0 and
    maxval, using coins from values?
    """

    # How many coin types
    nb_vals = len(values)
    nb_min_coins = [variable(0, maxval/values[i]) for i in range(nb_vals)]

    for val in range(maxval):
        # How many coins per type
        nb_coins = [variable(0, maxval/values[i]) for i in range(nb_vals)]
        mysum = sum([x[0] * x[1] for x in zip(values, nb_coins)])
        constraint(mysum == val)
        for j in range(len(nb_coins)):
            constraint(nb_coins[j] <= nb_min_coins[j])

    return minimize(nb_min_coins, sum(nb_min_coins))
예제 #6
0
파일: coins.py 프로젝트: xoolive/facile
def coins(values, maxval):
    """
    Which coins do you need to give back change for any amount between 0 and
    maxval, using coins from values?
    """

    # How many coin types
    nb_vals = len(values)
    nb_min_coins = [variable(0, maxval / values[i]) for i in range(nb_vals)]

    for val in range(maxval):
        # How many coins per type
        nb_coins = [variable(0, maxval / values[i]) for i in range(nb_vals)]
        mysum = sum([x[0] * x[1] for x in zip(values, nb_coins)])
        constraint(mysum == val)
        for j in range(len(nb_coins)):
            constraint(nb_coins[j] <= nb_min_coins[j])

    return minimize(nb_min_coins, sum(nb_min_coins))
예제 #7
0
# detail here!
def cumulative(s, d, r, b):
    tasks = [i for i in range(len(s)) if r[i] > 0 and d[i] > 0]
    times_min = min([s[i].domain()[0] for i in tasks])
    times_max = max([s[i].domain()[-1] + max(d) for i in tasks])
    for t in range(times_min, times_max + 1):
        bb = []
        for i in tasks:
            c1 = s[i] <= t
            c2 = t < s[i] + d[i]
            bb.append(c1 * c2 * r[i])
        facile.constraint(sum(bb) <= b)


cumulative(start_times, duration, demand, n_resources)

print("---- Minimize resources ----")
print(
    facile.minimize(
        start_times + end_times + [n_resources], n_resources, on_solution=print
    )
)

print("---- Minimize end_time ----")
print(
    facile.minimize(
        start_times + end_times + [end_time], end_time, on_solution=print
    )
)