2011-03-16 3 views
1

업데이트 : 나는 매우 심하게 질문을한다는 것을 알고 있습니다. 여기에 두 번째 실행이 있습니다.Python, Ruby, Haskell (또는 무엇이든)에서 반복 목록

는 다음과 같은 기능을 고려

myList = [] 
optimumList = [] 

def findOptimumListItems(): 
    n = 5 

    for i in range (n + 1): 
     for j in range (n + 1 - i): 
      myList.append((i, j, n-i-j)) 

    for i in myList: 
     win = 0.0 
     draw = 0.0 
     for j in myList: 
      score = 0 
      if (i[0] > j[0]): 
       score += 1 
      if (i[0] == j[0]): 
       score += 0.5 
      if (i[1] > j[1]): 
       score += 1 
      if (i[1] == j[1]): 
       score += 0.5 
      if (i[2] > j[2]): 
       score += 1 
      if (i[2] == j[2]): 
       score += 0.5 
      if (score == 2): 
       win += 1 
      if (score == 1.5): 
       draw += 1 
     if (win/(len(myList)-win-draw) > 1.0): 
      optimumList.append(i) 

    return optimumList 

먼저 내가 목록을 확인하십시오. n = 5의 경우 생성 된 목록은 다음과 같습니다.

[(0, 0, 5), (0, 1, 4), (0, 2, 3), (0, 3, 2), (0, 4, 1), 
(0, 5, 0), (1, 0, 4), (1, 1, 3), (1, 2, 2), (1, 3, 1), 
(1, 4, 0), (2, 0, 3), (2, 1, 2), (2, 2, 1), (2, 3, 0), 
(3, 0, 2), (3, 1, 1), (3, 2, 0), (4, 0, 1), (4, 1, 0), 
(5, 0, 0)] 

그런 다음이 함수는 목록의 각 요소를 가져 와서 목록 자체와 비교합니다. 이것이 당신이하는 방법입니다 : [3, 1, 1]과 [0, 0, 5]를 비교한다고 가정 해보십시오. 0은 3 점을 잃고 0 점은 1 점을 잃어 포인트가 없으며 1 점은 5 점을 얻는다. 끌기가 0.5 점을 얻으면 승리는 1 점을 얻습니다. 모든 항목에 대해, 승리가 손실보다 많으면 해당 항목은 최적의 것으로 간주되어 최적 목록에 추가됩니다.

N = 5의 경우, 최적의 목록입니다 :

[(0, 2, 3), (0, 3, 2), (1, 1, 3), (1, 2, 2), (1, 3, 1), (2, 0, 3), 
(2, 1, 2), (2, 2, 1), (2, 3, 0), (3, 0, 2), (3, 1, 1), (3, 2, 0)] 

내 질문은 : 나는 간결 방법으로 위의 기능을 쓸 수 있습니까? 나는 특히 기능적 알고리즘에 관심이있다. 파이썬, 루비, 자바, 하스켈의 답변을 주시면 감사하겠습니다. (말하자면, 어떤 언어로든 깔끔한 해결책이 있다면 괜찮습니다.)

같은 질문을 반복해서 드려 죄송합니다. 나는 원래의 질문이 지저분하고 이해하기 어렵다는 것에 동의한다. 나는 그것이 지금 분명하기를 바란다.

업데이트 (rampion 님의 의견에 따르면) :이 유형 (또는이 유형)에 대한 효율적인 알고리즘이 있습니까?

+1

나는 여전히 혼란 스럽다. 'item_','item_0' 및'item_n'은 무엇입니까? – senderle

+0

정상적인 (파이썬 용) 중첩리스트 구문을 사용하여'myList [0] [0]','myList [0] [1]'등과 같은 것들을 말하면 더 명확해질 것이다. – senderle

+0

다른 항목이 같은 경우 점수가 없습니까? –

답변

4

두 번째 업데이트는 그레이트 - 지금은 당신이 원하는 것을 정확히 이해합니다. 이것은 가장 최근 편집의 코드와 동일합니다 :

