How to resolve the algorithm Parallel calculations step by step in the Go programming language
How to resolve the algorithm Parallel calculations step by step in the Go programming language
Table of Contents
Problem Statement
Many programming languages allow you to specify computations to be run in parallel. While Concurrent computing is focused on concurrency, the purpose of this task is to distribute time-consuming calculations on as many CPUs as possible. Assume we have a collection of numbers, and want to find the one with the largest minimal prime factor (that is, the one that contains relatively large factors). To speed up the search, the factorization should be done in parallel using separate threads or processes, to take advantage of multi-core CPUs. Show how this can be formulated in your language. Parallelize the factorization of those numbers, then search the returned list of numbers and factors for the largest minimal factor, and return that number and its prime factors. For the prime number decomposition you may use the solution of the Prime decomposition task.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Parallel calculations step by step in the Go programming language
Overview:
This Go program implements the "Largest Minimal Factor" (LMF) algorithm, which decomposes a set of integers into their prime factors and identifies the numbers with the largest minimal prime factor.
Code Structure:
The program consists of the following main components:
-
main
function:- Calls the
lmf
function with a slice of big integers (numbers
) representing the input numbers. - Prints the largest minimal prime factor and the decomposition for each input number.
- Calls the
-
lmf
function:- Creates a channel (
rCh
) for sending results. - Starts goroutines to concurrently decompose each input number using the
decomp
function. - Collects decomposition results from the channel and accumulates the numbers with the largest minimal prime factor.
- Creates a channel (
-
decomp
function (goroutine):- Decomposes an input number (
n
) into prime factors using thePrimes
function. - Packages the result as a
result
struct and sends it on the result channel (rCh
).
- Decomposes an input number (
-
Primes
function (copied from another task):- Decomposes an integer into a slice of prime factors.
Code Explanation:
-
Input: The input is a slice of big integers (
numbers
) representing the numbers to be decomposed. -
Decomposition:
- The
lmf
function creates goroutines to decompose each input number using thedecomp
function. - The
decomp
function uses thePrimes
function to decompose the input number into a slice of prime factors. - The
decomp
function packages the decomposition result in aresult
struct, which includes the original number and its prime factors, and sends it on the result channel.
- The
-
Result Collection:
- The
lmf
function collects the results from the result channel. - It accumulates the numbers with the largest minimal prime factor in the
rs
slice. - If multiple numbers have the same largest minimal prime factor, all of them are included in the result.
- The
-
Output:
- The main function prints the largest minimal prime factor and the decomposition for each input number.
Source code in the go programming language
package main
import (
"fmt"
"math/big"
)
// collection of numbers. A slice is used for the collection.
// The elements are big integers, since that's what the function Primes
// uses (as was specified by the Prime decomposition task.)
var numbers = []*big.Int{
big.NewInt(12757923),
big.NewInt(12878611),
big.NewInt(12878893),
big.NewInt(12757923),
big.NewInt(15808973),
big.NewInt(15780709),
}
// main just calls the function specified by the task description and
// prints results. note it allows for multiple numbers with the largest
// minimal factor. the task didn't specify to handle this, but obviously
// it's possible.
func main() {
rs := lmf(numbers)
fmt.Println("largest minimal factor:", rs[0].decomp[0])
for _, r := range rs {
fmt.Println(r.number, "->", r.decomp)
}
}
// this type associates a number with it's prime decomposition.
// the type is neccessary so that they can be sent together over
// a Go channel, but it turns out to be convenient as well for
// the return type of lmf.
type result struct {
number *big.Int
decomp []*big.Int
}
// the function specified by the task description, "largest minimal factor."
func lmf([]*big.Int) []result {
// construct result channel and start a goroutine to decompose each number.
// goroutines run in parallel as CPU cores are available.
rCh := make(chan result)
for _, n := range numbers {
go decomp(n, rCh)
}
// collect results. <-rCh returns a single result from the result channel.
// we know how many results to expect so code here collects exactly that
// many results, and accumulates a list of those with the largest
// minimal factor.
rs := []result{<-rCh}
for i := 1; i < len(numbers); i++ {
switch r := <-rCh; r.decomp[0].Cmp(rs[0].decomp[0]) {
case 1:
rs = rs[:1]
rs[0] = r
case 0:
rs = append(rs, r)
}
}
return rs
}
// decomp is the function run as a goroutine. multiple instances of this
// function will run concurrently, one for each number being decomposed.
// it acts as a driver for Primes, calling Primes as needed, packaging
// the result, and sending the packaged result on the channel.
// "as needed" turns out to mean sending Primes a copy of n, as Primes
// as written is destructive on its argument.
func decomp(n *big.Int, rCh chan result) {
rCh <- result{n, Primes(new(big.Int).Set(n))}
}
// code below copied from Prime decomposition task
var (
ZERO = big.NewInt(0)
ONE = big.NewInt(1)
)
func Primes(n *big.Int) []*big.Int {
res := []*big.Int{}
mod, div := new(big.Int), new(big.Int)
for i := big.NewInt(2); i.Cmp(n) != 1; {
div.DivMod(n, i, mod)
for mod.Cmp(ZERO) == 0 {
res = append(res, new(big.Int).Set(i))
n.Set(div)
div.DivMod(n, i, mod)
}
i.Add(i, ONE)
}
return res
}
You may also check:How to resolve the algorithm Semiprime step by step in the Racket programming language
You may also check:How to resolve the algorithm Execute Brain step by step in the Objeck programming language
You may also check:How to resolve the algorithm 100 doors step by step in the HicEst programming language
You may also check:How to resolve the algorithm Unix/ls step by step in the LiveCode programming language
You may also check:How to resolve the algorithm SQL-based authentication step by step in the Nim programming language