Skip to content

implement a random graph generator : layer by layer method#6

Open
huggingstar wants to merge 2693 commits intolingeringsocket:masterfrom
jgrapht:master
Open

implement a random graph generator : layer by layer method#6
huggingstar wants to merge 2693 commits intolingeringsocket:masterfrom
jgrapht:master

Conversation

@huggingstar
Copy link

package dag.auxiliary;

import org.apache.commons.math3.distribution.NormalDistribution;
import org.jgrapht.DirectedGraph;
import org.jgrapht.Graph;
import org.jgrapht.VertexFactory;
import org.jgrapht.generate.GraphGenerator;
import org.jgrapht.graph.AbstractBaseGraph;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;



/**
 *
 * random graph generator : layer by layer generaotr
 * In the academic paper, it is shown below,
 * Algorithm:  Layer-by-Layer method.
 * Require: n, k, p ∈ N.
 * Distribute n vertices between k different sets enumerated as L1, . . . , Lk.
 * Let layer(v) be the layer assigned to vertex v.
 * Let M be an adjacency matrix n×n initialized as the zero matrix.
 * for all i = 1 to n do
 *     for all j = 1 to n do
 *         if layer(j) > layer(i) then
 *             if Random() < p then
 *                 M[i][j] = 1
 *             else
 *                 M[i][j] = 0
 * return a random DAG with k layers and n nodes
 *
 * the original algorithm indicates that a node in layer 2 may connect to nodes in layer 3
 * or layer 4 and so on.
 * I make some changes that the node only can connect to the nodes in the next layer.
 * for example, a node in layer 2 only can connect to the nodes in layer 3.
 *
 *     graph features:
 * 1. there is only one node in the first and the last layer, respectively.
 * 2. the only one node in the first layer connects to every node in the second layer.
 * 3. every node in the second to last layer connects to the only one node in the last layer.
 * 4. layers except the first layer and the last layer are called middle layers.
 * 5. Every node connect to the each node which is in next layer according to some probability.
 * 6. Every node in the middle layers has at least one predecessor and one successor.
 *
 * for example, there is a allocaion of nodes expressed in array.
 * int[][] allocation = {{0},                      // layer 0
 *                       {11, 12, 13, 14}},        // layer 1
 *                       {21, 22, 23, 24, 25},     // layer 2
 *                       {4}};                     // layer 3
 * the number of each entry is the node's name,
 * every one-dimensional array represents the content expressing the corresponding layer
 * the edges are like that,
 * 0 --> 11, 0 --> 12, 0 --> 13, 0 --> 14,
 * 11 --> 21, 11 --> 24,    (according to some probability)
 * 12 --> 22, 12 --> 23, 12 --> 25,     (according to some probability)
 * 13 --> 24, 13 --> 25       (according to some probability)
 * 14 --> 21, 14 --> 23     (according to some probability)
 * 21 --> 4,
 * 22 --> 4,
 * 23 --> 4,
 * 24 --> 4,
 * 25 --> 4,
 *
 */



/**
 * @param <V>
 * @param <E>
 */

public class LayerByLayerGenerator<V, E> implements GraphGenerator<V, E, V> {
    private static final boolean DEFAULT_ALLOW_LOOPS = false;


    private final int num_layer;    // 层数  the number of layer
    private final Random rng;
    private final int n;        // 节点数  the number of node
    private final double p;
    private final boolean loops;
    private HashMap<Integer, Integer> vertex_cost = new HashMap<>();    // every node has its cost
    private int total_cost = 0;
    // 每一层有哪些节点
    private int[][] detail;     // allocation of nodes

    /**
     * Create a new Layer-by-Layer random graph generator. The generator does not create self-loops.
     *
     * @param n the number of nodes
     * @param p the edge probability
     */
    public LayerByLayerGenerator(int n, double p, int num_layer) {
        this(n, p, new Random(), DEFAULT_ALLOW_LOOPS, num_layer);
    }


    /**
     * Create a new Layer-by-Layer random graph generator. The generator does not create self-loops.
     *
     * @param n    the number of nodes
     * @param p    the edge probability
     * @param seed seed for the random number generator
     */
    public LayerByLayerGenerator(int n, double p, long seed, int num_layer) {
        this(n, p, new Random(seed), DEFAULT_ALLOW_LOOPS, num_layer);
    }

