Repository: Qiskit/qiskit

Issue:
optimization_level=1 always uses Trivial layout
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: master
- **Python version**:
- **Operating system**:

### What is the current behavior?
```
               ┌───┐                ░ ┌─┐            
q37_0: |0>─────┤ X ├────────────────░─┤M├────────────
          ┌───┐└─┬─┘┌───┐           ░ └╥┘┌─┐         
q37_1: |0>┤ H ├──■──┤ X ├───────────░──╫─┤M├─────────
          ├───┤     └─┬─┘┌───┐      ░  ║ └╥┘┌─┐      
q37_2: |0>┤ H ├───────■──┤ X ├──────░──╫──╫─┤M├──────
          ├───┤          └─┬─┘┌───┐ ░  ║  ║ └╥┘┌─┐   
q37_3: |0>┤ H ├────────────■──┤ X ├─░──╫──╫──╫─┤M├───
          ├───┤               └─┬─┘ ░  ║  ║  ║ └╥┘┌─┐
q37_4: |0>┤ H ├─────────────────■───░──╫──╫──╫──╫─┤M├
          └───┘                     ░  ║  ║  ║  ║ └╥┘
  c5_0: 0 ═════════════════════════════╩══╬══╬══╬══╬═
                                          ║  ║  ║  ║ 
  c5_1: 0 ════════════════════════════════╩══╬══╬══╬═
                                             ║  ║  ║ 
  c5_2: 0 ═══════════════════════════════════╩══╬══╬═
                                                ║  ║ 
  c5_3: 0 ══════════════════════════════════════╩══╬═
                                                   ║ 
  c5_4: 0 ═════════════════════════════════════════╩═
```
```python
backend = provider.get_backend('ibmq_20_tokyo')
new_qc = transpile(qc, backend, optimization_level=1)
```

shows initial layout as the trivial layout, which is disconnected:

<img width="296" alt="Screen Shot 2019-07-22 at 4 14 54 PM" src="https://user-images.githubusercontent.com/1249193/61662177-e564af00-ac9b-11e9-94bb-0dbe3fbe0e20.png">

However part #2 in the source says `_layout_check` does better layout 
if the circuit needs swaps, 

```python
# 2. Use a better layout on densely connected qubits, if circuit needs swaps
```
which is obviously the case here, but no other layouts
are actually selected (or imported).

### Steps to reproduce the problem



### What is the expected behavior?
Expected that the `DenseLayout` is used if there are swaps needed.


### Suggested solutions





Discussion:
Confirmed.
```python
qr = QuantumRegister(5)
cr = ClassicalRegister(5)
qc = QuantumCircuit(qr, cr)

qc.h(qr[1])
qc.h(qr[2])
qc.h(qr[3])
qc.h(qr[4])
qc.cx(qr[0], qr[1])
qc.cx(qr[1], qr[2])
qc.cx(qr[2], qr[3])
qc.cx(qr[3], qr[4])
qc.barrier(qr)
qc.measure(qr, cr)

backend = IBMQ.get_backend('ibmq_20_tokyo')
new_qc = transpile(qc, backend, optimization_level=1)
print('\n'.join([str((i, j)) for i, j in new_qc.layout._p2v.values() if i.name != 'ancilla']))
```
```
(QuantumRegister(5, 'q0'), 0)
(QuantumRegister(5, 'q0'), 1)
(QuantumRegister(5, 'q0'), 2)
(QuantumRegister(5, 'q0'), 3)
(QuantumRegister(5, 'q0'), 4)
```

Is also `optimization_level=2` having a similar issue?
```python
new_qc = transpile(qc, backend, optimization_level=2)
print('\n'.join([str((i, j)) for i, j in new_qc.layout._p2v.values() if i.name != 'ancilla']))
```
```
(QuantumRegister(5, 'q0'), 1)
(QuantumRegister(5, 'q0'), 4)
(QuantumRegister(5, 'q0'), 2)
(QuantumRegister(5, 'q0'), 3)
(QuantumRegister(5, 'q0'), 0)
```
Re-opened by #2975, will revisit post-0.9.
This can be fixed once "best of" approach is implemented (see #2969). On hold until then.


Resolving patch:
diff --git a/qiskit/transpiler/passes/layout/noise_adaptive_layout.py b/qiskit/transpiler/passes/layout/noise_adaptive_layout.py
--- a/qiskit/transpiler/passes/layout/noise_adaptive_layout.py
+++ b/qiskit/transpiler/passes/layout/noise_adaptive_layout.py
@@ -208,9 +208,13 @@ def run(self, dag):
         num_qubits = self._create_program_graph(dag)
         if num_qubits > len(self.swap_graph):
             raise TranspilerError('Number of qubits greater than device.')
-        for end1, end2, _ in sorted(self.prog_graph.edges(data=True),
-                                    key=lambda x: x[2]['weight'], reverse=True):
-            self.pending_program_edges.append((end1, end2))
+
+        # sort by weight, then edge name for determinism (since networkx on python 3.5 returns
+        # different order of edges)
+        self.pending_program_edges = sorted(self.prog_graph.edges(data=True),
+                                            key=lambda x: [x[2]['weight'], -x[0], -x[1]],
+                                            reverse=True)
+
         while self.pending_program_edges:
             edge = self._select_next_edge()
             q1_mapped = edge[0] in self.prog2hw
diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py
--- a/qiskit/transpiler/preset_passmanagers/level1.py
+++ b/qiskit/transpiler/preset_passmanagers/level1.py
@@ -38,6 +38,8 @@
 from qiskit.transpiler.passes import Optimize1qGates
 from qiskit.transpiler.passes import ApplyLayout
 from qiskit.transpiler.passes import CheckCXDirection
+from qiskit.transpiler.passes import Layout2qDistance
+from qiskit.transpiler.passes import DenseLayout
 
 
 def level_1_pass_manager(transpile_config):
@@ -64,17 +66,18 @@ def level_1_pass_manager(transpile_config):
     coupling_map = transpile_config.coupling_map
     initial_layout = transpile_config.initial_layout
     seed_transpiler = transpile_config.seed_transpiler
+    backend_properties = getattr(transpile_config, 'backend_properties', None)
 
     # 1. Use trivial layout if no layout given
-    _given_layout = SetLayout(initial_layout)
+    _set_initial_layout = SetLayout(initial_layout)
 
     def _choose_layout_condition(property_set):
         return not property_set['layout']
 
-    _choose_layout = TrivialLayout(coupling_map)
-
     # 2. Use a better layout on densely connected qubits, if circuit needs swaps
-    _layout_check = CheckMap(coupling_map)
+    def _not_perfect_yet(property_set):
+        return property_set['trivial_layout_score'] is not None and \
+               property_set['trivial_layout_score'] != 0
 
     # 3. Extend dag/layout with ancillas using the full coupling map
     _embed = [FullAncillaAllocation(coupling_map), EnlargeWithAncilla(), ApplyLayout()]
@@ -114,9 +117,11 @@ def _opt_control(property_set):
 
     pm1 = PassManager()
     if coupling_map:
-        pm1.append(_given_layout)
-        pm1.append(_choose_layout, condition=_choose_layout_condition)
-        pm1.append(_layout_check)
+        pm1.append(_set_initial_layout)
+        pm1.append([TrivialLayout(coupling_map),
+                    Layout2qDistance(coupling_map, property_name='trivial_layout_score')],
+                   condition=_choose_layout_condition)
+        pm1.append(DenseLayout(coupling_map, backend_properties), condition=_not_perfect_yet)
         pm1.append(_embed)
     pm1.append(_unroll)
     if coupling_map:


Test patch:
diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py
--- a/test/python/transpiler/test_preset_passmanagers.py
+++ b/test/python/transpiler/test_preset_passmanagers.py
@@ -275,6 +275,57 @@ def test_layout_tokyo_2845(self, level):
                                  13: ancilla[8], 14: ancilla[9], 15: ancilla[10], 16: ancilla[11],
                                  17: ancilla[12], 18: ancilla[13], 19: ancilla[14]}
 
