sfplanner 0.1.5 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7aea85679985ccc529011c6d8145f45bae74702a
4
+ data.tar.gz: e24e321da99e4eadb5b5e37ea6fdf435df71ce3c
5
+ SHA512:
6
+ metadata.gz: 400496a44f31dcde8d7bd4fc47b1df632e6b916f9e09470cc1d02b6bbd5e032e0992bc5d1a1cf09dc5f71db8110d9c23e504cdf8644c75cd0fa3265413344ec1
7
+ data.tar.gz: 4faedc38ca1f6cbe29aab72a0ad1eaf52cc13dc70f11d0dd7a567e383267306ebe288190de4951cba367943a03d0450a1663c14d8b1ce5884efb62e07bbd409d
data/README.md CHANGED
@@ -10,8 +10,6 @@ A Ruby script and library of SFP planner, which solves a planning task written i
10
10
 
11
11
  Click [here](https://github.com/herry13/nuri/wiki/SFP-language), for more details about SFP language.
12
12
 
13
- This is a spin-out project from [Nuri](https://github.com/herry13/nuri).
14
-
15
13
 
16
14
  Features
17
15
  --------
@@ -28,10 +26,10 @@ To install
28
26
 
29
27
  Requirements
30
28
  ------------
31
- - Ruby (>= 1.8.7)
29
+ - Ruby (>= 1.9.2)
32
30
  - Graphviz
33
31
  - Rubygems
34
- - sfp (>= 0.3.0)
32
+ - sfp
35
33
 
36
34
  Tested on:
37
35
  - Ubuntu 12.04
@@ -222,3 +220,9 @@ You could set particular environment variable to change the planner settings:
222
220
  $ export SFPLANNER_MIXED_HEURISTICS=ff2,cea2
223
221
 
224
222
 
223
+ Related Projects
224
+ ----------------
225
+ - [Nuri](https://github.com/herry13/nuri)
226
+ - [Sfp-ruby](https://github.com/herry13/sfp-ruby)
227
+ - [Sfpagent](https://github.com/herry13/sfpagent)
228
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.2.1
@@ -1,4 +1,5 @@
1
1
  require 'fileutils'
2
+ require 'thread'
2
3
 
3
4
  module Sfp
4
5
  class Planner
@@ -346,7 +347,7 @@ module Sfp
346
347
  def solve_sas(parser, p={})
347
348
  return nil if parser.nil?
348
349
 
349
- tmp_dir = '/tmp/nuri_' + (rand * 100000).to_i.abs.to_s
350
+ tmp_dir = '/tmp/nuri_' + (Time.now.to_f * 1000000).to_i.to_s
350
351
  begin
351
352
  compile_time = Benchmark.measure do
352
353
  parser.compile_step_1
@@ -361,23 +362,21 @@ module Sfp
361
362
 
362
363
  benchmarks = parser.benchmarks
363
364
  benchmarks['compile time'] = compile_time
364
- File.open(tmp_dir + '/' + TranslatorBenchmarkFile, 'w') { |f| f.write(JSON.pretty_generate(benchmarks)) }
365
365
 
366
366
  sas_file = tmp_dir + '/problem.sas'
367
367
  plan_file = tmp_dir + '/out.plan'
368
- File.open(sas_file, 'w') do |f|
369
- #f.write(parser.to_sas)
370
- f.write(parser.sas)
371
- f.flush
368
+ benchmarks['generating sas'] = Benchmark.measure do
369
+ File.open(sas_file, 'w') do |f|
370
+ f.write(parser.sas)
371
+ f.flush
372
+ end
372
373
  end
373
374
 
374
- if Heuristic == 'mixed'
375
- mixed = MixedHeuristic.new(tmp_dir, sas_file, plan_file)
376
- mixed.solve
377
- else
378
- command = Sfp::Planner.getcommand(tmp_dir, sas_file, plan_file, Heuristic)
379
- Kernel.system(command)
375
+ benchmarks['search_time'] = Benchmark.measure do
376
+ planner = ParallelHeuristic.new(tmp_dir, sas_file, plan_file)
377
+ planner.solve
380
378
  end
379
+
381
380
  plan = (File.exist?(plan_file) ? File.read(plan_file) : nil)
382
381
  plan = plan_preprocessing(plan)
383
382
 
@@ -398,6 +397,8 @@ module Sfp
398
397
  plan = tmp
399
398
  end
400
399
 
400
+ File.open(tmp_dir + '/' + TranslatorBenchmarkFile, 'w') { |f| f.write(JSON.pretty_generate(benchmarks)) }
401
+
401
402
  return plan, sas_task
402
403
  rescue Exception => exp
403
404
  raise exp
@@ -443,7 +444,7 @@ module Sfp
443
444
  single(sum([g(),weight(hFF, 10)]),pref_only=true)],
444
445
  boost=2000),
445
446
  preferred=hFF,reopen_closed=false,cost_type=1)"'
446
- when 'autotune22' then ' \
447
+ when 'fd-autotune-2' then ' \
447
448
  --heuristic "hCea=cea(cost_type=2)" \
448
449
  --heuristic "hCg=cg(cost_type=1)" \
449
450
  --heuristic "hGoalCount=goalcount(cost_type=2)" \
@@ -458,7 +459,7 @@ module Sfp
458
459
  single(sum([weight(g(), 2),weight(hGoalCount, 3)]),pref_only=true)],
459
460
  boost=200),
