Minimizing the workflow and distance between department and stations

71 Views Asked by At

I wrote code for a project. But line 96 has too many errors. The aim of my project is to minimize material flow and distance between departments and stations in a factory. Obviously, the aim is to reduce the time loss in the material flow by changing the factory layout. But the most critical point is that departments and stations only switch places among themselves. i.e. department 1 and department 4 can be swapped, or station 3 and station 10. but Department 3 and Station 5 cannot be swapped. Please help me!

SETS
    i departments /1*6/
    j stations /1*10/
    m departments2 /1*6/
    n stations2 /1*10/ ;

PARAMETERS
    Table
    Workflow(i, j) Workflow matrix
     1   2   3   4   5   6   7   8   9   10
1    1   1   3   3   3   3   0   4   5   3
2    4   6   5   7   6   6   8   9   7   6
3    1   0   5   4   1   0   0   6   6   5
4    5   8   5   6   7   0   0   1   1   6
5    3   0   4   0   0   0   0   5   6   5
6    3   4   3   0   5   0   4   10  9   4;

PARAMETERS
    Table
    Distance(m, n) Distance matrix
       1   2    3   4   5   6   7   8   9   10
1     35   47  61  74  81  97  111 125 137  55
2     68   86  90  98  104 103  79  78  90  67
3    312  323 335 344 358 367 377 393 414 318
4     72   83  95  106 118 128 136 151 173 57
5    116   0   97   0   0   0   0   39  28  193
6     83   87  69  0   52  0   18  17  12  171;

VARIABLES
    y(m, n) Binary variables
    a(j, n) Binary variables
    b(i, m) Binary variables
    z Objective function;

BINARY VARIABLES
    Q(i, j, m, n);

EQUATIONS
    c1(n)
    c2(j)
    c3(i, j, m, n)
    c4(i, j, m, n)
    c5(i, j, m, n)
    c6(i)
    c7(m)
    c8(i, j, m, n)
    t1(n)
    t2(n)
    t3(n)
    t4(n)
    t5(n)
    t6(n)
    t7(n)
    t8(n)
    t9(n)
    t10(n)
    k1(m)
    k2(m)
    k3(m)
    k4(m)
    k5(m)
    k6(m);
    
c1(n).. sum(j, a(j, n)) =e= 1;
c2(j).. sum(n, a(j, n)) =e= 1;
c6(i).. sum(m, b(i, m)) =e= 1;
c7(m).. sum(i, b(i, m)) =e= 1;

c3(i, j, m, n).. Q(i, j, m, n) =l= a(j, n);
c8(i, j, m, n).. Q(i, j, m, n) =l= b(i, m);

c4(i, j, m, n).. Q(i, j, m, n) =l= y(m, n);
c5(i, j, m, n).. Q(i, j, m, n) =g= a(j, n) + y(m, n) + b(i, m) - 1;

