简体   繁体   English

删除最小数量的顶点以在图中找到链

[英]Remove the minimum number of vertices to find the chain in the graph

I have a graph (not directed and not weighted) and its adjacency matrix (matrix type - boolean).我有一个图(非定向且非加权)及其邻接矩阵(矩阵类型 - 布尔值)。 I need to remove the minimum number of vertices to find the chain in this graph.我需要删除最小数量的顶点才能在此图中找到链。 For the last two days I've been thinking about how to do this and haven't come to any decision, so I ask you for help.这两天我一直在想怎么做,还没有做出任何决定,所以我请你帮忙。

In my head I have a rough idea of a solution, but I can't implement it.在我的脑海中,我对解决方案有一个粗略的想法,但我无法实现它。 Here are my thoughts on this task.以下是我对这项任务的看法。

  1. Find the longest chain找到最长的链
  2. Create an adjacency matrix for this chain为这个链创建一个邻接矩阵
  3. Change the initial adjacency matrix改变初始邻接矩阵

Here is my attempts to implement this algorithm这是我实现这个算法的尝试

    public void createChain() {
    int[][] maxMatrix = new int[adjMatrix.length][adjMatrix.length];
    Map<Integer, int[][]> curStr = new HashMap<>();
    Map<Integer, Map<Integer, int[][]>> maxStr = new HashMap<>();

    for (int i = 0; i < adjMatrix.length; i++) {
        for (int j = 0; j < adjMatrix.length; j++) {
            maxMatrix[i][j] = 0;
        }
    }
    createChain(maxMatrix, curStr, maxStr, 0);

    int maxKey = 0;
    for (int key : maxStr.keySet()) {
        if (key > maxKey) maxKey = key;
    }

    curStr = maxStr.get(maxKey);
    int maxKey1 = 0;
    for (int key : curStr.keySet()) {
        if (key > maxKey1) {
            maxKey1 = key;
        }
    }
    maxMatrix = curStr.get(maxKey1);

    for (int i = 0; i < maxMatrix.length; i++) {
        for (int j = 0; j < maxMatrix.length; j++) {
            adjMatrix[i][j] = maxMatrix[i][j] == 1;
        }
    }

}

private void createChain(int[][] matrix, Map<Integer, int[][]> curStr, Map<Integer, Map<Integer, int[][]>> maxStr, int i) {
    for (int j = i; j < matrix.length; j++) {
        if (adjMatrix[i][j]) {

            if (!curStr.containsKey(i)) {
                matrix[i][j] = 1;
                curStr.put(i, matrix);
                i = j;

                maxStr.put(curStr.size(), curStr);
                Map<Integer, int[][]> copyOfCurStr = new HashMap<>();
                for (Integer key : curStr.keySet()) {
                    copyOfCurStr.put(key, copyOfCurStr.get(key));
                }

                int[][] copyOfMatrix = new int[matrix.length][matrix.length];
                for (int k = 0; k < matrix.length; k++) {
                    for (int l = 0; l < matrix.length; l++) {
                        copyOfMatrix[i][j] = matrix[i][j];
                    }
                }
                createChain(copyOfMatrix, copyOfCurStr, maxStr, i);
            }
        }
    }
}

the program works for some input, but not for other.该程序适用于某些输入,但不适用于其他输入。 For example:例如:

  1. input , output .输入output As you see, everything is working如您所见,一切正常
  2. input , output .输入output The algorithm is not working correctly.该算法无法正常工作。 The output should be like this output应该是这样

I think I found a solution.我想我找到了解决办法。 It is implemented based on a modified Hamiltonian path search algorithm.它是基于改进的哈密顿路径搜索算法实现的。

private boolean isSafe(int v, int graph[][], int path[], int pos) {
    if (graph[path[pos - 1]][v] == 0)
        return false;

    for (int i = 0; i < pos; i++)
        if (path[i] == v)
            return false;

    return true;
}


private void hamCycleUtil(int graph[][], int path[], int pos, List<int[]> paths) {
    if (pos >= adjMatrix.length) {
        return;
    }

    for (int v = 0; v < adjMatrix.length; v++) {
        if (isSafe(v, graph, path, pos)) {
            path[pos] = v;

            int[] copyOfPath = new int[adjMatrix.length];
            System.arraycopy(path, 0, copyOfPath, 0, adjMatrix.length);
            paths.add(copyOfPath);


            hamCycleUtil(graph, path, pos + 1, paths);

            path[pos] = -1;
        }
    }
}


public int createChain() {
    List<int[]> paths = new ArrayList<>();
    int[][] matrix = new int[adjMatrix.length][adjMatrix.length];
    for (int i = 0; i < adjMatrix.length; i++) {
        for (int j = 0; j < adjMatrix.length; j++) {
            if (adjMatrix[i][j]) matrix[i][j] = 1;
            else matrix[i][j] = 0;
        }
    }
    int[] path = new int[adjMatrix.length];
    Arrays.fill(path, -1);

    for (int i = 0; i < adjMatrix.length; i++) {
        path[0] = i;
        hamCycleUtil(matrix, path, 1, paths);
    }

    int[] maxPath = new int[adjMatrix.length];
    Arrays.fill(maxPath, -1);
    int quantityOfElems = 0;
    int maxPathLength = 0;
    for (int[] chain : paths) {
        for (int value : chain) {
            if (value == -1) {
                break;
            }
            quantityOfElems++;
        }
        for (int value : maxPath) {
            if (value == -1) {
                break;
            }
            maxPathLength++;
        }
        if (quantityOfElems >= maxPathLength) {
            maxPath = Arrays.copyOf(chain, chain.length);
        }
        maxPathLength = 0;
        quantityOfElems = 0;
    }

    /*
    for (int value : maxPath) {
        System.out.print(value + " ");
    }
    System.out.println();*/

    for (int i = 0; i < adjMatrix.length; i++) {
        for (int j = 0; j < adjMatrix.length; j++) {
            adjMatrix[i][j] = false;
        }
    }

    quantityOfElems = 0;
    for (int i = 0; i < maxPath.length - 1; i++) {
        if (maxPath[i] == -1 || maxPath[i + 1] == -1) break;
        adjMatrix[maxPath[i]][maxPath[i + 1]] = true;
        adjMatrix[maxPath[i + 1]][maxPath[i]] = true;
        quantityOfElems++;
    }

    return maxPath.length - quantityOfElems - 1;
}

Examples:例子:

  1. input , output输入output
  2. input , output输入output

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM