3 ms·
Hello brother from another mother. I did a similar thing for my bachelor thesis ( source available at https://github.com/za-creature/puls https://github.com/za-
by za_creature 10y ago
Hello brother from another mother. I did a similar thing for my bachelor thesis ( source available at https://github.com/za-creature/puls https://github.com/za-creature/puls ). Mind going into the details of how you designed yours?
Mine is extracting equations from benchmarks of the form ax = b where a and b are components, picking a random "unit" component and fixing it to 1, and then solving the overdetermined system in a least-squares sense. I designed it that way to take all equations into account (e.g. multiple benchmarks can and should include the same components with a potential different "factor") and to handle like a graph (as long as there's a benchmark-path between any two components, they are directly comparable)
Edit: to ensure the graph is always connected, an additional low-weight "metadata" benchmark is generated from the technical specs (e.g. amount of ram, cpu speed) and the total score of a computer is calculated as the weighted sum of all components, using target-specific weight factors (e.g. a gaming pc will want a fast cpu / gpu whereas a multimedia pc will want more capacity)
- onli 10y agoSure. I can give you a high level overview, but I fear that will be disappointing for you. It is not solving equations directly, thinking in graphs or doing anything fancy, but iteratively goes through the options and compares them. O(n²) and all. First the benchmarks. I also added had to add a factor, because a benchmark where the fastest processor (in the following, all that is said about processors also counts for gpus) is not the fastest processor the recommender knows (that happens often, as not many benchmarks include Intels 5960X) would otherwise move its processors too much to the top. That happens by using the one benchmark that contains all existing processors as a reference point in that case. There is still the problem that many benchmarks are sparse, to counteract that there is logic in there to prevent illogical results (stuff like: assert that the 4690 is faster than the 4590). The benchmarks then compute a normalized result from 0 to 10. When a recommendation is requested, he first picks the peripherals based on the budget. With the remaining money he then goes through all gpus and mainboard and picks the best possible combinations, with a factor favoring the gpu, and minimizing the difference between them. The value in doing it like that is how the results are tuneable by code, and that it is possible to pretty exactly say which configurations to build for which price point.
- za_creature 10y agoNot disappointing at all; solving the system in a least-squares sense is O(n^3) and choosing the optimal setup is NP-complete (didn't prove it, but I'm _pretty_ sure it involves backtracking, especially when you consider stuff like adding a PCIe SATA controller to maximize the total amount of storage available). I originally wanted to monetize the idea as well, but gave up and open sourced my solution due to the labor-intensiveness of adding and maintaining components and benchmarks. I can't really help you business-wise, but from a technical standpoint, my suggestion would be to split up the problem in two (sorry for the formal definitions, this is mostly translated from my paper): 1. Given n benchmarks each containing n[i] components each, assign a score to each component so as to obtain a total ordering that minimizes the error (as you mentioned above, one processor may be _way_ faster than another in one benchmark, but be completely outclassed in 50 others). 2. Given n desired component classes, each containing n[i] components as well as their bus requirements or offerings (I stretched the 'bus' definition to also include stuff like S-ATA, 3.5'' slots, ATX power cables, etc), their performance relative to components of the same class (obtained at step 1) and their price, obtain a compatible component subset that: i) satisfies sum(Price[i]) < max_price ii) satisfies sum(Power[i]) > 0 (assuming PSUs provide positive power and everything else negative power; I used watts here but if you're feeling badass, you can extend this to amps on the 3.3 / 5 / 12V rails) iii) maximizes weighted-sum(Performance[i]), given a certain target (this is how I implemented the "I don't want to play games" feature requested by another HN poster; in this case, each target would define a weight for each component class) Since 2. is most likely NP-complete (again, didn't prove it), my approximate solution was a greedy PTAS knapsack ( https://en.wikipedia.org/wiki/Knapsack_problem https://en.wikipedia.org/wiki/Knapsack_problem ) that stored partial systems in one of 3 heaps of about 10k items each: one sorted by cost (to ensure the cheapest system is displayed in the event of a low budget), one sorted by performance (to ensure the best system is displayed, in the event of a high budget) and one sorted by performance/cost ratio (to hopefully obtain the best-bang-for-your-buck system). Anyway, best of luck! Throw me a tweet (same username as HN) if you make it big :)