    /**
     * Create a new Layer-by-Layer random graph generator.
     *
     * @param n     the number of nodes
     * @param p     the edge probability
     * @param seed  seed for the random number generator
     * @param loops whether the generated graph may create loops
     */
    public LayerByLayerGenerator(int n, double p, long seed, boolean loops, int num_layer) {
        this(n, p, new Random(seed), loops, num_layer);
    }

    /**
     * Create a new Layer-by-Layer random graph generator.
     *
     * @param n         the number of nodes
     * @param p         the edge probability
     * @param rng       the random number generator to use
     * @param loops     whether the generated graph may create loops
     * @param num_layer the number of layer
     */
    public LayerByLayerGenerator(int n, double p, Random rng, boolean loops, int num_layer) {
        if (n < 6) {
            // the number of node can not smaller than 6
            throw new IllegalArgumentException("节点个数不能小于 6 ");
        }
        this.n = n;
        if (p < 0.0 || p > 1.0) {
            throw new IllegalArgumentException("概率P在 (0, 1) 之间");
        }
        if (num_layer < 3 || num_layer > n) {

            throw new IllegalArgumentException("层数不能小于3,且层数不能大于节点数");
        }
        this.num_layer = num_layer;
        this.p = p;
        this.rng = rng;
        this.loops = loops;
    }

    /**
     * Generates a random graph based on the Layer-by-Layer model.
     *
     * @param target        the target graph
     * @param vertexFactory the vertex factory
     * @param resultMap     not used by this generator, can be null
     */
    @Override
    public void generateGraph(Graph<V, E> target, VertexFactory<V> vertexFactory, Map<String, V> resultMap) {
        // special case
        if (n == 0) {
            return;
        }

        // check whether to also create loops
        boolean createLoops = loops;
        if (createLoops) {
            if (target instanceof AbstractBaseGraph<?, ?>) {
                AbstractBaseGraph<V, E> abg = (AbstractBaseGraph<V, E>) target;
                if (!abg.isAllowingLoops()) {
                    throw new IllegalArgumentException(
                            "Provided graph does not support self-loops");
                }
            } else {
                createLoops = false;
            }
        }

        /**
         *  创建节点
         *  create vertices
          */
        // 节点从 0 开始计数
        // name of node start from number 0

        // 操作 HashMap<Integer, Integer> vertex_cost;
        // 设置 每个节点的 执行时间
        int previousVertexSetSize = target.vertexSet().size();
        HashMap<Integer, V> vertices = new HashMap<>(n);
        for (int i = 0; i < n; i++) {
            V v = vertexFactory.createVertex();
            target.addVertex(v);
            vertices.put(i, v);
            // 设置节点的 cost
            // set node's cost value
            int cost = getVertexCost();
            total_cost += cost;
            vertex_cost.put(i, cost);
        }

        if (target.vertexSet().size() != previousVertexSetSize + n) {
            throw new IllegalArgumentException(
                    "Vertex factory did not produce " + n + " distinct vertices.");
        }

        // check if graph is directed
        boolean isDirected = target instanceof DirectedGraph<?, ?>;

        // 确定各层节点数分布情况
        // specify the allocation of the number of node of each layer
        detail = quantifyAllocation(n, num_layer);


        /**
         * 创建边
         * create edge
         *
         * 一层中,一个节点至少要与下一层中的一个节点相连接
         */
        // 对每一层
        // for each layer
        for (int i = 0; i < detail.length - 1; i++) {
            // 判断当前层的下一层中的每个节点是否都至少有一个前驱节点
            // check whether the nodes in middle has at least one predecessor
            boolean[] hasPredecessor = new boolean[detail[i + 1].length];
            for (int index = 0; index < hasPredecessor.length; index++) {
                hasPredecessor[index] = false;
            }
            // 对该层中的每一个元素
            // for each entry in current layer
            for (int j = 0; j < detail[i].length; j++) {
                boolean hasSuccessor = false;
                int a = detail[i][j];
                V s = vertices.get(a);
                // 对下一层中的每一个元素
                // for each entry in next layer
                for (int k = 0; k < detail[i + 1].length; k++) {
                    int b = detail[i + 1][k];
                    V t = vertices.get(b);
                    if (a == b) {
                        if (!createLoops) {
                            // no self-loops`
                            continue;
                        }
                    }
                    if (i == 0 || i == detail.length - 2) {
                        // 第一层和第二层中的所有节点都连接
                        // there is only one node in the first layer and the last layer respectively
                        // the only node in the first layer connects to the every node in the second layer
                        // 倒数第二层和最有一层的所有节点都连接
                        // every node in the second last layer connects to the only one node in the last layer

                        target.addEdge(s, t);
                        hasSuccessor = true;
                        hasPredecessor[k] = true;
                    } else {
                        if (rng.nextDouble() < p) {
                            // 其他层中的节点按照概率进行连接
                            // nodes in other layers connect to the nodes in correspondingly next layer according to a certain probability p
                            // addEdge
                            target.addEdge(s, t);
                            hasSuccessor = true;
                            hasPredecessor[k] = true;
                        }
//                        target.addEdge(s, t);
                    }
                }
                // 如果这个节点没有连接下一层的任何一个节点
                // if the node has no successor
                if (!hasSuccessor) {
                    Random random = new Random();
                    int index = random.nextInt(detail[i + 1].length);
                    int b = detail[i + 1][index];
                    V t = vertices.get(b);
                    target.addEdge(s, t);
                }
            }
            // 处理没有前驱节点的节点
            // process the nodes which has no predecessor
            for (int index = 0; index < hasPredecessor.length; index++) {
                if (!hasPredecessor[index]) {
                    int[] current = detail[i];
                    Random r = new Random();
                    int position = r.nextInt(current.length);
                    int a = current[position];
                    V s = vertices.get(a);
                    int b = detail[i + 1][index];
                    V t = vertices.get(b);
                    target.addEdge(s, t);
                }
            }
        }

//        showGraphInfo();


    }


