Seyyar satıcı


17

Bir liste ya da vektör ya da her neyse, bir grup 3-tuples ya da her neyse, ilk iki şey dizgidir ve üçüncü şey bir sayıdır. Dizeler şehirlerdir ve sayı aralarındaki mesafedir. Tuple içindeki şehirlerin sırası keyfidir (yani hangisinin önce hangisinin ikinci, hangisinin ikinci olacağı önemli değildir) çünkü her yönüyle aynı mesafedir. Ayrıca, her bir bağlı alıntı çifti için tam olarak bir grup vardır. Tüm şehirler bağlı olmayabilir. Ayrıca, mesafe her zaman pozitiftir (değil0). Bu koşulları kontrol etmenize gerek yoktur, girdinin iyi oluşturulacağını varsayabilirsiniz. İşiniz şehirleri döngüsel bir sırayla döndürmektir, öyle ki, herhangi bir şehirde başlarsanız ve aynı şehre geri dönerseniz, şehirler arasındaki mesafelerin toplamı minimum olacaktır (tam olarak ve tümüyle) ) Bir çözüm olduğunu varsayabilirsiniz. Örneğin, size

[("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)]

Aşağıdakilerden herhangi birini çıktılayabilirsiniz (ancak yalnızca birini çıktılamanız gerekir):

["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"]

çünkü en kısa yolculuk: 13.9

Ama değil

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

çünkü en kısa değil.

Bkz. En.wikipedia.org/wiki/Travelling_salesman_problem

puanlama

Burada ilginç hale geliyor. Sahip olduğunuz karakter sayısını alır ve bunları en kötü durum O-gösterim formülüne bağlarsınız. Örneğin, 42 karakterlik bir kaba kuvvet programı yazdığınızı varsayalım. Hepimizin bildiği gibi, en kötü durum şehir sayısının n!nerede nolduğudur. 42! = 1405006117752879898543142606244511569936384000000000, bu yüzden puanınız. En düşük puan kazanır .

Not: Daha sonra da rahatladım, ancak nasıl çözüleceğinden emin değildim ve kimsenin fark etmeyeceğini umuyordum. İnsanlar yaptı, bu yüzden issacg'ın önerisiyle gideceğim:

tek seçenek O (n!) ve O (b ^ n n ^ a ln (n) ^ k) şeklindedir ve tüm gösterim sınırları, bu gösterime göre mümkün olduğunca sıkı olmalıdır


4
Ama birisinin kodunun ne O(n!)olduğunu, O(sqrt(n)*n^n/e^n)ne olmadığını nasıl söylersiniz O(n!/100000000000000000000)?
jimmy23013

1
user23013 @ bir çözüm sadece seçeneklerdir demek ki O(n!)ve O(b^n*n^a*ln(n)^k)ve tüm sınırları olduğunu notasyonu verilen mümkün olduğunca Sımsıkı gibi olmalıdır. Ancak OP açıklığa kavuşturmalıdır.
isaacg

2
@Geobits Çizgi romanda gösterildiği gibi, dinamik programlama çözümü, büyük n'den O(n^2*2^n)çok daha azdır O(n!).
isaacg

@proud haskeller tamam (aslında bir süredir dışarı çıktı ve sadece kabul etmek istedim çünkü neredeyse hiç oy
vermemesine

@PyRulez iyi ne olursa olsun kendimi O (n!) Karmaşıklığı olduğuna ikna ediyorum ... bu karmaşık
gurur haskeller

Yanıtlar:


5

Haskell, 259

Kısaltabileceğimi düşündüm. Belki yaparım.
Bu O'nun zaman karmaşıklığına sahiptir (n ^ 2 * 2 ^ n) * bu nedenle puan yaklaşık 6.2e82'dir

* Aslında emin değilim, ama karmaşıklığı herhangi bir "ekleme" varsa polinom daha fazla değildir, bu yüzden bu puanı çok fazla değişmemelidir.

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

bir süredir var, ancak 'küçültülmemiş' (belki de açıklamalı) bir sürüm var mı? Haskell ile bu sorunu nasıl çözdüğünü merak ediyorum.
Henk Mollema

5

Python 2, 237 231 228 225 karakter

Bu naif bir algoritma olduğu için skoru muhtemelen 225 civarında! ≈ 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*daha kısa olurdu.
seequ

Oh, iyi fikir ..!
Greg Hewgill

Şimdi test edemiyorum, bu yüzden sadece fikirler atıyorum. Set gerekli mi?
seequ

Set, şehir listesindeki yinelemeleri ortadan kaldırmak için kullanılır. Giriş gibi girişler içermediğinden ("a", "a", 0), sıfır uzunluklu kenarları atlamak için bir yerde ekstra mantık olması gerekir. (Ve web'deyseniz , her zaman codepad.org gibi bir şeyle test edebilirsiniz . )
Greg Hewgill

Python hakkında çok şey bilmiyorum, ama görünüşe sumgöre bir permütasyonun her bir öğesini çağırdınız . Öyle değil mi O(n!*n)?
jimmy23013

4

Julia, 213 karakter

Muhtemelen böyle gider n!n, yani ~ 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)

Okunabilirlik ve kullanımın gösterilmesi için bazı girilmemiş satırlar ve sekmelerde olduğu gibi örnek girdi ve işleve çağrıda bıraktım. Ayrıca n!zaman gerektiren , ancak n!bellek gerektirmeyen bir algoritma kullandım , çalıştırmak biraz daha uygun.


sumBir permütasyonun her maddesine çağrılır . Bu O (n! * N) olmaz mı?
jimmy23013

Evet bence haklısın.
gggg

2

Python 3-491

Giriş grafiği değişkeninin uzunluğunu saymadım g. Bu çözüm, dinamik programlama kullanır ve ~ 6.39e147 toplam puanı için n ^ 2 * 2 ^ n karmaşıklığına sahiptir. Ben hala golf için oldukça yeniyim, bu yüzden bir yerde kod büyük bir israf görüyorsanız lütfen chime!

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

Mathematica, 66 bayt

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

Karmaşıklık hakkında hiçbir fikrim yok, bu yüzden puan 10^23ve arasında bir yerde 10^93.


0

Yakut, 198 180 bayt

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]

Girdiyi okuyan ilk satır, herkesin yaptığı gibi görünmediğinden, kodlanmamıştır. Ayrıca, yakut için gerekli son satırsonu yoktur.

Sadece şehirlerin tüm permütasyonlarını aptalca üretir, bu yüzden beni yere indir O(n!*n). Aslında, ikinci düşüncelerde, bundan daha yavaştır, çünkü O(n!)şimdiye kadarki en iyiyi takip etmek yerine tüm yolları sıralar .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.