найти все неповторяющиеся пути через набор связанных узлов / диаграмму процесса - PullRequest
2 голосов
/ 02 сентября 2011

Я пытаюсь понять, возможно ли каким-либо разумным способом установить набор неповторяющихся путей через данную диаграмму процесса.

Вот некоторые основные факты о диаграммах процессов, которые у меня есть:

  • у них есть одна или несколько начальных точек
  • у них есть одна или несколько конечных точек
  • все точки запуска имеют один разъем, ведущий от них
  • все шаги имеют как минимум один или несколько входящих соединителей и один или несколько исходящих Разъемы
  • если имеется более одного из следующих, каждый должен быть названы:
    • Стартовые терминаторы
    • Конечные терминаторы
    • Соединения, ведущие со ступени

У меня есть доступ ко всем данным, которые я могу себе представить (поиск всех начальных точек, получение всех соединений, имена соединений и т. Д.).

Я в основном хочу найти как можно больше уникальных путей в процессе от начальной точки до конечной точки, где вы не будете многократно повторять круг. так что вы можете пройти один и тот же шаг несколько раз, но вы не можете повторить полный цикл более одного раза на любом данном маршруте.

Это похоже на то, о чем люди писали бы статьи и имели доказательства того, почему это может или не может быть сделано, я просто не знаю волшебные слова, которые мне нужны, чтобы гуглить это ;-) Код Sudo или подобное было бы идеальным (и удивительно), но я с удовольствием читаю сам, если кто-то может указать мне правильное направление.

ЛЮБЫЕ УСЛОВИЯ ПОИСКА ПРЕДЛОЖЕНИЯ ОЧЕНЬ ДОБРО ПОЖАЛОВАТЬ И БОЛЬШЕ ЦЕНИТЬ Примечание Мне были бы интересны решения, которые предлагают множество дополнительных «глупых» возможностей, которые впоследствии человек должен рассмотреть, - все равно было бы интересно посмотреть, что оно породило.

Немного примера, чтобы прояснить ситуацию:

        G<--2-E<--1-F-2--|
        |     |     ^    |
        |     1     |    |
        |     |     2    |
        \/   \/     |   \/
start--->A--->B---->C-1->D---end

некоторые маршруты через:

  • старт, А, В, С: 1, D * конец * тысяча сорок-шесть * * +1047 старт, А, В, С: 2, F 1, Е: 1, B, C: 1, D * конец +1048 * * * Начало одна тысяча сорок-девять, А, В, С: 2, F 1, Е: 2, G, A, B, C: 1, D * конец 1050 *
  • старт, А, В, С: 2, F 2, D * конец * тысяча пятьдесят-две

хорошо, но как насчет более интересного:

Я нажимаю C три раза, и каждый раз выбираю второй вариант, и повторений нет.

Дополнительные точки : Я думал, что могу пометить некоторые узлы с несколькими исходящими соединителями как непротиворечивые при любом выполнении процесса. Например, если есть процесс «записи кода», имеющий точку принятия «языка» с двумя исходящими коннекторами «c #» и «java», я могу сказать, что при любом данном выполнении этого процесса это всегда будет либо c #, либо java - это будет никогда не меняйте во время выполнения процесса. в отличие от чего-то, что может измениться, как "есть ли ошибки?" который на первом проходе может иметь да, затем на втором проходе (после некоторого исправления ошибок ;-) может иметь результат нет.

Знаете ли вы какие-либо термины или методы, относящиеся к этому типу дополнительного анализа / обработки / определения?

РЕДАКТИРОВАТЬ: Я добавил пример решения, реализованного в JS в качестве ответа на основе ответа @ Иштар.

Ответы [ 3 ]

2 голосов
/ 02 сентября 2011

Как насчет глубины первого поиска?Это будет идти по всем возможным путям.Единственная сложная часть - игнорирование путей, которые снова приведут к тому же циклу.Если вы находитесь на узле, вы проверяете, были ли вы там раньше (цикл), и убедитесь, что такой же последовательности уже нет в пути.

Например,

start,A,B,C:2,F:1,E:1,B,C:2,F:1,E:1,B

Отсюда мы можем перейти только к C. Оглядываясь назад (последние 4 узла), мы находим цикл C:2,F:1,E:1,B.Цикл уже существует, поэтому мы не можем перейти к узлу c.Поскольку мы не можем никуда идти, эта ветвь не дает правильного пути.

Псевдокод:

allpaths(path,node)
  cycle = path.substring(path.lastIndex(node)) + node
  if path.contains(cycle)
    return
  path = path + node
  if node.isEndNode
    print path
    return
  for child in node.children
    allpaths(path, child)
1 голос
/ 02 сентября 2011

это актуально? поиск всех элементарных цепей ориентированного графа . даже если это не алгоритм, который вы используете, он может помочь с соответствующими определениями и именами.

0 голосов
/ 02 сентября 2011

полный пример на веб-странице решения @Ishtars, график - один из вопроса ... Кажется, он работает, а не тщательно его протестировал. Это гораздо более простое решение, чем я ожидал; -)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">

        function connection(name, endPoint) {
            this.name = name;
            this.endPoint = endPoint;
        }

        function node(name) {
            this.name = name;
            this.connections = [];

            this.addConnection = function (conn) {
                this.connections[this.connections.length] = conn;
            }
        }


        function printPath(path) {
            document.getElementById('output').innerHTML = 
              document.getElementById('output').innerHTML
              + path + '<br />';
        }

        function allPaths(path, node) {
            if (node.name == "end") {
                printPath(path + ',' + node.name);
                return;
            }
            cycle = path.substring(path.lastIndexOf(node.name)) + ',' + node.name;
            if (cycle.length > 1 && path.indexOf(cycle) > 0) {
                return;
            }
            for (var i = 0; i < node.connections.length; i++) {
               allPaths(path + ',' + node.name + ":" + 
                   node.connections[i].name
                   ,node.connections[i].endPoint);
            }
       }

        var start = new node("start");
        var a = new node("A");
        var b = new node("B");
        var c = new node("C");
        var d = new node("D");
        var e = new node("E");
        var f = new node("F");
        var g = new node("G");
        var end = new node("end");

        start.addConnection(new connection("1", a));
        a.addConnection(new connection("1", b));
        b.addConnection(new connection("1", c));
        c.addConnection(new connection("1", d));
        c.addConnection(new connection("2", f));
        d.addConnection(new connection("1", end));
        f.addConnection(new connection("1", e));
        f.addConnection(new connection("2", d));
        e.addConnection(new connection("1", b));
        e.addConnection(new connection("2", g));
        g.addConnection(new connection("1", a));

    </script>
</head>
<body onload="javascript:allPaths('start', a)";>
    <div id="output"></div>
</body>
</html>

и вот вывод (на всякий случай, если кто-то может обнаружить ошибку; -):

start,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:1,E:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:2,D:1,end

Полагаю, я не знал о jsFiddle, когда писал это, вот скрипка с приведенным выше кодом:

http://jsfiddle.net/6bWMp/1/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...