dpmir1988 2019-03-06 17:05
浏览 18
已采纳

Go语言“ n”个人的桥梁和火炬问题[关闭]

Problem: Given an array of positive distinct integer denoting the crossing time of ‘n’ people. These ‘n’ people are standing at one side of bridge. Bridge can hold at max two people at a time. When two people cross the bridge, they must move at the slower person’s pace. Find the minimum total time in which all persons can cross the bridge.

I am not able to find the pattern as of how to scale this for 'n' people. But somehow I managed to find the case with 4 people. Can someone help me with this. I am new to Golang and I am stuck with this problem.

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "sort"

    "gopkg.in/yaml.v2"
)

type conf struct {
    Person []map[string]float32 `yaml:"person"`
}

func (c *conf) getConf() *conf {
    filename := os.Args[1]                     // Taking file input
    yamlFile, err := ioutil.ReadFile(filename) // Yaml parse
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err = yaml.Unmarshal(yamlFile, c)
    if err != nil {
        log.Fatalf("Unmarshal: %v", err)
    }
    return c
}

func main() {
    var c conf  // Object of struct conf
    c.getConf() // calling getConf function
    // Sorting the current conf map
    n := map[float32][]string{} // Map to store current conf map
    var a []float32             // Store values from conf map
    for k, v := range c.Person {
        v := float32(v)
        fmt.Println(k, v)
        n[v] = append(n[v], k)
    }
    for k := range n {
        a = append(a, k)
    }
    // Converting float32 as float64 in order to sort the values in conf map
    float32AsFloat64Values := make([]float64, len(a))
    for i, val := range a {
        float32AsFloat64Values[i] = float64(val)
    }
    sort.Float64s(float32AsFloat64Values)
    for i, val := range float32AsFloat64Values {
        a[i] = float32(val)
    }
    var time float32
    fmt.Printf("
%v
", a)
    for _, k := range a {
        min1 := a[0]
        min2 := a[1]
        min3 := a[2]
        for _, s := range n[k] {
            //Debug:
            fmt.Printf("%s, %g
", s, k)
            if len(a) > 3 {
                time = (3 * min2) + min1 + a[3] //Formula for minimum time in case of 4 people
            } else if len(a) == 3 {
                time = min1 + min2 + min3
            } else {
                fmt.Println("Enter valid arguments in config.yaml")
            }
        }
    }
    fmt.Printf("Minimum time taken to cross the bridge is:\t%g
", time)
}

Playground: https://play.golang.org/p/ObTVA8gk0mg

Config.yaml is:

person:
  person_1: 2
  person_2: 1
  person_3: 5
  person_4: 8
  person_5: 9

One could run this as: 'go run main.go config.yaml'. My scenario is that there could be 4,5 or 'n' number of people given in this yaml. Then what would be the minimum time for them to cross the bridge given the constraints.

  • 写回答

2条回答 默认 最新

  • duanhe4155 2019-03-06 21:34
    关注

    I think the original problem is a bit more interesting than the one stated (yes, there has to be a Torch in the "Bridge and Torch" problem!).

    Based on the Wikipedia description, for example,

    Four people come to a river in the night. There is a narrow bridge, but it can only hold two people at a time. They have one torch and, because it's night, the torch has to be used when crossing the bridge. Person A can cross the bridge in 1 minute, B in 2 minutes, C in 5 minutes, and D in 8 minutes. When two people cross the bridge together, they must move at the slower person's pace. The question is, can they all get across the bridge if the torch lasts only 15 minutes?

    In our case, of course, there are N people instead of just four, and it takes them variable amount of time to cross the bridge, but the rest of the story is the same.

    Here's the implementation:

    import (
        "fmt"
        "sort"
    )
    
    func minCrossingTime(x []int) int {
        if len(x) == 1 {
            return x[0]
        }
    
        sort.Ints(x)
    
        t := 0
        a, b := x[0], x[1]
        x = x[2:]
    
        for len(x) >= 2 {
            n := len(x)
            c, d := x[n-2], x[n-1]
            x = x[:n-2]
    
            t1 := 2*b + a + d
            t2 := d + c + 2*a
            if t1 < t2 {
                t += t1
            } else {
                t += t2
            }
        }
    
        if len(x) == 1 {
            c := x[0]
            t += a + b + c
        } else {
            t += b
        }
        return t
    }
    
    func main() {
        x1 := []int{1, 2, 5, 8}
        fmt.Printf("x = %x, time = %d
    ", x1, minCrossingTime(x1))
        x2 := []int{3, 8, 1, 6, 2, 9}
        fmt.Printf("x = %x, time = %d
    ", x2, minCrossingTime(x2))
    }
    

    Output:

    x = [1 2 5 8], time = 15
    x = [1 2 3 6 8 9], time = 27
    

    Note: the first example [1 2 5 8] is straight from the Wikipedia, so the answer is yes, they can cross in 15 minutes

    Key idea:

    Definitions:

    • Let X = [X1,X2,...,XN] be the sorted array of crossing times with X1 being the fastest and XN the slowest
    • Let's denote as {XI,XJ} crossing by the pair of people XI and XJ, and {XK} crossing by one person XK, with +{...} indicating the crossing in the desired direction and -{...} in the opposite direction

    Logic:

    1. If N < 4 the problem is trivial:

      • N = 1 => t = X1 (+{X1})
      • N = 2 => t = X2 (+{X1,X2})
      • N = 3 => t = X1 + X2 + X3 (+{X1,X2} -{X1} + {X1,X3})
    2. If N >= 4 consider the following problem: how to make two slowest people (and only them) cross the bridge and have the torch brought back in minimal time. There are two "good" ways to do it, with times t1 = X1 + 2*X2 + XN (+{X1,X2} -{X1} +{X[N-1],XN} -{X2}) and t2 = 2*X1 + X[N-1] + XN (+{X1,X[N-1]} -{X1} +{X1,XN} -{X1}), so we choose the best (minimum) out of these two

    3. Now the two slowest have crossed the bridge, and the torch is on the same side where it started, so we are left with the original problem for X' = [X1, X2, ..., X[N-2]], which can be solved iteratively by applying the same logic and summing up the crossing times

    Extras:

    1. For mathematical proof and more context see e.g. https://page.mi.fu-berlin.de/rote/Papers/pdf/Crossing+the+bridge+at+night.pdf
    2. Code golf solutions in different programming languages: https://codegolf.stackexchange.com/questions/75615/the-bridge-and-torch-problem
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题