{"id":47214233,"url":"https://github.com/lucamazzza/tube","last_synced_at":"2026-03-13T15:54:42.981Z","repository":{"id":259525808,"uuid":"878034256","full_name":"lucamazzza/tube","owner":"lucamazzza","description":"Chocolate factory optimization problem, solved with a DFS implementation","archived":false,"fork":false,"pushed_at":"2025-12-27T22:28:17.000Z","size":725,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-19T08:37:06.426Z","etag":null,"topics":["algorithms","dfs","dfs-algorithm","graph-algorithms","graphs","weighted-graphs"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lucamazzza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-10-24T16:58:33.000Z","updated_at":"2025-12-27T22:28:20.000Z","dependencies_parsed_at":"2024-10-26T07:46:37.253Z","dependency_job_id":"cb843d74-9fa3-4bff-8721-339a6206ab7e","html_url":"https://github.com/lucamazzza/tube","commit_stats":null,"previous_names":["lucamazzza/tube"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lucamazzza/tube","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucamazzza%2Ftube","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucamazzza%2Ftube/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucamazzza%2Ftube/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucamazzza%2Ftube/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucamazzza","download_url":"https://codeload.github.com/lucamazzza/tube/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucamazzza%2Ftube/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30469633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T11:00:43.441Z","status":"ssl_error","status_checked_at":"2026-03-13T11:00:23.173Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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","dfs","dfs-algorithm","graph-algorithms","graphs","weighted-graphs"],"created_at":"2026-03-13T15:54:38.347Z","updated_at":"2026-03-13T15:54:42.973Z","avatar_url":"https://github.com/lucamazzza.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align='center'\u003e\n\n\u003cimg src=\"https://capsule-render.vercel.app/api?type=venom\u0026color=323b9d\u0026height=200\u0026section=header\u0026text=tube\u0026fontSize=90\u0026fontColor=ffffff\u0026animation=fadeIn\u0026fontAlignY=35\u0026desc=Chocolate%20Optimization%20Problem\u0026descAlignY=61\u0026descAlign=50\"/\u003e\n\n\u003c/p\u003e\n\n\u003cp align='center'\u003e\n\n\u003cimg src=\"https://img.shields.io/badge/11-%23323b9d?style=for-the-badge\u0026logo=c\u0026logoColor=%23323b9d\u0026labelColor=%23ffffff\u0026color=%23323b9d\"/\u003e\n\n## Description\n\nThe project consists of solving an optimisation problem with regard to a chocolate factory.\n\nThis factory has a chocolate canister (*root*) from which several pipes lead to the production stations. \nproduction stations; these pipes are interconnected by joints (*nodes*) that periodically have to be maintained, and this\nmust be maintained, and this takes time.\n\nHowever, replacement joints (*nodes*) are available which reduce maintenance time to zero.\n\nIt is therefore necessary to find out which joints in the tube branch it is best to change in order to achieve the shortest possible time\nfor the start of production.\n\n### Input\n\nThe first line contains two integers $N$, $C$; the first represents the total number of joints in the system,\nwhile the second represents the number of available spares.\nThe next lines are composed of the parameter $t_n$ (*maintenance time*) and $p_n$ (*parent node*). \n\n```\nN C\nt0 p0\nt1 p1\n ...\nti pi\n```\n\n#### Constraints\n\n- Integer $1 \\le N \\le 10000$\n- Integer $0 C \\le 100$\n- Integer $0 \\le T_i \\le 10^4$\n- Only one value $P_i = -1$ while for all others $0 \\le P_i \u003c N$\n- There is always a sequence from $n_i$ leading to the main tank\n- You are allowed to perform maintenance operations in parallel\n\n### Output\n\nA single integer value representing the minimum time within which the last station can start production.\n\n### Requirements\n\nA solution is required to find the optimal solution to the problem by using utilising the paradigm of dynamic programming.\n\n---\n\n## Solution\n\nAnalysing the problem request, we guessed that the required algorithm had to solve an\noptimisation on a rooted tree, where each node has an associated value (the maintenance time) and where you have\nof ‘spare parts’ with which the associated value can be reset.\n\nThe objective is to minimise the maximum value in the resulting subtrees, distributing spares optimally\namong the nodes.\n\nIt is therefore evident that there is an arborescent structure, representing the problem in its entirety, whose nodes must be\nnodes must be explored, and then its maximum value calculated.\n\nThis problem was first addressed by consulting the course material, in which we found different\noptions for the recursive exploration of nodes, starting with a root; of these we immediately chose to approach the problem on the basis of the\nproblem on the basis of the `DFS` prototype.\n\nIn summary, the algorithm traverses the tree, from root to leaves, giving priority to depth, calculating\nall the part combinations in the subtree of the current node, and then minimising the maximum between the result of the\nsubtree and that of the current node.\n\nThe algorithm was then implemented recursively, which starts from the root and visits the nodes following a\ntransversal *post-order*, so the children are visited first, then the current node.\nThe results calculated for the children are combined to calculate the result for the current node.\n\n### Cases\n\nThe algorithm consists of three steps:\n\n#### 1. Base case\n\nThe base case represents the eventuality in which the algorithm is on a *leaf node*, i.e. a node where there are no\nchildren are present.\n\nIn this case the algorithm has two paths it can follow:\n\n* if the number of residual spares $c$ is $0$, the maximum value is simply the value of the node itself;\n* if, on the other hand, the number of residual spares $c$ is strictly greater than $0$, the maximum is $0$, since there are no \nchildren to use them on.\n\n#### 2. General case\n\nFor a node with $u$ children, the spares distributions on the subtree are first computed:\n\n* All children $v$ of $n$ are iterated and the solutions computed for the subtrees rooted in $v$ are combined.\n* Every possible distribution $x$ of the $c$ spares is attempted where:\n    * $x$ spares are applied to the subtree of the child $v$;\n    * $c-x$ spares are applied to the remaining children and to $n$.\n\nThe formula used is therefore:\n\n$$cur(c) = \\min(cur(c), \\max(S_v(x), S_u(c - x)))$$\n\nwhere $cur(c)$ represents the present value calculated for $c$ parts distributed in the subtree,\n$S_v(x)$ the optimal solution for $x$ spares applied to the child $v$ and $S_n(c-x)$ is the optimal solution of the\nremaining $c-x$ spares applied to node $n$ or its other children.\n\nThis minimises the maximum result of the subtree of child $v$ and that of the current node.\n\n#### 3. Wrap-up\n\nFinally, the improvement directly on the current node $n$ is considered, a decision that is saved in the memory\ndynamic programming memory:\n\n$$mem(n,c) = \\min(T_n + mem(n, c), mem(n, c - 1))$$\n\n---\n\n## Time statistics\n\nThe solution we implemented is fast enough to be judged satisfactory, in our opinion;\nwe noted the following statistical values (considered for 10 executions of the same instance):\n\n| Data                    | Value      |\n| ----------------------- | ---------: |\n| Average                 | $175.3$ µs |\n| Median                  | $172.5$ µs |\n| Range                   | $200.0$ µs |\n| Minimum                 | $117.0$ µs |\n| Maximum                 | $317.0$ µs |\n\nThese data refer to the set of tasks of numerosity $n$ of $30$, with a total execution time of $5,259$ \nms.\n\nThe time complexity thus results to be $O(N\\cdot C^2)$, where $N$ is the input size and $C$ is the number of\navailable spares.\n\n## Space statistics\n\nThe algorithm is quite memory-hungry, given its static memory management, with no use of memory \ndynamic memory. This is known to us and will be indicated in future developments;\nwe have noted the following statistical values (considered for 10 executions of the same instance):\n\n| Data                    | Value       |\n| ----------------------- | ----------: |\n| Average                 | $5.556$ MB  |\n| Median                  | $2.575$ MB  |\n| Range                   | $14.850$ MB |\n| Minimum                 | $1.650$ MB  |\n| Maximum                 | $16.500$ MB |\n\nThese data refer to the set of tasks of $n$ $30$ in number, with a total utilisation of $33,400$ MB. \nms.\n\nThe spatial complexity thus results to be $O(N\\cdot C)$, where $N$ is the input size and $C$ is the number of\navailable spares.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucamazzza%2Ftube","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucamazzza%2Ftube","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucamazzza%2Ftube/lists"}