General Algorithms - Graph

本文深入讲解了图论中的几种核心算法,包括BFS、DFS、Kruskal算法等,并通过具体例子展示了它们的应用场景及实现细节。此外,还介绍了如何利用MST解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BFS

Red Knight’s Shortest Path - World CodeSprint 12 -

While loop 和 Recusive function可以互相用来替换; 0 为任意随机起始点, 4 为任意终点, 1,2,3为过程中步骤

DFS

Even Tree

  • 由于已知node范围在2-100,把adjacency list(vector)的范围直接写成 ”>100” 大一点的可以帮助更快确定位置。Sparse 的这种不确定分布的图,使用matrix会增加storage的负担,最大情况会需要一个100x100的matrix, 然而不是每个matrix 的cell都会用到。

  • 整个DFS里,不用一个一个node来回测试相连为不为even的tree,只用计算出DFS 遍历的nodes的和能不能被%2。使用公共的Variable来 counts 可以砍掉的edges的数量。

  • 最要小心是return的时候,nodes的总和计算要加上当前的这一个node (1), 即:dfs(当前node)+1。dfs(当前node) recursion (back tracking)的作用是累计当前node的 子nodes 的个数。

  • num_vertex+=num_nodes 累计到当前node,需要经过的子nodes.

  • Visit[] 的boolean判断在DFS非要不可,是为了track node.

Roads and Libraries

这里写图片描述

  • 此题已知edge 和 node统一Weights,则BFS没有优势但也可以用

  • 除了BFS, DFS这些能够确保每个点和边都会经过的,还有Minimum Spanning Tree 可以用. MST运用了Union-Find的Data structure,比如根据Weight来Swap

MST解法 1

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

class MinSpanningTree {

    public static final class Edge implements Comparable<Edge> {
        final int srcId;
        final int trgId;
        final long value;

        Edge(int srcId, int trgId, long value) {
            this.srcId = srcId;
            this.trgId = trgId;
            this.value = value;
        }

        public int compareTo(Edge o) {
            return (value < o.value) ? -1 : (value > o.value) ? 1 : 0;
        }
    }

    private static final class NodeEntry {
        NodesSet owner;
        NodeEntry next;     
    }

    private static final class NodesSet {
        int size;
        NodeEntry first;
        NodeEntry last;

        NodesSet(NodeEntry node) {
            size = 1;
            first = node;
            last = node;
        }

        static void merge(NodesSet set1, NodesSet set2) {
            if (set1.size < set2.size) {
                merge(set2, set1);
                return;
            }
            set1.size += set2.size;
            set1.last.next = set2.first;
            set1.last = set2.last;
            NodeEntry node = set2.first;
            while (node != null) {
                node.owner = set1;
                node = node.next;
            }
        }
    }

    private int nodesCount;
    private int edgesCount;
    private Edge[] edges;

    public MinSpanningTree(int nodes) {
        this.nodesCount = nodes;
        this.edgesCount = 0;
        this.edges = new Edge[nodesCount];
    }

    public void addEdge(int srcId, int trgId, long value) {
        if (edgesCount == edges.length) {
            edges = Arrays.copyOf(edges, 2 * edges.length);
        }
        edges[edgesCount++] = new Edge(srcId, trgId, value);
    }

    public Edge[] getMinSpanningTree() {
        NodeEntry[] nodes = new NodeEntry[nodesCount];
        for (int i = 0; i < nodesCount; i++) {
            nodes[i] = new NodeEntry();
            nodes[i].owner = new NodesSet(nodes[i]);
        }
        edges = Arrays.copyOf(edges, edgesCount);
        Arrays.sort(edges, 0, edgesCount);
        Edge[] spanningTree = new Edge[nodesCount-1];
        int k = 0;
        for (int i = 0; i < edgesCount & k+1 < nodesCount; i++) {
            NodesSet set1 = nodes[edges[i].srcId].owner;
            NodesSet set2 = nodes[edges[i].trgId].owner;
            if (set1 != set2) {
                NodesSet.merge(set1, set2);
                spanningTree[k++] = edges[i];
            }
        }
        return (k+1 < nodesCount) ? null : spanningTree;
    }

    public long getMinSpanningTreeSize() {
        Edge[] spanningTree = getMinSpanningTree();
        if (spanningTree == null) return -1;
        long treeSize = 0;
        for (Edge edge : spanningTree) treeSize += edge.value;
        return treeSize;
    }
}

public class Solution {
    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in), 256 << 10));
        int testsNumber = in.nextInt();
        for (int test = 0; test < testsNumber; test++) {
            int n = in.nextInt();
            int m = in.nextInt();
            int costOfLib = in.nextInt();
            int costOfRoad = in.nextInt();
            MinSpanningTree tree = new MinSpanningTree(n+1);
            for (int i = 0; i < n; i++) {
                tree.addEdge(0, i+1, costOfLib);
            }
            for (int i = 0; i < m; i++) {
                int v1 = in.nextInt();
                int v2 = in.nextInt();
                tree.addEdge(v1, v2, costOfRoad);
            }
            System.out.println(tree.getMinSpanningTreeSize());
        }
        in.close();
    }
}

