Nhân viên kinh doanh du lịch


17

Bạn được đưa ra, như một danh sách hoặc vectơ hoặc bất cứ điều gì, một bó 3-tuples hoặc bất cứ điều gì, trong đó hai điều đầu tiên là chuỗi và điều thứ ba là một số. Các chuỗi là thành phố và số là khoảng cách giữa chúng. Thứ tự của các thành phố trong tuple là tùy ý (nghĩa là không có vấn đề nào đến trước và thứ hai) vì nó có cùng khoảng cách mỗi chiều. Ngoài ra, có chính xác một tuple cho mỗi cặp trích dẫn được kết nối. Không phải tất cả các thành phố có thể được kết nối. Ngoài ra, khoảng cách luôn luôn tích cực (không0). Bạn không cần kiểm tra các điều kiện này, bạn có thể cho rằng đầu vào sẽ được hình thành tốt. Công việc của bạn là trả lại các thành phố theo trình tự tuần hoàn, như vậy, nếu bạn bắt đầu ở bất kỳ thành phố nào và đi vòng quanh trở lại cùng một thành phố, tổng khoảng cách giữa các thành phố sẽ là tối thiểu (chính xác và tất cả trường hợp.) Bạn có thể giả sử một giải pháp tồn tại. Ví dụ: giả sử bạn được cho

[("New York", "Detroit", 2.2), ("New York", "Dillsburg", 3.7), ("Hong Kong", "Dillsburg", 4), ("Hong Kong", "Detroit", 4), ("Dillsburg", "Detroit", 9000.1), ("New York", "Hong Kong", 9000.01)]

Bạn có thể xuất bất kỳ thứ nào sau đây (nhưng bạn chỉ cần xuất một cái):

["Detroit","Hong Kong","Dillsburg","New York"]
["Hong Kong","Dillsburg","New York","Detroit"]
["Dillsburg","New York","Detroit","Hong Kong"]
["New York","Detroit","Hong Kong","Dillsburg"]
["Dillsburg","Hong Kong","Detroit","New York"]
["New York","Dillsburg","Hong Kong","Detroit"]
["Detroit","New York","Dillsburg","Hong Kong"]
["Hong Kong","Detroit","New York","Dillsburg"]

bởi vì đó là chuyến đi ngắn nhất: 13.9

nhưng không

["Dillburg","Detroit","New York","Hong Kong"]

bởi vì nó không phải là ngắn nhất

Xem en.wikipedia.org/wiki/Travelling_salesman_propet

Chấm điểm

Đây là nơi mà nó sẽ thú vị. Bạn lấy số lượng ký tự bạn có, sau đó cắm chúng vào công thức ký hiệu O trong trường hợp xấu nhất. Ví dụ: giả sử bạn viết chương trình vũ phu có 42 ký tự. Như chúng ta đều biết, trường hợp xấu nhất là n!nơi nlà số của các thành phố. 42! = 1405006117752879898543142606244511569936384000000000, vì vậy đó là điểm số của bạn. Điểm thấp nhất sẽ thắng .

Lưu ý: Tôi cũng đã giải tỏa điều này sau đó, nhưng không chắc chắn làm thế nào để giải quyết nó và hy vọng rằng không ai sẽ nhận thấy. Mọi người đã làm, vì vậy tôi sẽ đi với đề xuất của issacg:

các tùy chọn duy nhất là O (n!) và O (b ^ n n ^ a ln (n) ^ k), và tất cả các giới hạn phải càng chặt chẽ càng tốt với ký hiệu đó


4
Nhưng làm thế nào để bạn nói mã của ai đó O(n!)nhưng không phải là O(sqrt(n)*n^n/e^n)không O(n!/100000000000000000000)?
jimmy23013

1
@ user23013 Một giải pháp là nói các tùy chọn duy nhất là O(n!)O(b^n*n^a*ln(n)^k), và tất cả các giới hạn phải càng chặt chẽ càng tốt với ký hiệu đó. OP nên làm rõ, mặc dù.
isaacg

