示例#1
0
文件: etc.py 项目: hnishi/ortoolpy
def tsp1(nodes, dist):
    """
    巡回セールスマン問題
    入力
        nodes: 点(dist未指定時は、座標)のリスト
        dist: (i,j)をキー、距離を値とした辞書
    出力
        距離と点番号リスト
    """
    from more_itertools import iterate, take

    n = len(nodes)
    df = pd.DataFrame(
        [(i, j, dist[i, j]) for i in range(n) for j in range(n) if i != j],
        columns=["NodeI", "NodeJ", "Dist"],
    )
    m = LpProblem()
    df["VarIJ"] = addbinvars(len(df))
    df["VarJI"] = df.sort_values(["NodeJ", "NodeI"]).VarIJ.values
    u = [0] + addvars(n - 1)
    m += lpDot(df.Dist, df.VarIJ)
    for _, v in df.groupby("NodeI"):
        m += lpSum(v.VarIJ) == 1  # 出次数制約
        m += lpSum(v.VarJI) == 1  # 入次数制約
    for i, j, _, vij, vji in df.query("NodeI!=0 & NodeJ!=0").itertuples(False):
        m += u[i] + 1 - (n - 1) * (1 - vij) + (n - 3) * vji <= u[
            j]  # 持ち上げポテンシャル制約(MTZ)
    for _, j, _, v0j, vj0 in df.query("NodeI==0").itertuples(False):
        m += 1 + (1 - v0j) + (n - 3) * vj0 <= u[j]  # 持ち上げ下界制約
    for i, _, _, vi0, v0i in df.query("NodeJ==0").itertuples(False):
        m += u[i] <= (n - 1) - (1 - vi0) - (n - 3) * v0i  # 持ち上げ上界制約
    m.solve()
    df["ValIJ"] = df.VarIJ.apply(value)
    dc = df[df.ValIJ > 0.5].set_index("NodeI").NodeJ.to_dict()
    return value(m.objective), list(take(n, iterate(lambda k: dc[k], 0)))
示例#2
0
def evolve(state, D):
    offset = [o for o in product([-1, 0, +1], repeat=D) if any(o)]
    counts = lambda state: (
        (p, sum(tuple(a + b for (a, b) in zip(p, q)) in state for q in offset))
        for p in product(*[itercoord(state, d) for d in range(D)]))
    return iterate(
        lambda state: {
            p
            for (p, c) in counts(state) if (c in {2, 3}
                                            if p in state else c == 3)
        }, state)
示例#3
0
def part_1(data):
    r'''
    >>> part_1("""\
    ... .#.
    ... ..#
    ... ###""")
    112

    '''
    grid = GridPart1.parse(data)
    final = mit.nth(mit.iterate(GridPart1.next, grid), 6)
    return len(final)
示例#4
0
def part_2(data):
    r'''
    >>> part_2("""\
    ... .#.
    ... ..#
    ... ###""")
    848

    '''
    grid = GridPart2.parse(data)
    final = mit.nth(mit.iterate(GridPart2.next, grid), 6)
    return len(final)
示例#5
0
def tsp(nodes, dist=None):
    """
    巡回セールスマン問題
    入力
        nodes: 点(dist未指定時は、座標)のリスト
        dist: (i,j)をキー、距離を値とした辞書
    出力
        距離と点番号リスト
    """
    import numpy as np
    import pandas as pd
    from more_itertools import iterate, take
    from pulp import LpProblem, LpVariable, LpBinary, lpDot, lpSum, value

    n = len(nodes)
    if not dist:
        dist = {(i, j): np.linalg.norm(np.subtract(nodes[i], nodes[j]))
                for i in range(n) for j in range(i + 1, n)}
        dist.update({(j, i): d for (i, j), d in dist.items()})
    a = pd.DataFrame(
        [(i, j, dist[i, j]) for i in range(n) for j in range(n) if i != j],
        columns=["NodeI", "NodeJ", "Dist"],
    )
    m = LpProblem()
    a["VarIJ"] = [LpVariable("x%d" % i, cat=LpBinary) for i in a.index]
    a["VarJI"] = a.sort_values(["NodeJ", "NodeI"]).VarIJ.values
    u = [0] + [LpVariable("y%d" % i, lowBound=0) for i in range(n - 1)]
    m += lpDot(a.Dist, a.VarIJ)
    for _, v in a.groupby("NodeI"):
        m += lpSum(v.VarIJ) == 1  # 出次数制約
        m += lpSum(v.VarJI) == 1  # 入次数制約
    for _, (i, j, _, vij, vji) in a.query("NodeI!=0 & NodeJ!=0").iterrows():
        m += u[i] + 1 - (n - 1) * (1 - vij) + (n - 3) * vji <= u[
            j]  # 持ち上げポテンシャル制約(MTZ)
    for _, (_, j, _, v0j, vj0) in a.query("NodeI==0").iterrows():
        m += 1 + (1 - v0j) + (n - 3) * vj0 <= u[j]  # 持ち上げ下界制約
    for _, (i, _, _, vi0, v0i) in a.query("NodeJ==0").iterrows():
        m += u[i] <= (n - 1) - (1 - vi0) - (n - 3) * v0i  # 持ち上げ上界制約
    m.solve()
    a["ValIJ"] = a.VarIJ.apply(value)
    dc = dict(a[a.ValIJ > 0.5][["NodeI", "NodeJ"]].values)
    return value(m.objective), list(take(n, iterate(lambda k: dc[k], 0)))