460
461
  preferred=[hCea,hGoalCount],reopen_closed=false,cost_type=1)"'
461
- when 'autotune12' then ' \
462
+ when 'fd-autotune-1' then ' \
462
463
  --heuristic "hFF=ff(cost_type=1)" \
463
464
  --heuristic "hCea=cea(cost_type=0)" \
464
465
  --heuristic "hCg=cg(cost_type=2)" \
@@ -514,6 +515,34 @@ module Sfp
514
515
  command
515
516
  end
516
517
 
518
+ def self.get_search_command(dir, plan_file, heuristic, timeout=nil)
519
+ planner = Sfp::Planner.path
520
+ params = Sfp::Planner.parameters(heuristic)
521
+ timeout = Sfp::Planner::Config.timeout if timeout.nil?
522
+ max_memory = Sfp::Planner::Config.max_memory
523
+ logfile = "search.log." + heuristic
524
+
525
+ case `uname -s`.downcase.strip
526
+ when 'linux'
527
+ "ulimit -Sv #{max_memory} && timeout #{timeout} nice #{planner}/downward #{params} \
528
+ --plan-file #{plan_file} < output 1>>#{logfile} 2>>#{logfile}"
529
+ when 'macos', 'darwin'
530
+ "ulimit -Sv #{max_memory} && nice #{planner}/downward #{params} \
531
+ --plan-file #{plan_file} < output 1>>#{logfile} 2>>#{logfile}"
532
+ else
533
+ 'exit 1'
534
+ end
535
+ end
536
+
537
+ def self.get_preprocess_command(dir, sas_file)
538
+ case `uname -s`.downcase.strip
539
+ when 'linux', 'macos', 'darwin'
540
+ "cd #{dir} && #{Sfp::Planner.path}/preprocess < #{sas_file} 2>/dev/null 1>/dev/null"
541
+ else
542
+ "exit 1"
543
+ end
544
+ end
545
+
517
546
  # Combination between two heuristic to obtain a suboptimal plan.
518
547
  # 1) solve the problem with CG/CEA/FF, that will produce (usually) a non-optimal plan
519
548
  # 2) remove actions which are not selected by previous step
@@ -525,7 +554,7 @@ module Sfp
525
554
  @dir = dir
526
555
  @sas_file = sas_file
527
556
  @plan_file = plan_file
528
- @heuristics_order = ['ff2', 'cea2', 'autotune12', 'autotune22']
557
+ @heuristics_order = ['ff2', 'cea2', 'fd-autotune1', 'fd-autotune2']
529
558
  @heuristics_order = ENV['SFPLANNER_MIXED_HEURISTICS'].split(',') if ENV['SFPLANNER_MIXED_HEURISTICS']
530
559
  @continue = continue
531
560
  @continue = true if ENV['SFPLANNER_MIXED_CONTINUE']
@@ -534,13 +563,13 @@ module Sfp
534
563
 
535
564
  def solve2
536
565
  if not File.exist?(@plan_file)