    /**
     * 确定每一层都有哪些节点
     * specify the allocation of nodes
     *
     * @param n
     * @param num_layer
     * @return
     */
    public int[][] quantifyAllocation(int n, int num_layer) {
        return quantifyAllocation(getNumOfNodeOfEachLayer(n, num_layer));
    }


    /**
     * 确定每一层都是哪些节点
     * determine which nodes are on each level
     *
     * @param allocation
     */
    public int[][] quantifyAllocation(int[] allocation) {
        int[][] result = new int[allocation.length][];
        int value = 0;
        for (int i = 0; i < allocation.length; i++) {
            int[] temp = new int[allocation[i]];
            for (int j = 0; j < allocation[i]; j++) {
                int store = value++;
                temp[j] = store;
            }
            result[i] = temp;
        }
        return result;
    }


    /**
     * 分层方式
     * the way of layering
     * 确定不同层中节点个数
     * specify the number of node in each layer
     * 第一层和最后一层都只有一个节点
     * only one node in the first layer
     * only one node in the last layer
     *
     * @param n
     * @param num_layer
     * @return
     */
    public int[] getNumOfNodeOfEachLayer(int n, int num_layer) {
        int[] result = new int[num_layer];
        result[0] = 1;
        result[num_layer - 1] = 1;
        int available_n = n - 2;
        int available_num_layer = num_layer - 2;
        int mean = available_n / available_num_layer;
        double standardDeviation = 2;
        NormalDistribution normalDistribution = new NormalDistribution(mean, standardDeviation);
//        System.out.println("概要\t\t" + "node : " + n + "\t layer number : " + num_layer + "\tmean : " + mean);

        // 对数组的前一半进行赋值
        // assign values to the first half of array
        for (int i = 1; i < (num_layer / 2); i++) {
            while (true) {
                int random = (int) normalDistribution.sample();
                if (random > 0 && random < mean * 2) {
                    result[i] = random;
                    break;
                }

            }
        }

        // 对数组的后一半进行赋值
        // assign values to the second half of array
        // 使用均值的2倍减去在前半部分对应位置的值,从而获得后半部分对应位置的值


        if (num_layer % 2 == 0) {
            for (int i = 1; i < num_layer / 2; i++) {
                result[num_layer - i - 1] = mean * 2 - result[i];
            }
        } else {
            for (int i = 1; i < (num_layer - 1) / 2; i++) {
                result[num_layer - i - 1] = mean * 2 - result[i];
            }
        }

        // 计算误差
        // calculate error
        int sum = 0;
        for (int c : result) {
            sum += c;
        }
        int error = n - sum;

        // 处理误差
        // deal with error
        if (num_layer % 2 == 0) {
            result[(num_layer - 2) / 2] += error;
        } else {
            result[(num_layer - 1) / 2] += error;
        }

        return result;
    }

