【问题标题】:Remove the minimum number of vertices to find the chain in the graph删除最小数量的顶点以在图中找到链
【发布时间】:2020-06-25 16:43:21
【问题描述】:

我有一个图(非有向图和非加权图)及其邻接矩阵(矩阵类型 - 布尔值)。我需要删除最小数量的顶点才能在此图中找到链。 这两天我一直在想怎么做,还没有做出任何决定,所以请你帮忙。

在我的脑海中我有一个解决方案的粗略想法,但我无法实现它。 以下是我对这项任务的看法。

  1. 找到最长的链
  2. 为此链创建邻接矩阵
  3. 更改初始邻接矩阵

这是我实现这个算法的尝试

    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);
            }
        }
    }
}

该程序适用于某些输入,但不适用于其他输入。 例如:

  1. inputoutput。如您所见,一切正常
  2. inputoutput。该算法无法正常工作。输出应该是like this

【问题讨论】:

  • 什么是“链”?
  • @amit 图中的链是使用边从一个顶点到另一个顶点的一系列顶点。链的长度是使用的边数,或使用的顶点数减一。一个简单的链不能两次访问同一个顶点。算法的结果应该是一个简单的链
  • 感谢您的澄清。这方面的术语是path。您要解决的问题似乎是Hamiltonian Path Problem 的变体
  • @amit 感谢您的帮助

标签: java algorithm matrix graph


【解决方案1】:

我想我找到了解决办法。它是基于改进的哈密顿路径搜索算法实现的。

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;
}

例子:

  1. input, output
  2. input, output

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    相关资源
    最近更新 更多