+        # Trivial layout
+        expected_layout_level0 = trivial_layout
+        # Dense layout
+        expected_layout_level1 = dense_layout
+        expected_layout_level2 = dense_layout
+        # Noise adaptive layout
+        expected_layout_level3 = noise_adaptive_layout
+
+        expected_layouts = [expected_layout_level0,
+                            expected_layout_level1,
+                            expected_layout_level2,
+                            expected_layout_level3]
+        backend = FakeTokyo()
+        result = transpile(qc, backend, optimization_level=level, seed_transpiler=42)
+        self.assertEqual(result._layout._p2v, expected_layouts[level])
+
+    @data(0, 1, 2, 3)
+    def test_trivial_layout(self, level):
+        """Test that, when possible, trivial layout should be preferred in level 0 and 1
+        See: https://github.com/Qiskit/qiskit-terra/pull/3657#pullrequestreview-342012465
+        """
+        qr = QuantumRegister(10, 'qr')
+        qc = QuantumCircuit(qr)
+        qc.cx(qr[0], qr[1])
+        qc.cx(qr[1], qr[2])
+        qc.cx(qr[2], qr[3])
+        qc.cx(qr[3], qr[9])
+        qc.cx(qr[4], qr[9])
+        qc.cx(qr[9], qr[8])
+        qc.cx(qr[8], qr[7])
+        qc.cx(qr[7], qr[6])
+        qc.cx(qr[6], qr[5])
+        qc.cx(qr[5], qr[0])
+
+        ancilla = QuantumRegister(10, 'ancilla')
+        trivial_layout = {0: qr[0], 1: qr[1], 2: qr[2], 3: qr[3], 4: qr[4],
+                          5: qr[5], 6: qr[6], 7: qr[7], 8: qr[8], 9: qr[9],
+                          10: ancilla[0], 11: ancilla[1], 12: ancilla[2], 13: ancilla[3],
+                          14: ancilla[4], 15: ancilla[5], 16: ancilla[6], 17: ancilla[7],
+                          18: ancilla[8], 19: ancilla[9]}
+
+        dense_layout = {0: qr[9], 1: qr[8], 2: qr[6], 3: qr[1], 4: ancilla[0], 5: qr[7], 6: qr[4],
+                        7: qr[5], 8: qr[0], 9: ancilla[1], 10: qr[3], 11: qr[2], 12: ancilla[2],
+                        13: ancilla[3], 14: ancilla[4], 15: ancilla[5], 16: ancilla[6],
+                        17: ancilla[7], 18: ancilla[8], 19: ancilla[9]}
+
+        noise_adaptive_layout = {0: qr[6], 1: qr[7], 2: ancilla[0], 3: ancilla[1], 4: ancilla[2],
+                                 5: qr[5], 6: qr[0], 7: ancilla[3], 8: ancilla[4], 9: ancilla[5],
+                                 10: ancilla[6], 11: qr[1], 12: ancilla[7], 13: qr[8], 14: qr[9],
+                                 15: ancilla[8], 16: ancilla[9], 17: qr[2], 18: qr[3], 19: qr[4]}
+
         # Trivial layout
         expected_layout_level0 = trivial_layout
         expected_layout_level1 = trivial_layout
@@ -290,3 +341,30 @@ def test_layout_tokyo_2845(self, level):
         backend = FakeTokyo()
         result = transpile(qc, backend, optimization_level=level, seed_transpiler=42)
         self.assertEqual(result._layout._p2v, expected_layouts[level])
+
+    @data(0, 1, 2, 3)
+    def test_initial_layout(self, level):
+        """When a user provides a layout (initial_layout), it should be used.
+        """
+        qr = QuantumRegister(10, 'qr')
+        qc = QuantumCircuit(qr)
+        qc.cx(qr[0], qr[1])
+        qc.cx(qr[1], qr[2])
+        qc.cx(qr[2], qr[3])
+        qc.cx(qr[3], qr[9])
+        qc.cx(qr[4], qr[9])
+        qc.cx(qr[9], qr[8])
+        qc.cx(qr[8], qr[7])
+        qc.cx(qr[7], qr[6])
+        qc.cx(qr[6], qr[5])
+        qc.cx(qr[5], qr[0])
+
+        initial_layout = {0: qr[0], 2: qr[1], 4: qr[2], 6: qr[3], 8: qr[4],
+                          10: qr[5], 12: qr[6], 14: qr[7], 16: qr[8], 18: qr[9]}
+
+        backend = FakeTokyo()
+        result = transpile(qc, backend, optimization_level=level, initial_layout=initial_layout,
+                           seed_transpiler=42)
+
+        for physical, virtual in initial_layout.items():
+            self.assertEqual(result._layout._p2v[physical], virtual)