    // 显示分层内容
    // demonstrate the result after the layering
    public void showLayerInfo() {
        System.out.println("\t\t\t分层方式  detail");
        int count = 0;
        for (int[] i : detail) {
            System.out.print("layer : " + count++ + "|\t");
            for (int each : i) {
                System.out.print(each + "\t");
            }
            System.out.println();
        }
        System.out.println();
    }



    // 显示所有节点的 cost
    // show all nodes' cost
    public void showAllCost() {
        for (Integer key : vertex_cost.keySet()) {
            System.out.println("vertex : cost\t\t\t" + key + " : " + vertex_cost.get(key));
        }
        System.out.println();
    }





    // 获取一个节点的 cost
    // get a node's cost
    private static int getVertexCost() {
        int period = getPeriod();
        int n = getNumOfVertex();
        int max = period / n;
        while (true) {
            int result = (int) (Math.random() * max);
            if (result > 0) {
                return result;
            }
        }
    }


    // 获取节点数, [1, 30]
    // get the number of node
    private static int getNumOfVertex() {
        int max = 30;
        while (true) {
            int n = (int) (Math.random() * max);
            if (n > 5) {
                return n;
            }
        }
    }


    // 获取周期, [100, 1000]
    // get the period value
    private static int getPeriod() {
        while (true) {
            int a = (int) (Math.random() * 1000);
            if (a >= 100 && a <= 1000) {
                return a;
            }
        }
    }


    // 获取 HashMap<Integer, Integer> vertex_cost;
    // get HashMap<Integer, Integer> vertex_cost;
    public HashMap<Integer, Integer> getVertexCostMap() {
        return vertex_cost;
    }


    // 获取总的 cost
    // get all nodes' cost
    public int getToalCost() {
        return total_cost;
    }


    // 显示 graph 的信息
    // show the graph information
    public void showGraphInfo() {
        System.out.println("------------ graph info from generator -------------------");
        showLayerInfo();
        showAllCost();
        System.out.println("------------- end graph info -----------------");
        System.out.println();
    }



}

jsichi and others added 30 commits November 24, 2020 14:10
* Create CODE_OF_CONDUCT.md
* Add documentation for thread-safety, and update documentation for
graph equality.

* Avoid fragile link.
* Eigenvector centrality

* New implementation of Katz centrality and deprecation of AlphaCentrality

* Fixed copyright blurb
…1016)

* Added overflow tests and strategy in betweenness centrality

* Fixed typos
…#1022)

* [Util] replace comparators with lambda and deprecate them for removal

* [Util] make VertexDegreeComparator a factory for lambda comparators

* [Util] fix java doc and add deprecation notes
This aligns the weighted PageRank with the unweighted variant. To efficiently access the corresponding edge weights these are also cached. Especially for many iterations the caching becomes useful.

Fixes #1011
* Replace Map<Integer,E> with ArrayList<E> where possible

Using a Integer-key in maps is only useful if the keys are not
consecutive values. In case of consecutive integer values using an
ArrayList is much faster (getting an element at a certain index of a
ArrayList is much faster than getting the value of a key from a HashMap
plus autoboxing from int to integer objects is avoided) and less memory
demanding (an ArrayList of the same size has a smaller backing array and
also does not need the Entry-objects for each entry) compared to using
an HashMap.

Map<Integer,Integer> are replaced by int-arrays if possible.

* fixed wrong indices in GridGraphGenerator

* fixed out-of-range handling in DIMACSImporter

* revert clean-up actions

and use int instead of Integer in ColorRefinementAlgorithm

* Apply changes requested by @Toptachamann
…1025)

Apply the VertexDegreeComparator to GraphOrdering to replace its own
GeneralVertexDegreeComparator.