537
- #autotune12 (see fd-autotune-1)
538
- planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'autotune12')
566
+ #fd-autotune-1
567
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'fd-autotune-1')
539
568
  Kernel.system(planner)
540
569
  end
541
570
  if not File.exist?(@plan_file)
542
- #autotune22 (see fd-autotune-2)
543
- planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'autotune22')
571
+ #fd-autotune-2
572
+ planner = Sfp::Planner.getcommand(@dir, @sas_file, @plan_file, 'fd-autotune-2')
544
573
  Kernel.system(planner)
545
574
  end
546
575
  if not File.exists?(@plan_file)
@@ -664,6 +693,96 @@ module Sfp
664
693
  end
665
694
  end
666
695
 
696
+
697
+ class ParallelHeuristic < MixedHeuristic
698
+ def initialize(dir, sas_file, plan_file, optimize=false)
699
+ @dir = dir
700
+ @sas_file = sas_file
701
+ @plan_file = plan_file
702
+ if ENV['SFPLANNER_HEURISTICS']
703
+ @heuristics = ENV['SFPLANNER_HEURISTICS'].split(',')
704
+ else
705
+ @heuristics = ['ff2', 'cea2', 'fd-autotune-1', 'fd-autotune-2']
706
+ end
707
+ if ENV['SFPLANNER_OPTIMIZE']
708
+ @optimize = case ENV['SFPLANNER_OPTIMIZE']
709
+ when '1', 'true'
710
+ true
711
+ else
712
+ false
713
+ end
714
+ else
715
+ @optimize = optimize
716
+ end
717
+ @timeout = (ENV['SFPLANNER_TIMEOUT'] ? ENV['SFPLANNER_TIMEOUT'].to_i : Sfp::Planner::Config.timeout)
718
+ end
719
+
720
+ def solve
721
+ ### run preprocessing
722
+ return false if not do_preprocess
723
+
724
+ ### save current working dir
725
+ home = Dir.pwd
726
+
727
+ ### change to temporary working dir
728
+ Dir.chdir @dir
729
+
730
+ ### run a thread for each heuristic
731
+ files = []
732
+ @heuristics.each do |heuristic|
733
+ plan_file = @plan_file + '.' + heuristic
734
+ cmd = Sfp::Planner.get_search_command(@dir, plan_file, heuristic, @timeout)
735
+ pid = Process.spawn cmd
736
+ Process.detach pid
737
+ files << plan_file
738
+ end
739
+
740
+ def processes(dir)
741
+ `ps ax | grep -v grep | grep downward | grep sfplanner | grep '#{dir}' | awk '{print $1" "}'`.to_s.strip.split("\n")
742
+ end
743
+
744
+ loop do
745
+ list = processes(@dir)
746
+ break if list.length <= 0
747
+ finished = files.select { |f| File.exist?(f) }
748
+ break if finished.length > 0
749
+ sleep 0.2
750
+ end
751
+
752
+ system "kill -9 " + processes(@dir).join(" ") + " 1>/dev/null 2>/dev/null"
753
+
754
+ ### select best plan
755
+ selected = nil
756
+ length = -1
757
+ files.each do |file|
758
+ if File.exist?(file)
759
+ len = File.read(file).split("\n").length
760
+ if length < 0 or len < length
761
+ length = len
762
+ selected = file
763
+ end
764
+ end
765
+ end
766
+
767
+ if not selected.nil?
768
+ FileUtils.copy(selected, @plan_file)
769
+ optimize_plan if @optimize
770
+
771
+ Dir.chdir home
772
+ true
773
+ else
774
+ Dir.chdir home
775
+ false
776
+ end
777
+ end
778
+
779
+ def do_preprocess
780
+ (!!system(Sfp::Planner.get_preprocess_command(@dir, @sas_file)) &&
781
+ File.exist?(@dir + '/output'))
782
+ end
783
+ end
784
+
785
+
667
786
  class Action
668
787
  attr_accessor :operator, :predecessor
669
788
 
data/lib/sfplanner.rb CHANGED
@@ -4,8 +4,7 @@ require 'json'
4
4
  require 'sfp'
5
5
 
6
6
  # internal dependencies
