{"id":49538447,"url":"https://github.com/hoavu-cs/julialg","last_synced_at":"2026-05-02T13:04:49.067Z","repository":{"id":334077263,"uuid":"1139933905","full_name":"hoavu-cs/JuliAlg","owner":"hoavu-cs","description":"A Julia package for common optimization and algorithms with multithreading","archived":false,"fork":false,"pushed_at":"2026-02-16T06:32:35.000Z","size":143,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-16T08:54:36.056Z","etag":null,"topics":["algorithms","julia","optimization"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoavu-cs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-22T15:57:43.000Z","updated_at":"2026-02-16T07:13:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hoavu-cs/JuliAlg","commit_stats":null,"previous_names":["hoavu-cs/juliopt","hoavu-cs/julialg"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hoavu-cs/JuliAlg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoavu-cs%2FJuliAlg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoavu-cs%2FJuliAlg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoavu-cs%2FJuliAlg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoavu-cs%2FJuliAlg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoavu-cs","download_url":"https://codeload.github.com/hoavu-cs/JuliAlg/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoavu-cs%2FJuliAlg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32534975,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T12:25:33.646Z","status":"ssl_error","status_checked_at":"2026-05-02T12:24:51.733Z","response_time":132,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","julia","optimization"],"created_at":"2026-05-02T13:04:37.622Z","updated_at":"2026-05-02T13:04:49.057Z","avatar_url":"https://github.com/hoavu-cs.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JuliAlg\n\nA Julia package for combinatorial optimization and graph algorithms. It contains implementation of exact, approximate, and heuristic solutions for classic problems in optimization and network analysis. I aim to implement every  algorithms that I can get a good grasp of that are \n- theoretically sound\n- practical with applications in mind\n- those that require more understanding or optimization. \n\nI also utilize multi-threading for algorithms that can benefit from parallelism. See the benchmarks section for some results. There are some NP-Hard problems with no known polynomial-time approximation. For these, I try to come up with heuristics that help reduce the search space (such as in densest at-most-k-subgraph). Some are dealt with using parameterization.\n\nCoding agents are often used to generate documentation and benchmark tools. The core algorithms and implementations are mostly written and optimized by me. \n\nThe goal is to use this package internally for my other projects, but I would also be happy if it can be useful to others. Pull requests and contributions are welcome. \n\n\n## Installation\n\n```julia\nusing Pkg\nPkg.add(url=\"https://github.com/\u003cowner\u003e/JuliAlg.jl\")\n```\n\nOr for local development:\n\n```bash\ngit clone \u003crepo-url\u003e\ncd JuliAlg\njulia --project -e 'using Pkg; Pkg.instantiate()'\n```\n\n## Algorithms\n\n### Combinatorial Optimization\n\n| Function | Problem | Method | Guarantee |\n|---|---|---|---|\n| `exact_knapsack(W, weights, values)` | 0/1 Knapsack | Value-based DP | Exact, O(n * sum(values)) |\n| `ptas_knapsack(W, epsilon, weights, values)` | 0/1 Knapsack | Value scaling + DP | (1 - epsilon)-approx |\n| `lpt_makespan(jobs, m)` | Makespan | LPT heuristic | 4/3 + 1/(3m)-approx |\n| `bin_packing(items, bin_capacity)` | Bin Packing | Best-Fit Decreasing | \u003c= (11/9)OPT + 6/9 |\n| `weighted_interval_scheduling(starts, ends, weights)` | Weighted Interval Scheduling | DP + binary search | Exact, O(n log n) |\n| `set_cover(subsets, costs)` | Weighted Set Cover | Greedy | O(ln n)-approx |\n| `max_coverage(subsets, k)` | Maximum Coverage | Greedy | (1 - 1/e)-approx |\n\n### Graph Algorithms\n\n| Function | Problem | Method | Guarantee |\n|---|---|---|---|\n| `pagerank(G, weights; α)` | PageRank | Power iteration | Exact (up to convergence) |\n| `influence_maximization_ic(g, weights, k)` | Influence Maximization | Greedy + Monte Carlo IC | (1 - 1/e)-approx |\n| `simulate_ic(g, weights, seed_set)` | IC Spread Estimation | Monte Carlo simulation | - |\n| `densest_subgraph(G)` | Densest Subgraph | Goldberg's algorithm (binary search + max-flow) | Exact |\n| `densest_subgraph_peeling(G)` | Densest Subgraph | Charikar's peeling algorithm | 1/2-approx |\n| `densest_at_most_k_subgraph(G, k)` | Densest At-Most-k Subgraph | Degree-based pruning + brute force | Heuristic |\n| `k_core_decomposition(G)` | K-Core Decomposition | Iterative peeling | Exact, O(m) |\n| `bw_centrality(G, weights; normalized)` | Betweenness Centrality | Brandes' algorithm (BFS / Dijkstra) | Exact, O(nm) / O(nm + n² log n) |\n| `weighted_bipartite_matching(G, L, R; weights)` | Maximum Weight Bipartite Matching | LP relaxation (totally unimodular) | Exact |\n\n\u003e **Note:** Some functions (`pagerank`, `bw_centrality`, `influence_maximization_ic`, `simulate_ic`) have the same names as functions in Graphs.jl. To use JuliAlg's implementation, call them with the module prefix (e.g., `JuliAlg.pagerank(...)`).\n\n`pagerank`, `bw_centrality`, `influence_maximization_ic`, and `simulate_ic` accept both directed (`SimpleDiGraph`) and undirected (`SimpleGraph`) graphs. For weighted undirected graphs, ensure `weights[(u,v)] == weights[(v,u)]` for all edges.\n\n## Usage\n\nAll algorithms return a tuple of `(objective_value, selected_items)`.\n\n### Knapsack\n\n```julia\nusing JuliAlg\n\nW = 10\nweights = [2, 3, 4, 5]\nvalues  = [3, 4, 5, 6]\n\n# Exact solution\nvalue, items = exact_knapsack(W, weights, values)\n\n# PTAS with epsilon = 0.1\nvalue, items = ptas_knapsack(W, 0.1, weights, values)\n```\n\n### Makespan\n\n```julia\nusing JuliAlg\n\njobs = [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0]\nm = 3\n\nmakespan, assignments = lpt_makespan(jobs, m)\n# makespan is the maximum load across all m machines\n# assignments[i] gives the machine assigned to job i\n```\n\n### Bin Packing\n\n```julia\nitems = [7, 5, 3, 4, 2, 6]\ncapacity = 10\n\nnum_bins, bins = bin_packing(items, capacity)\n```\n\n### Weighted Interval Scheduling\n\n```julia\nstarts  = [1, 3, 0, 5, 8]\nends    = [4, 5, 6, 7, 9]\nweights = [3, 2, 4, 7, 2]\n\nvalue, selected = weighted_interval_scheduling(starts, ends, weights)\n```\n\n### Set Cover\n\n```julia\nsubsets = [[1, 2, 3], [2, 4], [3, 4, 5]]\ncosts   = [1.0, 2.0, 1.5]\n\ncost, selected = set_cover(subsets, costs)\n```\n\n### Maximum Coverage\n\n```julia\nsubsets = [[1, 2], [2, 3, 4], [4, 5]]\nk = 2\n\ncovered, selected = max_coverage(subsets, Int64(k))\n```\n\n### Influence Maximization\n\n```julia\nusing Graphs, JuliAlg\n\ng = SimpleDiGraph(5)\nadd_edge!(g, 1, 2); add_edge!(g, 2, 3)\nadd_edge!(g, 3, 4); add_edge!(g, 4, 5)\n\nweights = Dict((src(e), dst(e)) =\u003e 0.5 for e in edges(g))\nk = 2\n\nseeds, spread = JuliAlg.influence_maximization_ic(g, weights, k)\n```\n\n### PageRank\n\n```julia\nusing Graphs, JuliAlg\n\n# Directed, unweighted\ng = SimpleDiGraph(4)\nadd_edge!(g, 1, 2); add_edge!(g, 2, 3); add_edge!(g, 3, 1); add_edge!(g, 2, 4)\nr = JuliAlg.pagerank(g)                       # α=0.85\nr = JuliAlg.pagerank(g, nothing; α=0.9)      # custom damping factor\nr = JuliAlg.pagerank(g, nothing; tol=1e-10)  # stricter convergence\n\n# Directed, weighted\nweights = Dict((1,2) =\u003e 2.0, (2,3) =\u003e 1.0, (3,1) =\u003e 1.0, (2,4) =\u003e 3.0)\nr = JuliAlg.pagerank(g, weights)\n\n# Undirected, unweighted\ng = SimpleGraph(4)\nadd_edge!(g, 1, 2); add_edge!(g, 2, 3); add_edge!(g, 3, 4); add_edge!(g, 4, 1)\nr = JuliAlg.pagerank(g)\n\n# Undirected, weighted (weights must be symmetric: w[(u,v)] == w[(v,u)])\nweights = Dict((1,2)=\u003e2.0, (2,1)=\u003e2.0, (2,3)=\u003e1.0, (3,2)=\u003e1.0,\n               (3,4)=\u003e3.0, (4,3)=\u003e3.0, (4,1)=\u003e1.0, (1,4)=\u003e1.0)\nr = JuliAlg.pagerank(g, weights)\n```\n\n### Betweenness Centrality\n\n```julia\nusing Graphs, JuliAlg\n\n# Directed, unweighted\ng = SimpleDiGraph(4)\nadd_edge!(g, 1, 2); add_edge!(g, 2, 3); add_edge!(g, 3, 4); add_edge!(g, 1, 4)\nbc = JuliAlg.bw_centrality(g)                             # normalized\nbc = JuliAlg.bw_centrality(g, nothing; normalized=false)  # unnormalized\n\n# Directed, weighted\nweights = Dict((1,2)=\u003e2.0, (2,3)=\u003e1.0, (3,4)=\u003e3.0, (1,4)=\u003e10.0)\nbc = JuliAlg.bw_centrality(g, weights)\n\n# Undirected, unweighted\ng = SimpleGraph(5)\nfor i in 1:4; add_edge!(g, i, i+1); end\nbc = JuliAlg.bw_centrality(g)\n\n# Undirected, weighted (weights must be symmetric: w[(u,v)] == w[(v,u)])\nweights = Dict((1,2)=\u003e1.0, (2,1)=\u003e1.0, (2,3)=\u003e2.0, (3,2)=\u003e2.0,\n               (3,4)=\u003e1.0, (4,3)=\u003e1.0, (4,5)=\u003e3.0, (5,4)=\u003e3.0)\nbc = JuliAlg.bw_centrality(g, weights)\n```\n\n### K-Core Decomposition\n\n```julia\nusing Graphs, JuliAlg\n\ng = SimpleGraph(6)\nadd_edge!(g, 1, 2); add_edge!(g, 2, 3); add_edge!(g, 1, 3)  # triangle (2-core)\nadd_edge!(g, 3, 4); add_edge!(g, 4, 5); add_edge!(g, 5, 6)  # tail (1-core)\n\ncore = k_core_decomposition(g)\n# core[1] == core[2] == core[3] == 2  (inside the triangle)\n# core[4] == core[5] == core[6] == 1  (in the tail)\n```\n\n### Weighted Bipartite Matching\n\n```julia\nusing Graphs, JuliAlg\n\n# Bipartite graph: L = {1,2,3}, R = {4,5,6}\ng = SimpleGraph(6)\nfor u in 1:3, v in 4:6; add_edge!(g, u, v); end\n\nweights = Dict(\n    (1, 4) =\u003e 3.0, (1, 5) =\u003e 2.0, (1, 6) =\u003e 1.0,\n    (2, 4) =\u003e 6.0, (2, 5) =\u003e 4.0, (2, 6) =\u003e 5.0,\n    (3, 4) =\u003e 1.0, (3, 5) =\u003e 7.0, (3, 6) =\u003e 2.0,\n)\n\nL = [1, 2, 3]; R = [4, 5, 6]\nval, matching = weighted_bipartite_matching(g, L, R; weights)\n# val = 15.0, matching = [(1,4), (2,6), (3,5)]\n\n# Omit weights for maximum cardinality matching (all edge weights default to 1.0)\nval, matching = weighted_bipartite_matching(g, L, R)\n```\n\n### Densest Subgraph\n\n```julia\nusing Graphs, JuliAlg\n\ng = complete_graph(5)\nadd_vertex!(g)\nadd_edge!(g, 1, 6)  # pendant vertex\n\nS, density = densest_subgraph(g)\n# S = [1, 2, 3, 4, 5], density = 2.0\n\n# Densest subgraph with at most k vertices\nS, d = JuliAlg.densest_at_most_k_subgraph(g, 3)\n# Finds the 3-vertex subset with highest density\n```\n\n## Testing\n\n```bash\n# Run all tests\njulia --project -e 'using Pkg; Pkg.test()'\n\n# Run a single test file\njulia --project -e 'using JuliAlg; using Test; include(\"test/knapsack_test.jl\")'\n\n# With threads (needed for influence maximization)\njulia --threads=auto --project -e 'using Pkg; Pkg.test()'\n```\n\n## Benchmarks for Thread Scaling\n\n### Influence Maximization\n\n| Threads | Median (ms) | Min (ms) | Speedup |\n|---------|-------------|----------|---------|\n| 1       | 7,111       | 7,095    | 1.0x    |\n| 2       | 3,788       | 3,725    | 1.9x    |\n| 4       | 2,006       | 1,994    | 3.5x    |\n| 8       | 1,695       | 1,578    | 4.2x    |\n\n### PageRank\n\n| Threads | Median (ms) | Min (ms) | Speedup |\n|---------|-------------|----------|---------|\n| 1       | 677.84      | 517.57   | 1.0x    |\n| 2       | 586.70      | 483.27   | 1.2x    |\n| 4       | 562.86      | 491.88   | 1.2x    |\n| 8       | 535.50      | 475.12   | 1.3x    |\n\n### Set Cover\n\n| Threads | Median (ms) | Min (ms) | Speedup |\n|---------|-------------|----------|---------|\n| 1       | 5,854       | 5,763    | 1.0x    |\n| 2       | 4,141       | 4,040    | 1.4x    |\n| 4       | 3,191       | 3,132    | 1.8x    |\n| 8       | 2,892       | 2,834    | 2.0x    |\n\n### Max Coverage\n\n| Threads | Median (ms) | Min (ms) | Speedup |\n|---------|-------------|----------|---------|\n| 1       | 4,240       | 3,963    | 1.0x    |\n| 2       | 2,945       | 2,889    | 1.4x    |\n| 4       | 2,284       | 2,230    | 1.9x    |\n| 8       | 2,040       | 2,021    | 2.1x    |\n\n### Betweenness Centrality\n\n| Threads | Median (ms) | Min (ms) | Speedup |\n|---------|-------------|----------|---------|\n| 1       | 15,739      | 14,430   | 1.0x    |\n| 2       | 7,571       | 7,288    | 2.0x    |\n| 4       | 3,675       | 3,454    | 4.2x    |\n| 8       | 3,745       | 3,300    | 4.4x    |\n\n```bash\n# Run benchmarks\njulia --project benchmarks/influence_maximization_bench.jl\njulia --project benchmarks/pagerank_bench.jl\njulia --project benchmarks/set_cover_bench.jl\njulia --project benchmarks/max_coverage_bench.jl\njulia --project benchmarks/centrality_bench.jl\n```\n\n## Dependencies\n\nGraphs, GraphsFlows, DataStructures, OffsetArrays, Combinatorics, JuMP, HiGHS. See `Project.toml` for version constraints. Requires Julia \u003e= 1.10.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoavu-cs%2Fjulialg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoavu-cs%2Fjulialg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoavu-cs%2Fjulialg/lists"}