Моє розуміння проблеми, як спочатку було заявлено і потім оновлено коментарями у відповіді Макке, включає таке: 1) спрямовані обидва типи краю (залежності та конфлікти); 2) якщо два вузли з'єднані одним краєм, вони не повинні бути з'єднані іншим, навіть якщо він іншого типу або зворотно; 3) якщо шлях між двома вузлами можна побудувати шляхом змішування ребер різних типів, то це помилка, а не обставина, яка ігнорується; 4) Якщо існує шлях між двома вузлами з використанням ребер одного типу, то між ними не може бути іншого шляху, використовуючи ребра іншого типу; 5) цикли або одного типу ребер, або змішаних типів ребер не дозволені (з здогадки в застосуванні, я не впевнений, що цикли, що стосуються лише конфлікту, є помилкою, але ця умова може бути усунена, якщо ні.)
Крім того, я припускаю, що використовувана структура даних не перешкоджає вираженню порушень цих вимог (наприклад, графік, що порушує умову 2, не може бути виражений у карті від пари вузлів до (тип, напрямок), якщо пара вузлів завжди спочатку має найменший номер вузла.) Якщо певні помилки неможливо виразити, це зменшує кількість випадків, які слід розглядати.
Тут насправді можна розглядати три графіки: два виключно одного реберного типу та змішаний графік, утворений об'єднанням одного з двох типів. Ви можете використовувати це для систематичного генерування всіх графіків до деякої кількості вузлів. Спочатку згенеруйте всі можливі графіки з N вузлів, що мають не більше одного краю між будь-якими двома упорядкованими парами вузлів (упорядковані пари, оскільки це спрямовані графіки.) Тепер візьміть усі можливі пари цих графіків, один представляє залежності, а другий представляє конфлікти, і утворюють союз кожної пари.
Якщо ваша структура даних не може виражати порушення умови 2, ви можете значно зменшити випадки, які слід розглядати, лише побудувавши всі можливі конфліктні графіки, що входять у проміжки графіків залежності, або навпаки. В іншому випадку ви можете виявити порушення умови 2 під час формування союзу.
На першому широтному обході комбінованого графіка від першого вузла ви можете побудувати набір усіх шляхів до кожного доступного вузла, і, зробивши це, ви можете перевірити на порушення всіх умов (для виявлення циклу ви могли б використовувати алгоритм Таряна .)
Вам слід розглянути лише шляхи від першого вузла, навіть якщо графік відключений, оскільки шляхи від будь-якого іншого вузла будуть відображатися як шляхи від першого вузла в іншому випадку.
Якщо змішані контури можна просто ігнорувати, а не помилятись (умова 3), достатньо розглянути графіки залежності та конфлікту незалежно та перевірити, якщо вузол досяжний в одному, він не в іншому.
Якщо ви пам’ятаєте шляхи, знайдені при вивченні графіків вузлів N-1, ви можете використовувати їх як вихідну точку для генерації та оцінки графіків N вузлів.
Це не створює декілька ребер одного типу між вузлами, але це може бути розширено для цього. Однак це значно збільшить кількість випадків, тому було б краще, якби тестований код унеможливив уявлення або, якщо це не вдалося, попередньо відфільтрував усі подібні випадки.
Ключовим моментом написання подібного оракула є збереження його максимально просто, навіть якщо це означає неефективність, щоб ви могли довіритись йому (в ідеалі за допомогою аргументів на його правильність, підкріплених тестуванням.)
Коли у вас є засоби для генерування тестових випадків, і ви довіряєте створеному оракулу, щоб точно відокремити добро від поганого, ви можете використовувати це для автоматичного тестування цільового коду. Якщо це неможливо, ваш наступний найкращий варіант - прочесати результати для відмінних випадків. Оракул може класифікувати знайдені помилки та надати деяку інформацію про прийняті випадки, такі як кількість та довжина шляхів кожного типу, а також чи є вузли, які знаходяться на початку обох типів шляху, і це може допомогти вам шукати випадки, яких ви ще не бачили.