示例#6
0
def part_two():
    input_lines = get_input()
    coordinates = create_coordinates(input_lines, 4)
    cycles = iterate(generate_cycle, coordinates)
    return len(nth(cycles, 6))
def _walk_parents(command):
    """Walks up a command's parent chain."""
    return iter(iterate(operator.attrgetter('parent'), command).__next__, None)
示例#8
0
def generate_state(agent, environment):
    """Run a single planning interval for the given number of steps."""
    initial_step_data = StepData(environment.initial_state(), None, 0, agent)  # Initial state with step_id 0
    return iterate(lambda step_data: run_step(step_data, environment), initial_step_data)
示例#9
0
def generate_state(agent, environment):
    """Run a single planning interval for the given number of steps."""
    initial_step_data = StepData(environment.initial_state(), None, 0,
                                 agent)  # Initial state with step_id 0
    return iterate(lambda step_data: run_step(step_data, environment),
                   initial_step_data)
示例#10
0
def tsp(nodes, list_of_homes, dist=None):
    """
    巡回セールスマン問題
    入力
        nodes: 点(dist未指定時は、座標)のリスト
        dist: (i,j)をキー、距離を値とした辞書
    出力
        距離と点番号リスト
    """

    n = len(nodes)

    if not dist:
        dist = {(i, j): np.linalg.norm(np.subtract(nodes[i], nodes[j]))
                for i in range(n) for j in range(i + 1, n)}
        dist.update({(j, i): d for (i, j), d in dist.items()})

    # data farme containing distances from node i to node j
    print(dist)
    a = pd.DataFrame([(nodes[i], i, j, dist[(i, j)]) for i in range(n)
                      for j in range(n) if i != j],
                     columns=['Name', 'NodeI', 'NodeJ', 'Dist'])

    m = LpProblem()

    # creates x_ij for every edge in the graph
    a['VarIJ'] = [LpVariable('x%d' % i, cat=LpBinary) for i in a.index]

    a['VarJI'] = a.sort_values(['NodeJ', 'NodeI']).VarIJ.values

    #
    u = [0] + [LpVariable('y%d' % i, lowBound=0) for i in range(n - 1)]
    print(a)
    # gives the total distance,
    m += lpDot(a.Dist, a.VarIJ)
    print(list_of_homes)
    for _, v in a.groupby('NodeI'):
        print(v)
        print(v.iloc[0, :].NodeI)
        print('*****')
        if v.iloc[0, :].Name in list_of_homes:
            print('*&&&&', v.iloc[0, :].Name)
            m += lpSum(
                v.VarIJ) == 1  # constraint for one edge exiting each vertex
            m += lpSum(
                v.VarJI) == 1  # constraint for one edge entering each vertex

    for _, (name, i, j, _, vij,
            vji) in a.query('NodeI!=0 & NodeJ!=0').iterrows():
        m += u[i] + 1 - (n - 1) * (1 - vij) + (n - 3) * vji <= u[
            j]  # 持ち上げポテンシャル制約(MTZ)

    for _, (name, _, j, _, v0j, vj0) in a.query('NodeI==0').iterrows():
        m += 1 + (1 - v0j) + (n - 3) * vj0 <= u[j]  # lower bound constraints
    for _, (name, i, _, _, vi0, v0i) in a.query('NodeJ==0').iterrows():
        m += u[i] <= (n - 1) - (1 -
                                vi0) - (n - 3) * v0i  # upper bound constraints
    m.solve()
    a['ValIJ'] = a.VarIJ.apply(value)
    dc = dict(a[a.ValIJ > 0.5][['NodeI', 'NodeJ']].values)
    return value(m.objective), list(take(n, iterate(lambda k: dc[k], 0)))