def optimize(myList): 
    score_tup = lambda tup_a, tup_b: sum(1.0 if a > b else 0.5 if a == b else 0 for a, b in zip(tup_a, tup_b)) 
    scores = ((tup_a, [score_tup(tup_a, tup_b) for tup_b in myList]) for tup_a in myList) 
    scores = ((tup, score.count(2), score.count(1.5)) for tup, score in scores) 
    return [tup for tup, win, draw in scores if (win * 1.0/(len(myList) - win - draw)) > 1.0] 

a = 5 
myList = [(i, j, a-i-j) for i in range(a + 1) for j in range(a + 1 - i)] 
print myList 
print optimize(myList) 

이 답변의 이전 버전을 보려면 수정 사항을 확인하십시오. 이것은 너무 길어지고있었습니다.

+0

이유 : 단지 myList = [(i, j, a-1-ij) 범위 (i-10) 범위의 i (a-i)] ' – newacct

+0

@newacct, 네, 그것을 시도하고 내가 예상했던대로 작동하지 않았다. 하지만 방금 타이핑 한 것을 시도해 보았습니다. 그래서 처음 시도했을 때 실수를 저질렀을 것입니다. 내가 편집 할게 ... – senderle

0

이것은 무엇입니까? 목록의 각 항목을 목록의 다른 모든 항목과 비교하는 것은 매우 큰 시간이 걸릴 것입니다 (O (n^2), 나는 믿습니다). 특히 목록의 크기가 커지면 더욱 그렇습니다. 당신이 우리에게 어떤 맥락을 주면, 우리는 당신에게 이것을하기위한 더 좋은 방법을 말할 수있을 것입니다. 이 실행을 완료하지으로,

>>> for i in range(len(myList)): 
...  for x in range(len(myList)): 
...    if x != i: 
...      if myList[i][0] > myList[x][0]: 
...        score += 1 
...      if myList[i][0] < myList[x][0]: 
...        score += .5 
... 

테스트되지 않은, 그래서 실수가있을 수 있습니다 :

어쨌든, 여기에 내가 당신의 모든 항목을 비교 해낸거야.

1

아직 완료되지 않았지만 좋은 시작이라고 생각합니다.

루비로 작성되었습니다.

>> l = [1,2,3] 
>> l.map {|n| l.map{|i| i > n ? 1 : 0.5 }}.flatten.inject(0){|start, n| start + n} 
=> 6.0 
+1

'.inject (0) {? start, n | 대신에 .inject (: +)'를 사용할 수도 있습니다. 시작 + = n}'. (그리고'+ ='그냥'+'이어야합니다) –

+0

고마워, 나는 게시물을 편집했습니다. – Oleander

0

이 작업을 올바르게 수행하면 비교 함수가 변형되지 않으며 반환되는 것은 비교하기 전의 목록과 동일합니다. 즉, 목록을 생성하는 내 기능 프로그램은 다음과 같습니다.

def triple_tuple_generator(a): 
    """Given an integer 'a', returns a generator of triple tuples of length 'a(a-1), where the tuple values are over the range 'a-1=i' (i,i-1,a-2*i+1).""" 
    for i in range(a): 
     for j in range(a-1): 
      yield (i,j,a-1-i-j) 

이것은 생성기이므로 원하는대로 사용할 수 있습니다.내가 합계를 가지고 일하는 데 충분하다면, 나는 직감을 증명할 것이다. 그러나 나는 수학자가 아닌 물리학 자다. ;)이 권리가 있다면 알려줘.

하스켈
4

이 상당히 간결하지만

optimize :: Int -> [(Int,Int,Int)] 
optimize n = filter optimal [ (a,b,c) | a <- [0..n], b <- [0..(n-a)], let c = n - a - b ] 
    where optimal x = (>0) . sum $ map (comp x) xs 
     comp (a,b,c) (a',b',c') = signum $ vs a a' + vs b b' + vs c c' 
     vs x x' = case compare x x' of 
        GT -> 1 
        EQ -> 0 
        LT -> -1 

, 그것은 우리가하기 만하면 (0,2,3)과 그 반대에 (우리가 (0,3,2 비교) 매우 효율적이 아니다 한번 그렇게해라.)