2
@Geobits Như trong truyện tranh, giải pháp lập trình động là O(n^2*2^n), ít hơn nhiều so O(n!)với n lớn.
isaacg

@proud haskeller ổn (thực sự đã hết thời gian và tôi chỉ muốn chấp nhận nó vì nó là tốt nhất mặc dù gần như không có phiếu bầu, nhưng nếu bạn nhận được một cái gì đó tốt hơn hãy tiếp tục.)
PyRulez

@PyRulez tốt bất cứ điều gì tôi thử Tôi tự thuyết phục bản thân nó có độ phức tạp của O (n!) ... thật phức tạp
tự hào

Câu trả lời:


5

Haskell, 259

Tôi nghĩ rằng tôi sẽ có thể làm cho nó ngắn hơn. có thể tôi sẽ.
điều này có độ phức tạp thời gian của O (n ^ 2 * 2 ^ n) * vì vậy điểm số là khoảng 6.2e82

* Tôi không thực sự chắc chắn, nhưng nếu có bất kỳ "sự bổ sung" nào cho sự phức tạp thì nó không hơn đa thức, vì vậy điều này không nên thay đổi điểm số nhiều.

import Data.List
g e=tail$snd$minimum[r|r@(_,b)<-iterate(\l->nubBy((.f).(==).f)$sort[(b+d,c:a)|(b,a)<-l,c<-h\\init a,d<-a!!0%c])[(0,[h!!0])]!!length h,b!!0==h!!0]where h=sort$nub$e>>= \(a,b,_)->[a,b];a%b=[z|(x,y,z)<-e,x==a&&y==b||x==b&&y==a]
f(_,x:b)=x:sort b

đã được một lúc, nhưng có phiên bản 'không được thu nhỏ' (có lẽ là chú thích) không? Tôi tò mò về cách bạn giải quyết vấn đề này với Haskell.
Henk Mollema

5

Python 2, 237 231 228 225 ký tự

Vì đây là một thuật toán ngây thơ, điểm số của nó có lẽ là khoảng 225! ≈ 1,26e433.

from itertools import*
a=input()
n=lambda*a:tuple(sorted(a))
d=dict((n(*x[:2]),x[2])for x in a)
print min(permutations(set(chain(*[x[:2]for x in a]))),key=lambda x:sum(d.get(n(x[i],x[i+1]),1e400)for i in range(-1,len(x)-1)))

from itertools import*sẽ ngắn hơn
xem

Ồ, ý kiến ​​hay đấy ..!
Greg Hewgill

Bây giờ tôi không thể kiểm tra, vì vậy tôi chỉ đang đưa ra ý tưởng. Là bộ cần thiết?
Seequ

Bộ này được sử dụng để loại bỏ các bản sao trong danh sách các thành phố. Vì đầu vào không chứa các mục như thế ("a", "a", 0), nên cần phải có thêm logic ở đâu đó để bỏ qua các cạnh có độ dài bằng không. (Và nếu bạn đang ở trên web, bạn luôn có thể kiểm tra bằng thứ gì đó như codepad.org. )
Greg Hewgill

Tôi không biết nhiều về Python, nhưng rõ ràng bạn đã gọi sumtừng mục hoán vị. Điều đó có O(n!*n)đúng không?
jimmy23013

4

Julia, 213 ký tự

Có lẽ là đi như n!nvậy, vì vậy ~ 2e407.