MST解法2

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static class Edge {
        public int u, v;
        public long w;
        public Edge(int u, int v, long w) {
            this.u = u;
            this.v = v;
            this.w = w;
        }
    }

    public static class UnionFind {
        private int parent[];
        private int rank[];

        public UnionFind(int n) {
            parent = new int[n];
            rank = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }
        }

        public int findSet(int x) {
            while (parent[x] != x) {
                parent[x] = parent[parent[x]];
                x = parent[x];
            }
            return x;
        }

        public void union(int a, int b) {
            int setA = findSet(a);
            int setB = findSet(b);

            if (rank[setA] > rank[setB]) {
                parent[setB] = setA;
            } else {
                parent[setA] = setB;
                if (rank[setA] == rank[setB]) {
                    rank[setB] += 1;
                }
            }
        }

        public boolean connected(int a, int b) {
            return (findSet(a) == findSet(b));
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int q = in.nextInt();
        for(int a0 = 0; a0 < q; a0++){
            long n = in.nextLong();
            long m = in.nextLong();
            long lib = in.nextLong();
            long road = in.nextLong();

            List<Edge> edges = new ArrayList<>();
            for(int a1 = 0; a1 < m; a1++){
                int city_1 = in.nextInt();
                int city_2 = in.nextInt();
                edges.add(new Edge(city_1, city_2, road));
            }

            UnionFind uf = new UnionFind((int)(n + 1));
            long minCost = n * lib;
            long roadCosts = 0;
            long libCosts = n * lib;

            for (Edge edge : edges) {
                if (!uf.connected(edge.u, edge.v)) {
                    uf.union(edge.u, edge.v);
                    roadCosts += road;
                    libCosts -= lib;
                    minCost = Math.min(minCost, roadCosts + libCosts);
                }
            }

            System.out.println(minCost);
        }
    }
}

MST

Kruskal (MST): Really Special Subtree

这里写图片描述

按照算法,右图的大括号里的已经是所有edges从小到大的排序。已知从最小的那个开始直到所有nodes都包含在一个Minimum Spanning Tree里:先是Edge(1,3), 到Edge(2,3),当到Edge(1,2)时,由于前面的两个Edges已经包含了1 与 2 这两个node,所以忽略Edge(1,2);到Edge(3,4), 然后到Edge(1,4),由于前面也已经包含了Node 1 和 4,所以忽略Edge(1,4), 到Edge(2,4)同理,也被忽略。则最后只留有:

Edge(1,3) +Edge(2,3)+Edge(3,4) = 3+4+5 = 12

  • 这个算法的time complexity 由Sort来决定。因为在找MST时的For loop只为Edge的数量级,很少很简单。

A*

Graph Algorithms: Practical Examples in Apache Spark and Neo4j By 作者: Mark Needham – Amy E. Hodler ISBN-10 书号: 1492047686 ISBN-13 书号: 9781492047681 Edition 版本: 1 出版日期: 2019-01-04 pages 页数: (217) Discover how graph algorithms can help you leverage the relationships within your data to develop more intelligent solutions and enhance your machine learning models. You’ll learn how graph analytics are uniquely suited to unfold complex structures and reveal difficult-to-find patterns lurking in your data. Whether you are trying to build dynamic network models or forecast real-world behavior, this book illustrates how graph algorithms deliver value—from finding vulnerabilities and bottlenecks to detecting communities and improving machine learning predictions. This practical book walks you through hands-on examples of how to use graph algorithms in Apache Spark and Neo4j—two of the most common choices for graph analytics. Also included: sample code and tips for over 20 practical graph algorithms that cover optimal pathfinding, importance through centrality, and community detection. Learn how graph analytics vary from conventional statistical analysis Understand how classic graph algorithms work, and how they are applied Get guidance on which algorithms to use for different types of questions Explore algorithm examples with working code and sample datasets from Spark and Neo4j See how connected feature extraction can increase machine learning accuracy and precision Walk through creating an ML workflow for link prediction combining Neo4j and Spark
### Partial Least Squares Structural Equation Modeling (PLS-SEM) in the IT Field Partial Least Squares Structural Equation Modeling (PLS-SEM) is a statistical technique that combines aspects of principal components analysis, multiple regression, and path analysis into one general multivariate procedure. This method has gained significant traction within information technology research due to its ability to handle complex models with multiple dependent variables, measurement errors, and small sample sizes. In the context of IT studies, PLS-SEM can be particularly useful when evaluating constructs such as user satisfaction, system quality, service quality, or even more abstract concepts like innovation adoption rates. The flexibility offered by this approach allows researchers to model relationships between latent variables while simultaneously assessing both measurement and structural properties[^1]. For instance, in analyzing belief propagation algorithms' convergence speed towards global optima, PLS-SEM could provide insights into how different parameters influence overall performance metrics without requiring assumptions about underlying distributions . Similarly, for understanding attention mechanisms within graph neural networks, PLS-SEM might help identify key factors contributing to improved prediction accuracy under varying conditions [^2]. Moreover, regarding computerized lung sound analysis systems mentioned earlier, applying PLS-SEM would enable an examination of various influencing elements on diagnostic outcomes—such as algorithm type used, dataset characteristics, preprocessing techniques applied—and their combined effect on sensitivity and specificity levels achieved [^3]. When implementing PLS-SEM analyses, several software tools are available including SmartPLS, R packages semPLS/plspm, SPSS AMOS among others which support comprehensive data processing capabilities required for robust results interpretation. ```python import pandas as pd from sklearn.cross_decomposition import PLSCanonical # Example code snippet demonstrating basic usage of PLS Regression in Python data = pd.read_csv('it_survey_data.csv') X = data[['variable_1', 'variable_2']] # Independent Variables Y = data['dependent_variable'] # Dependent Variable pls = PLSCanonical(n_components=2) pls.fit(X, Y) print("Coefficients:", pls.coef_) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值