7
- libdir = File.expand_path(File.dirname(__FILE__))
8
-
9
- require libdir + '/sfplanner/sas'
10
- require libdir + '/sfplanner/graph.rb'
11
- require libdir + '/sfplanner/planner'
7
+ libdir = File.dirname(__FILE__) + '/sfplanner'
8
+ Dir.entries(libdir).each do |item|
9
+ require "#{libdir}/#{item}" if File.extname(item) == '.rb'
10
+ end
data/sfplanner.gemspec CHANGED
@@ -1,23 +1,22 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = 'sfplanner'
3
- s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).sub(/\n/, '')
4
- s.date = '2013-08-13'
5
- s.summary = 'SFPlanner'
6
- s.description = 'A Ruby gem that provides a Ruby API and a script to the SFP planner. This planner can automatically generate a plan that solves a planning problem written in SFP language.'
7
- s.authors = ['Herry']
8
- s.email = 'herry13@gmail.com'
2
+ s.name = 'sfplanner'
3
+ s.version = File.read(File.dirname(__FILE__) + '/VERSION').strip
4
+ s.date = File.atime(File.dirname(__FILE__) + '/VERSION').strftime("%Y-%m-%d").to_s
5
+ s.summary = 'SFPlanner'
6
+ s.description = 'A Ruby gem that provides a Ruby API and a script to the SFP planner. This planner can automatically generate a plan that solves a planning problem written in SFP language.'
7
+ s.authors = ['Herry']
8
+ s.email = 'herry13@gmail.com'
9
9
 
10
- s.executables << 'sfplanner'
11
- s.executables << 'sfw2graph'
12
- s.files = `git ls-files`.split("\n")
10
+ s.executables << 'sfplanner'
11
+ s.files = `git ls-files`.split("\n")
13
12
 
14
13
  s.require_paths = ['lib']
15
14
  s.license = 'BSD'
16
15
 
17
- s.homepage = 'https://github.com/herry13/sfplanner'
18
- s.rubyforge_project = 'sfplanner'
16
+ s.homepage = 'https://github.com/herry13/sfplanner'
17
+ s.rubyforge_project = 'sfplanner'
19
18
 
20
- s.add_dependency 'sfp', '~> 0.3.17'
19
+ s.add_dependency 'sfp', '~> 0.3.19'
21
20
 
22
21
  s.add_development_dependency 'rake'
23
22
  end
metadata CHANGED
@@ -1,45 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfplanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Herry
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-13 00:00:00.000000000 Z
11
+ date: 2013-11-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: sfp
16
- requirement: &18815260 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
21
- version: 0.3.17
19
+ version: 0.3.19
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *18815260
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.19
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: rake
27
- requirement: &18814780 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *18814780
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  description: A Ruby gem that provides a Ruby API and a script to the SFP planner.
37
42
  This planner can automatically generate a plan that solves a planning problem written
38
43
  in SFP language.
39
44
  email: herry13@gmail.com
40
45
  executables:
41
46
  - sfplanner
42
- - sfw2graph
43
47
  extensions: []
44
48
  extra_rdoc_files: []
45
49
  files:
@@ -74,26 +78,25 @@ files:
74
78
  homepage: https://github.com/herry13/sfplanner
75
79
  licenses:
76
80
  - BSD
81
+ metadata: {}
77
82
  post_install_message:
78
83
  rdoc_options: []
79
84
  require_paths:
80
85
  - lib
81
86
  required_ruby_version: !ruby/object:Gem::Requirement
82
- none: false
83
87
  requirements:
84
- - - ! '>='
88
+ - - '>='
85
89
  - !ruby/object:Gem::Version
86
90
  version: '0'
87
91
  required_rubygems_version: !ruby/object:Gem::Requirement
88
- none: false
89
92
  requirements:
90
- - - ! '>='
93
+ - - '>='
91
94
  - !ruby/object:Gem::Version
92
95
  version: '0'
93
96
  requirements: []
94
97
  rubyforge_project: sfplanner
95
- rubygems_version: 1.8.11
98
+ rubygems_version: 2.1.10
96
99
  signing_key:
97
- specification_version: 3
100
+ specification_version: 4
98
101
  summary: SFPlanner
99
102
  test_files: []