Increasingly, high-assurance software systems apply selfreconfiguration in order to satisfy changing functional and non-functional requirements. Most self-reconfiguration approaches identify a target system configuration to provide the desired system behavior, then apply a series of reconfiguration instructions to reach the desired target configuration. Collectively, these reconfiguration instructions define an adaptation path. Although multiple satisfying adaptation paths may exist, most self-reconfiguration approaches select adaptation paths based on a single criterion, such as minimizing reconfiguration cost. However, different adaptation paths may represent tradeoffs between reconfiguration costs and other criteria, such as performance and reliability. This paper introduces an evolutionary computationbased approach to automatically evolve adaptation paths that safely transition an executing system from its current configuration to its desired target configuration, while balancing tradeoffs between functional and non-functional requirements. The proposed approach can be applied both at design time to generate suites of adaptation paths, as well as at run time to evolve safe adaptation paths to handle changing system and environmental conditions. We demonstrate the effectiveness of this approach by applying it to the dynamic reconfiguration of a collection of remote data mirrors, with the goal of minimizing reconfiguration costs while maximizing reconfiguration performance and reliability.