Also use the VertexToIntegerMapping in the constructor of GraphOrdering
to compute the vertexToOrder mapping.
This avoids unnecessary copy to the vertexList and allocates the HashMap
with its expected size (avoids array-growth and re-hashing while
populating the map).
* Added two basic link prediction algorithms + interface

* Added more local link prediction algs

* Added 2 more tests

* More tests

* Improvements due to PR comments

* Fixed broken tests due to forgotten exception change
* supplying ThreadPoolExecutor to parallel algorithms

* improved docs & removed unrelated changes

* Removed constructors deprecation

* Restored constructors deprecation

* Removed typos and parametrized ThreadPoolExecutor termination time

* Proper handling of InterruptedException
jsichi and others added 30 commits September 29, 2025 21:26
* Terminate BFSShortestPath#getPath when target vertex is found. Issue#1158 #1158

* Dummy edit to re-run checks

---------

Co-authored-by: John Sichi <jsichi@gmail.com>
…hs (#1284)

Explicitly mention that the argument `partialPath` of
`PathValidator::isValidPath` might be an empty path with both source and
target vertices equal to `null`. This happens in `AllDirectedPaths`.
* Adds `DagAllPathsCounter` class for counting all simple paths in a DAG and corresponding test cases

* Fixes the license header
* Add subgraph support in DOTExporter

Signed-off-by: Nicolas Rol <nicolas.rol@rte-france.com>

* Fix header and javadoc

Signed-off-by: Nicolas Rol <nicolas.rol@rte-france.com>

* Fix javadoc

Signed-off-by: Nicolas Rol <nicolas.rol@rte-france.com>

* Simplify unit test due to attributes being rendered in undefined order

* Preserve attribute ordering in DOTExporter and improve javadoc for DOTSubgraph

---------

Signed-off-by: Nicolas Rol <nicolas.rol@rte-france.com>
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.5.0 to 4.7.6.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](JamesIves/github-pages-deploy-action@v4.5.0...v4.7.6)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-version: 4.7.6
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.0 to 3.14.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](apache/maven-compiler-plugin@maven-compiler-plugin-3.14.0...maven-compiler-plugin-3.14.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `maven-surefire-plugin.version` from 3.5.3 to 3.5.4.

Updates `org.apache.maven.surefire:surefire-junit-platform` from 3.5.3 to 3.5.4

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](apache/maven-surefire@surefire-3.5.3...surefire-3.5.4)

Updates `org.apache.maven.plugins:maven-failsafe-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](apache/maven-surefire@surefire-3.5.3...surefire-3.5.4)

---
updated-dependencies:
- dependency-name: org.apache.maven.surefire:surefire-junit-platform
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.apache.maven.plugins:maven-failsafe-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.7.6 to 4.8.0.
- [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases)
- [Commits](JamesIves/github-pages-deploy-action@v4.7.6...v4.8.0)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-version: 4.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
….0 (#1299)

Bumps [org.apache.maven.plugins:maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 3.7.1 to 3.8.0.
- [Release notes](https://github.com/apache/maven-assembly-plugin/releases)
- [Commits](apache/maven-assembly-plugin@maven-assembly-plugin-3.7.1...v3.8.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-assembly-plugin
  dependency-version: 3.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* KConnectiveness feature

* KConnectiveness feature

* Error fix

* KConnectiveness feature

* Checkstyle fix

* Checkstyle fix

* Resolving review comments

* resolve review and fix errors

* Fix methods spelling errors

---------

Co-authored-by: a23barho <azim.barhoumi@imt-atlantique.net>
Co-authored-by: Paul.E <paul.enjalbert@imt-atlantique.net>
…1298)

* Base center location algorithm classes and implementation of the Gon heuristic.

* Unit tests added.

* Style corrected.

* Original reference.

* Update GonAlgorithmTest.java

---------

Co-authored-by: Alex Cornejo <alex@PCDS-JA>
…1300)

Bumps [org.apache.maven.plugins:maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.6.0 to 3.6.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](apache/maven-shade-plugin@maven-shade-plugin-3.6.0...maven-shade-plugin-3.6.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-shade-plugin
  dependency-version: 3.6.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Comments