a=[("New York", "Detroit", 2.2), ("New York", "Dillsburg", 3.7), ("Hong Kong", "Dillsburg", 4), ("Hong Kong", "Detroit", 4), ("Dillsburg", "Detroit", 9000.1), ("New York", "Hong Kong", 9000.01)]
f(a)=(
d(x,y)=(r=filter(z->x in z&&y in z,a);r==[]?Inf:r[1][3]);
m=Inf;
q=0;
c=unique([[z[1] for z=a],[z[2] for z=a]]);
n=length(c);
for p=permutations(c);
    x=sum([d(p[i],p[mod1(i+1,n)]) for i=1:n]);
    x<m&&(m=x;q=p);
end;
q)
f(a)

Để dễ đọc và để chứng minh việc sử dụng, tôi đã để lại một số dòng và tab mới chưa được kiểm tra cũng như nhập ví dụ và một cuộc gọi đến chức năng. Ngoài ra tôi đã sử dụng một thuật toán đòi hỏi n!thời gian, nhưng không phải n!bộ nhớ, nó khả thi hơn một chút để chạy.


Được gọi sumtrên mỗi mục của một hoán vị. Đó có phải là O (n! * N) không?
jimmy23013

Vâng tôi nghĩ bạn đúng.
gggg

2

Trăn 3 - 491

Tôi đã không đếm chiều dài của biến đồ thị đầu vào g. Giải pháp này sử dụng lập trình động và có độ phức tạp n ^ 2 * 2 ^ n, với tổng điểm ~ 6,39e147. Tôi vẫn còn khá mới mẻ với việc chơi golf, vì vậy xin vui lòng ghé thăm nếu bạn thấy một sự lãng phí lớn về mã ở đâu đó!

g=[("New York", "Detroit", 2.2), ("New York", "Dillsburg", 3.7), ("Hong Kong", "Dillsburg", 4), ("Hong Kong", "Detroit", 4), ("Dillsburg", "Detroit", 9000.1), ("New York", "Hong Kong", 9000.01)]
s=''
c={s:1}
D={}
for t in g:c[t[0]]=1;c[t[1]]=1;D[(t[0],t[1])]=t[2];D[(t[1],t[0])]=t[2];D[('',t[0])]=0;D['',t[1]]=0
V={}
y=[x for x in c.keys() if x!='']
f=''
def n(z,p):
 if(len(p)==len(y)-1):
  global f;f=z
 if(0==len(p)):
  return (D[(z,f)] if (z,f) in D else float('inf'))
 Y=[(float('inf'),'')]
 for P in p:
  if((z,P) in D):
   Y.append((D[(z,P)] + n(P,[m for m in p if m!=P]), P))
 V[(z,tuple(p))]=min(Y)
 return min(Y)[0]
n('',y)
for i in range(len(c)-1):
 N=V[(s,tuple(y))][1]
 print(N)
 s=N
 y.remove(N)

1

Toán học, 66 byte

Most@Last@FindShortestTour@Graph[#<->#2&@@@#,EdgeWeight->Last/@#]&

Không có ý tưởng về sự phức tạp, vì vậy điểm số nằm ở đâu đó giữa 10^2310^93.


0

Hồng ngọc 198 180 byte

G=eval(gets.tr("()","[]"))
C=G.map{|t|[t[0],t[1]]}.flatten.uniq
D=Hash.new(+1.0/0)
G.map{|p|D[[p[0],p[1]]]=D[[p[1],p[0]]]=p[2]}
p C.permutation.map{|l|d=0;p=l[-1];l.map{|c|d+=D[[p,c]];p=c};[d,l]}.sort[0][1]

Dòng đầu tiên đọc đầu vào là không được kiểm soát, vì đó dường như là những gì mọi người khác đang làm. Ngoài ra, không có dòng mới cuối cùng cần thiết cho ruby.

Nó chỉ ngu ngốc tạo ra tất cả các hoán vị của các thành phố, vì vậy đặt tôi xuống cho O(n!*n). Trên thực tế, trên suy nghĩ thứ hai, nó thậm chí còn chậm hơn thế, bởi vì nó sắp xếp tất cả các O(n!)con đường thay vì theo dõi tốt nhất cho đến nay.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.