t1(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t2(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t3(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t4(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t5(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t6(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t7(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t8(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t9(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;
t10(n).. sum((i, j, m), Q(i, j, m, n)) =e= 1;


k1(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;
k2(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;
k3(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;
k4(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;
k5(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;
k6(m).. sum((n, i,j), Q(i, j, m, n)) =e= 1;



min.. z =e= sum((i, j, m, n), workflow(i, j) * Distance(m, n) * Q(i, j, m, n));


Model Layout /all/;
Solve Layout using RMIP minimizing z;

There are so many errors and didnt work.

2

There are 2 best solutions below

0
Lutz On BEST ANSWER

On a general note, I'd suggest to look at the first error only, as subsequent ones often go away after fixing previous ones. Your first error is:

  96  min.. z =e= sum((i, j, m, n), workflow(i, j) * Distance(m, n) * Q(i, j, m, n));
****    $168
**** 168  Assignment not allowed to this identifier

The problem is, that min is a keyword which you cannot assign to. This can easily be fixed if you change it to something like this:

equation obj;
obj.. z =e= sum((i, j, m, n), workflow(i, j) * Distance(m, n) * Q(i, j, m, n));

That change actually resolves all your compilation errors.

The model still is infeasible, so you might need to check your model formulation and data.

4
Reinderien On

I do not have GAMS so I demonstrate in PuLP.

I make a lot of assumptions here, including:

  • The original workflows per department-station pair are preserved
  • Those workflows are moved to new department-station locations
  • The distance between those new locations is used in the objective
  • You're actually minimizing the integral of workflow-rate-distance, so if the workflow is in units per second and the distance is in metres, the objective is in metre units per second. If all speed is constant this simplifies to metre units.

Your formulation is over-constructed; Q is too high-dimensional. I demonstrate how you can replace both Q and y with a smaller ixm (6x6) intermediate array of continuous variables. It needs to be lower-bounded and have big-M constraints based on department assignment (what you call your b). At the heart of this simplification is a double matrix product over distance, workflow, and station assignment (the latter chosen because it's the larger of the two assignment matrices).

All together,

from io import StringIO

import pandas as pd
import pulp

with StringIO('''
i    1   2   3   4   5   6   7   8   9   10
1    1   1   3   3   3   3   0   4   5   3
2    4   6   5   7   6   6   8   9   7   6
3    1   0   5   4   1   0   0   6   6   5
4    5   8   5   6   7   0   0   1   1   6
5    3   0   4   0   0   0   0   5   6   5
6    3   4   3   0   5   0   4   10  9   4
''') as f:
    workflow = pd.read_fwf(f).set_index('i')
workflow.index.name = 'department'  # i
workflow.columns = pd.Index(name='station', data=workflow.columns.astype(int))   # j

with StringIO('''
i      1    2    3    4    5    6    7    8    9   10
1    116    0   97    0    0    0    0   39   28  193
2     68   86   90   98  104  103   79   78   90   67
3    312  323  335  344  358  367  377  393  414  318
4     72   83   95  106  118  128  136  151  173   57
5    116    0   97    0    0    0    0   39   28  193
6     83   87   69    0   52    0   18   17   12  171
''') as f:
    distance = pd.read_fwf(f).set_index('i')
distance.index.name = 'department'  # i
distance.columns = pd.Index(name='station', data=distance.columns.astype(int))   # j


def two_digits(row: pd.Series) -> str:
    return '{:02d}_to_{:02d}'.format(*row)


station_idx = pd.MultiIndex.from_product(
    iterables=(workflow.columns, workflow.columns), names=('source_station', 'dest_station'),
)
station_assign = (  # a
    (
        'station_' +
        station_idx.to_frame().apply(two_digits, axis=1)
    )
    .apply(pulp.LpVariable, cat=pulp.LpBinary)
    .unstack('dest_station')
)

dept_idx = pd.MultiIndex.from_product(
    iterables=(workflow.index, workflow.index), names=('source_dept', 'dest_dept'),
)
dept_names = 'dept_' + dept_idx.to_frame().apply(two_digits, axis=1)
dept_assign = (  # b
    dept_names
    .apply(pulp.LpVariable, cat=pulp.LpBinary)
    .unstack('dest_dept')
)

factors = (
    ('prod_' + dept_names)
    .apply(pulp.LpVariable, cat=pulp.LpContinuous, lowBound=0)
    .unstack('dest_dept')
)

prob = pulp.LpProblem(name='factory', sense=pulp.LpMinimize)
prob.objective = factors.sum().sum()

for assign in (station_assign, dept_assign):
    for axis in (0, 1):
        for name, total in assign.sum(axis=axis).items():
            prob.addConstraint(
                name=f'excl_{assign.axes[1 - axis].name}_{name}',
                constraint=total == 1,
            )

'''
If e.g. station 2 moves to the original position of station 4, and
department 5 moves to the original position of department 3,
the workflow from station 2 to department 5 is still 6,
but the distance between them is no longer 0: it's now 344.
minimize (st24)(dp53)*6*344

for dept source
  for dept dest
    for station source
      for station dest
        if these two dept-dept station-station variables are selected, then
        add the (distance between dest dept and dest station) *
        (workflow between source dept and source station)
        
== sum  (deptdept)*(statstat)*(dest distance)*(source workflow)
   ijkl     i   j      k   l             j l               i k

== sum deptdept [sum statstat*(dest distance)*(source workflow)]_ij
    ij       ij   kl    k   l            j l               i k

( workflow @ statstat ) @ distance.T
      i k         k l           l j 
'''

statstat_factors = (workflow @ station_assign) @ distance.T
M = 2*distance.max()*workflow.max()

for dest_dept, dept_col in dept_assign.items():
    for source_dept, is_dept_assigned in dept_col.items():
        statstat = statstat_factors.loc[source_dept, dest_dept]
        factor = factors.loc[source_dept, dest_dept]

        # if is_dept_assigned, then factor >= statstat
        # otherwise, factor >= 0 (by bound)
        prob.addConstraint(
            name=f'prodlo_d{source_dept:02d}_to_d{dest_dept:02d}',
            constraint=factor >= statstat - M*(1 - is_dept_assigned),
        )

print('Station assignment variables:')
print(station_assign, end='\n\n')
print('Department assignment variables:')
print(dept_assign, end='\n\n')
print(prob)
prob.solve()
assert prob.status == pulp.LpStatusOptimal

print('Station solution:')
station_assign = station_assign.applymap(pulp.LpVariable.value)
print(station_assign.astype(int), end='\n\n')

print('Department solution:')
dept_assign = dept_assign.applymap(pulp.LpVariable.value)
print(dept_assign.astype(int), end='\n\n')

results = []
for source_station, workflow_col in workflow.items():
    for source_dept, workflow_rate in workflow_col.items():
        dept_row = dept_assign.loc[source_dept, :]
        dest_dept = dept_row[dept_row > 0.5].first_valid_index()
        stat_row = station_assign.loc[source_station, :]
        dest_station = stat_row[stat_row > 0.5].first_valid_index()
        results.append((
            distance.loc[dest_dept, dest_station], workflow_rate,
            source_dept, source_station, dest_dept, dest_station,
        ))
results = pd.DataFrame(
    results,
    columns=('new_dist', 'workflow', 'source_dept', 'source_stat', 'dest_dept', 'dest_stat'),
).sort_values(by=['workflow', 'new_dist'], ascending=False)

print('Assignments by distance-workflow cost:')
print(results.to_string(index=False))
Station assignment variables:
dest_station                  1   ...                10
source_station                    ...                  
1               station_01_to_01  ...  station_01_to_10
2               station_02_to_01  ...  station_02_to_10
3               station_03_to_01  ...  station_03_to_10
4               station_04_to_01  ...  station_04_to_10
5               station_05_to_01  ...  station_05_to_10
6               station_06_to_01  ...  station_06_to_10
7               station_07_to_01  ...  station_07_to_10
8               station_08_to_01  ...  station_08_to_10
9               station_09_to_01  ...  station_09_to_10
10              station_10_to_01  ...  station_10_to_10

[10 rows x 10 columns]

Department assignment variables:
dest_dept                1              2  ...              5              6
source_dept                                ...                              
1            dept_01_to_01  dept_01_to_02  ...  dept_01_to_05  dept_01_to_06
2            dept_02_to_01  dept_02_to_02  ...  dept_02_to_05  dept_02_to_06
3            dept_03_to_01  dept_03_to_02  ...  dept_03_to_05  dept_03_to_06
4            dept_04_to_01  dept_04_to_02  ...  dept_04_to_05  dept_04_to_06
5            dept_05_to_01  dept_05_to_02  ...  dept_05_to_05  dept_05_to_06
6            dept_06_to_01  dept_06_to_02  ...  dept_06_to_05  dept_06_to_06

[6 rows x 6 columns]

factory:
MINIMIZE
1*prod_dept_01_to_01 + 1*prod_dept_01_to_02 + 1*prod_dept_01_to_03 + 1*prod_dept_01_to_04 ...
SUBJECT TO
excl_dest_station_1: station_01_to_01 + station_02_to_01 + station_03_to_01
 + station_04_to_01 + station_05_to_01 + station_06_to_01 + station_07_to_01
 + station_08_to_01 + station_09_to_01 + station_10_to_01 = 1
...


excl_source_station_1: station_01_to_01 + station_01_to_02 + station_01_to_03
 + station_01_to_04 + station_01_to_05 + station_01_to_06 + station_01_to_07
 + station_01_to_08 + station_01_to_09 + station_01_to_10 = 1
...


prodlo_d01_to_d01: - 51030 dept_01_to_01 + prod_dept_01_to_01
 - 116 station_01_to_01 - 97 station_01_to_03 - 39 station_01_to_08
 - 28 station_01_to_09 - 193 station_01_to_10 - 116 station_02_to_01
 - 97 station_02_to_03 - 39 station_02_to_08 - 28 station_02_to_09
 - 193 station_02_to_10 - 348 station_03_to_01 - 291 station_03_to_03
 - 117 station_03_to_08 - 84 station_03_to_09 - 579 station_03_to_10
 - 348 station_04_to_01 - 291 station_04_to_03 - 117 station_04_to_08
 - 84 station_04_to_09 - 579 station_04_to_10 - 348 station_05_to_01
 - 291 station_05_to_03 - 117 station_05_to_08 - 84 station_05_to_09
 - 579 station_05_to_10 - 348 station_06_to_01 - 291 station_06_to_03
 - 117 station_06_to_08 - 84 station_06_to_09 - 579 station_06_to_10
 - 464 station_08_to_01 - 388 station_08_to_03 - 156 station_08_to_08
 - 112 station_08_to_09 - 772 station_08_to_10 - 580 station_09_to_01
 - 485 station_09_to_03 - 195 station_09_to_08 - 140 station_09_to_09
 - 965 station_09_to_10 - 348 station_10_to_01 - 291 station_10_to_03
 - 117 station_10_to_08 - 84 station_10_to_09 - 579 station_10_to_10 >= -51030
...



VARIABLES
0 <= dept_01_to_01 <= 1 Integer
0 <= dept_01_to_02 <= 1 Integer
0 <= dept_01_to_03 <= 1 Integer
0 <= dept_01_to_04 <= 1 Integer
0 <= dept_01_to_05 <= 1 Integer
0 <= dept_01_to_06 <= 1 Integer
0 <= dept_02_to_01 <= 1 Integer
0 <= dept_02_to_02 <= 1 Integer
0 <= dept_02_to_03 <= 1 Integer
0 <= dept_02_to_04 <= 1 Integer
0 <= dept_02_to_05 <= 1 Integer
0 <= dept_02_to_06 <= 1 Integer
0 <= dept_03_to_01 <= 1 Integer
0 <= dept_03_to_02 <= 1 Integer
0 <= dept_03_to_03 <= 1 Integer
0 <= dept_03_to_04 <= 1 Integer
0 <= dept_03_to_05 <= 1 Integer
0 <= dept_03_to_06 <= 1 Integer
0 <= dept_04_to_01 <= 1 Integer
0 <= dept_04_to_02 <= 1 Integer
0 <= dept_04_to_03 <= 1 Integer
0 <= dept_04_to_04 <= 1 Integer
0 <= dept_04_to_05 <= 1 Integer
0 <= dept_04_to_06 <= 1 Integer
0 <= dept_05_to_01 <= 1 Integer
0 <= dept_05_to_02 <= 1 Integer
0 <= dept_05_to_03 <= 1 Integer
0 <= dept_05_to_04 <= 1 Integer
0 <= dept_05_to_05 <= 1 Integer
0 <= dept_05_to_06 <= 1 Integer
0 <= dept_06_to_01 <= 1 Integer
0 <= dept_06_to_02 <= 1 Integer
0 <= dept_06_to_03 <= 1 Integer
0 <= dept_06_to_04 <= 1 Integer
0 <= dept_06_to_05 <= 1 Integer
0 <= dept_06_to_06 <= 1 Integer
prod_dept_01_to_01 Continuous
prod_dept_01_to_02 Continuous
prod_dept_01_to_03 Continuous
prod_dept_01_to_04 Continuous
prod_dept_01_to_05 Continuous
prod_dept_01_to_06 Continuous
prod_dept_02_to_01 Continuous
prod_dept_02_to_02 Continuous
prod_dept_02_to_03 Continuous
prod_dept_02_to_04 Continuous
prod_dept_02_to_05 Continuous
prod_dept_02_to_06 Continuous
prod_dept_03_to_01 Continuous
prod_dept_03_to_02 Continuous
prod_dept_03_to_03 Continuous
prod_dept_03_to_04 Continuous
prod_dept_03_to_05 Continuous
prod_dept_03_to_06 Continuous
prod_dept_04_to_01 Continuous
prod_dept_04_to_02 Continuous
prod_dept_04_to_03 Continuous
prod_dept_04_to_04 Continuous
prod_dept_04_to_05 Continuous
prod_dept_04_to_06 Continuous
prod_dept_05_to_01 Continuous
prod_dept_05_to_02 Continuous
prod_dept_05_to_03 Continuous
prod_dept_05_to_04 Continuous
prod_dept_05_to_05 Continuous
prod_dept_05_to_06 Continuous
prod_dept_06_to_01 Continuous
prod_dept_06_to_02 Continuous
prod_dept_06_to_03 Continuous
prod_dept_06_to_04 Continuous
prod_dept_06_to_05 Continuous
prod_dept_06_to_06 Continuous
0 <= station_01_to_01 <= 1 Integer
0 <= station_01_to_02 <= 1 Integer
0 <= station_01_to_03 <= 1 Integer
0 <= station_01_to_04 <= 1 Integer
0 <= station_01_to_05 <= 1 Integer
0 <= station_01_to_06 <= 1 Integer
0 <= station_01_to_07 <= 1 Integer
0 <= station_01_to_08 <= 1 Integer
0 <= station_01_to_09 <= 1 Integer
0 <= station_01_to_10 <= 1 Integer
0 <= station_02_to_01 <= 1 Integer
0 <= station_02_to_02 <= 1 Integer
0 <= station_02_to_03 <= 1 Integer
0 <= station_02_to_04 <= 1 Integer
0 <= station_02_to_05 <= 1 Integer
0 <= station_02_to_06 <= 1 Integer
0 <= station_02_to_07 <= 1 Integer
0 <= station_02_to_08 <= 1 Integer
0 <= station_02_to_09 <= 1 Integer
0 <= station_02_to_10 <= 1 Integer
0 <= station_03_to_01 <= 1 Integer
0 <= station_03_to_02 <= 1 Integer
0 <= station_03_to_03 <= 1 Integer
0 <= station_03_to_04 <= 1 Integer
0 <= station_03_to_05 <= 1 Integer
0 <= station_03_to_06 <= 1 Integer
0 <= station_03_to_07 <= 1 Integer
0 <= station_03_to_08 <= 1 Integer
0 <= station_03_to_09 <= 1 Integer
0 <= station_03_to_10 <= 1 Integer
0 <= station_04_to_01 <= 1 Integer
0 <= station_04_to_02 <= 1 Integer
0 <= station_04_to_03 <= 1 Integer
0 <= station_04_to_04 <= 1 Integer
0 <= station_04_to_05 <= 1 Integer
0 <= station_04_to_06 <= 1 Integer
0 <= station_04_to_07 <= 1 Integer
0 <= station_04_to_08 <= 1 Integer
0 <= station_04_to_09 <= 1 Integer
0 <= station_04_to_10 <= 1 Integer
0 <= station_05_to_01 <= 1 Integer
0 <= station_05_to_02 <= 1 Integer
0 <= station_05_to_03 <= 1 Integer
0 <= station_05_to_04 <= 1 Integer
0 <= station_05_to_05 <= 1 Integer
0 <= station_05_to_06 <= 1 Integer
0 <= station_05_to_07 <= 1 Integer
0 <= station_05_to_08 <= 1 Integer
0 <= station_05_to_09 <= 1 Integer
0 <= station_05_to_10 <= 1 Integer
0 <= station_06_to_01 <= 1 Integer
0 <= station_06_to_02 <= 1 Integer
0 <= station_06_to_03 <= 1 Integer
0 <= station_06_to_04 <= 1 Integer
0 <= station_06_to_05 <= 1 Integer
0 <= station_06_to_06 <= 1 Integer
0 <= station_06_to_07 <= 1 Integer
0 <= station_06_to_08 <= 1 Integer
0 <= station_06_to_09 <= 1 Integer
0 <= station_06_to_10 <= 1 Integer
0 <= station_07_to_01 <= 1 Integer
0 <= station_07_to_02 <= 1 Integer
0 <= station_07_to_03 <= 1 Integer
0 <= station_07_to_04 <= 1 Integer
0 <= station_07_to_05 <= 1 Integer
0 <= station_07_to_06 <= 1 Integer
0 <= station_07_to_07 <= 1 Integer
0 <= station_07_to_08 <= 1 Integer
0 <= station_07_to_09 <= 1 Integer
0 <= station_07_to_10 <= 1 Integer
0 <= station_08_to_01 <= 1 Integer
0 <= station_08_to_02 <= 1 Integer
0 <= station_08_to_03 <= 1 Integer
0 <= station_08_to_04 <= 1 Integer
0 <= station_08_to_05 <= 1 Integer
0 <= station_08_to_06 <= 1 Integer
0 <= station_08_to_07 <= 1 Integer
0 <= station_08_to_08 <= 1 Integer
0 <= station_08_to_09 <= 1 Integer
0 <= station_08_to_10 <= 1 Integer
0 <= station_09_to_01 <= 1 Integer
0 <= station_09_to_02 <= 1 Integer
0 <= station_09_to_03 <= 1 Integer
0 <= station_09_to_04 <= 1 Integer
0 <= station_09_to_05 <= 1 Integer
0 <= station_09_to_06 <= 1 Integer
0 <= station_09_to_07 <= 1 Integer
0 <= station_09_to_08 <= 1 Integer
0 <= station_09_to_09 <= 1 Integer
0 <= station_09_to_10 <= 1 Integer
0 <= station_10_to_01 <= 1 Integer
0 <= station_10_to_02 <= 1 Integer
0 <= station_10_to_03 <= 1 Integer
0 <= station_10_to_04 <= 1 Integer
0 <= station_10_to_05 <= 1 Integer
0 <= station_10_to_06 <= 1 Integer
0 <= station_10_to_07 <= 1 Integer
0 <= station_10_to_08 <= 1 Integer
0 <= station_10_to_09 <= 1 Integer
0 <= station_10_to_10 <= 1 Integer

Welcome to the CBC MILP Solver 
Version: 2.10.3 
Build Date: Dec 15 2019 

At line 2 NAME          MODEL
At line 3 ROWS
At line 73 COLUMNS
At line 2982 RHS
At line 3051 BOUNDS
At line 3188 ENDATA
Problem MODEL has 68 rows, 172 columns and 2600 elements
Coin0008I MODEL read with 0 errors
Option for timeMode changed from cpu to elapsed
...


Result - Optimal solution found

Objective value:                17271.00000000
Enumerated nodes:               1109
Total iterations:               45726
Time (CPU seconds):             3.43
Time (Wallclock seconds):       3.43

Option for printingOptions changed from normal to all
Total time (CPU seconds):       3.43   (Wallclock seconds):       3.43

Station solution:
dest_station    1   2   3   4   5   6   7   8   9   10
source_station                                        
1                0   0   1   0   0   0   0   0   0   0
2                0   0   0   0   0   0   0   0   1   0
3                1   0   0   0   0   0   0   0   0   0
4                0   0   0   0   0   0   0   1   0   0
5                0   0   0   0   0   1   0   0   0   0
6                0   0   0   0   0   0   0   0   0   1
7                0   0   0   0   1   0   0   0   0   0
8                0   0   0   0   0   0   1   0   0   0
9                0   1   0   0   0   0   0   0   0   0
10               0   0   0   1   0   0   0   0   0   0

Department solution:
dest_dept    1  2  3  4  5  6
source_dept                  
1            0  0  0  1  0  0
2            0  0  0  0  1  0
3            0  1  0  0  0  0
4            0  0  0  0  0  1
5            0  0  1  0  0  0
6            1  0  0  0  0  0

Assignments by distance-workflow cost:
 new_dist  workflow  source_dept  source_stat  dest_dept  dest_stat
        0        10            6            8          1          7
        0         9            2            8          5          7
        0         9            6            9          1          2
       12         8            4            2          6          9
        0         8            2            7          5          5
       39         7            2            4          5          8
        0         7            4            5          6          6
        0         7            2            9          5          2
      323         6            5            9          3          2
      193         6            2            6          5         10
       86         6            3            9          2          2
       79         6            3            8          2          7
       28         6            2            2          5          9
       17         6            4            4          6          8
        0         6            2            5          5          6
        0         6            2           10          5          4
        0         6            4           10          6          4
      377         5            5            8          3          7
      344         5            5           10          3          4
      116         5            2            3          5          1
       98         5            3           10          2          4
       83         5            4            3          6          1
       83         5            1            9          4          2
       69         5            4            1          6          3
       68         5            3            3          2          1
        0         5            6            5          1          6
      312         4            5            3          3          1
      136         4            1            8          4          7
       97         4            2            1          5          3
       78         4            3            4          2          8
       28         4            6            2          1          9
        0         4            6            7          1          5
        0         4            6           10          1          4
      335         3            5            1          3          3
      151         3            1            4          4          8
      128         3            1            5          4          6
      116         3            6            3          1          1
      106         3            1           10          4          4
       97         3            6            1          1          3
       72         3            1            3          4          1
       57         3            1            6          4         10
      173         1            1            2          4          9
      103         1            3            5          2          6
       95         1            1            1          4          3
       90         1            3            1          2          3
       87         1            4            9          6          2
       18         1            4            8          6          7
      414         0            5            2          3          9
      393         0            5            4          3          8
      367         0            5            5          3          6
      358         0            5            7          3          5
      318         0            5            6          3         10
      193         0            6            6          1         10
      171         0            4            6          6         10
      118         0            1            7          4          5
      104         0            3            7          2          5
       90         0            3            2          2          9
       67         0            3            6          2         10
       52         0            4            7          6          5
       39         0            6            4          1          8