{"id":15906010,"url":"https://github.com/lucacappelletti94/visited-rs","last_synced_at":"2025-04-02T22:42:56.995Z","repository":{"id":162859650,"uuid":"637342293","full_name":"LucaCappelletti94/visited-rs","owner":"LucaCappelletti94","description":"Data structure to keep track of visited objects that does not require clearing for several iterations.","archived":false,"fork":false,"pushed_at":"2023-05-07T15:08:15.000Z","size":8,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-08T13:13:54.171Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/LucaCappelletti94.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}},"created_at":"2023-05-07T09:01:17.000Z","updated_at":"2023-05-09T21:43:49.000Z","dependencies_parsed_at":"2024-10-28T10:21:59.438Z","dependency_job_id":"771b38b7-027f-4087-8659-754b228f3c67","html_url":"https://github.com/LucaCappelletti94/visited-rs","commit_stats":{"total_commits":7,"total_committers":1,"mean_commits":7.0,"dds":0.0,"last_synced_commit":"79272e1376a8a5f9a43d07edcd83efd9ff1760da"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fvisited-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fvisited-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fvisited-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaCappelletti94%2Fvisited-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucaCappelletti94","download_url":"https://codeload.github.com/LucaCappelletti94/visited-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246905830,"owners_count":20852818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-06T13:20:32.921Z","updated_at":"2025-04-02T22:42:56.974Z","avatar_url":"https://github.com/LucaCappelletti94.png","language":"Rust","readme":"# Visited 👽\nData structure to keep track of visited objects that does not require clearing for several iterations.\n\n## What is this for?\nSometimes, in algorithms such as breadth-first search, you need to keep a vector that represents whether a node \nwas visited or not. For these instances, of course, a normal vector of bools is quite okay.\n\nThe issues begin when you need to repeat the same BFS over and over, such as when you are computing a centrality \nmetric such as a Closeness centrality or a Betweenness centrality. In these cases, you would need to reset the state\nof the counter.\n\nIf we say that the graph has `|V|` nodes, you would be resetting an object of length `|V|` for `|V|` times, so you would\nbe executing an operation, granted quite a small one, for `|V|^2` times. That is not good, and we can do better.\nLet's replace the boolean values with integers, as booleans  are commonly not bits but `u8` values unless you are using a \nbitvector.\n\nWe start by setting the vector of counters to `0`, and we set a `visited` flag to `1`. Whenever we want to reset the state\nof the vector, we simply run `visited+=1`, implicitly clearing all values of the vector.\n\nNow, up until we reach `T::MAX` if we are using `T` unsigned or whathever other unsigned numerical value we intend to use, we can\nsimply clear the entire vector implicitly by bumping the visited flag. The entire vector still requires an extensive clearing\nwhen the flag reaches saturation if we cannot assume that the vector is all visited by the end of the execution of the\nalgorithm, such as in the execution of BFS runs in disconnected graphs.\n\nSo with this approach, we can reduce the complexity from `|V|^2` to `|V|^2 / min(T::MAX, |V|)`. For instance, if you use `T=u16` and \nyou have less than `32k` nodes, the complexity would be reduced to `|V|`.\n\n## How do I use with this crate?\nFor now, I am still exploring ways to improve this softwate, so you can use it in your Rust project by\nincluding in your `Cargo.toml` by adding the following line under `[dependencies]`:\n\n```toml\nvisited-rs = { git = \"https://github.com/LucaCappelletti94/visited-rs\", branch = \"main\" }\n```\n\nThen, you can import the structs contained in it as such:\n\n```rust\nuse visited_rs::prelude::*;\n```\n\nYou can init a new object with, for instance, the number of nodes as:\n\n```rust\nlet mut visited = Visited::zero(number_of_nodes);\n```\n\nThen, in your BFS-like loop, you will want something like:\n\n```rust\nlet previous_state = visited.set_and_get_visited(node);\n```\n\nOr you can do them separately as such:\n\n```rust\nlet previous_state = visited.is_visited(node);\nvisited.set_visited(node);\n```\n\nFinally, sometimes it make sense to write code in a [data-race aware](https://en.wikipedia.org/wiki/Race_condition) manner.\nFor those special occasion where you really want to break the mutability system, I have prepared the following [`unsafe`](https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html) methods:\n\n```rust\nunsafe{visited.set_visited_racing(node);}\nunsafe{let previous_state = visited.set_and_get_visited_racing(node);}\n```\n\nUse them wisely.\n\nAnd finally, when you want to clear the object for the next round of BFS, you can simply use:\n\n```rust\nvisited.clear();\n```\n\n## Helping\nYou can help out by [opening an issue](https://github.com/LucaCappelletti94/visited-rs/issues) or a [pull request](https://github.com/LucaCappelletti94/visited-rs/pulls). If you like, you can also [directly support my work on GitHub](https://github.com/sponsors/LucaCappelletti94).","funding_links":["https://github.com/sponsors/LucaCappelletti94"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Fvisited-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucacappelletti94%2Fvisited-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucacappelletti94%2Fvisited-rs/lists"}